我正在尝试使用font-lock和elisp的正则表达式突出显示如下内容:
class Foo implements A, B, C, D { }
问题是implements
之后逗号分隔列表的未知长度。我已经完成了正则表达式,它突出显示了列表中的所有单词(使用re-buider,A,B,C和D突出显示):
"implements\\s-+\\(?:\\(\\sw+\\)\\s-*,\\s-*\\)*\\(\\sw+\\)"
但我无法将其与font-lock结合使用。
显然
'("implements\\s-+\\(?:\\(\\sw+\\)\\s-*,\\s-*\\)*\\(\\sw+\\)"
(1 font-lock-type-face) (2 font-lock-type-face))
不起作用,因为它仅突出显示在第一次反向引用后忽略星号(*
)的最后一次出现(C和D)。
有没有办法捕获所有匹配单词的列表,或者可能采用不同的方式来解决这个问题?
答案 0 :(得分:2)
如果您不希望也突出显示逗号,则您的方法无效。当您使用表格的subexp-highlighter
时(subexp facespec)
subexp
指的是正则表达式的子组,并使用给定的facespec
突出显示。现在,正则表达式匹配的子组是具有开始和结束的连续文本跨度。实际上,无论何时进行正则表达式搜索,都可以使用(match-beginning subexp)
和(match-end subexp)
函数查询这些值。
但这意味着您无法匹配可变数量的类名,不包括逗号和单个子表达式,因为该子表达式必须是连续的跨度。覆盖不同数量的类名的连续跨度也必须始终包含逗号,没有办法解决这个问题。
这是为什么你的方法不是一个好主意的另一个原因:你的regexp显式使用空格。如果空白被排除在突出显示之外并不重要,但即使在正则表达式中使用它也不是一个好主意,因为只要允许空格,你总是可以遇到注释。
考虑以下代码行:
class Foo implements A, /*B, C,*/ D { }
在这种情况下,您希望使用/*B, C,*/
以及font-lock-comment-face
中的周围类突出显示范围font-lock-type-face
中的字符。如果仅在其他所有内容都已突出显示之后突出显示注释,并允许注释覆盖其他字体锁定匹配,则仍可以实现此效果。但是这会导致相当低效的匹配,因为每个注释首先会被突出显示,就好像它是代码一样,然后在第二遍中突出显示为注释。
这两个问题的解决方案可能是将关键字(“implements”)和类的匹配分成两个不同的匹配规则,也许你可以将它作为起点:
'(("\\bimplements\\b" . font-lock-keyword-face)
("\\b[A-Z]\\w*\\b" . font-lock-type-face))
答案 1 :(得分:1)
这样的事情似乎在这里起作用:
'("\\(implements\\)\\s-+\\(\\(\\sw+\\s-*,\\s-*\\)*\\sw+\\)"
(1 font-lock-warning-face)
(2 font-lock-keyword-face))
(显然你可能想要不同的面孔......)