1

我正在尝试使用 font-lock 和 elisp 的正则表达式来突出显示如下内容:

class Foo implements A, B, C, D { }

问题是 . 之后的逗号分隔列表的长度未知implements。我已经完成了正则表达式,它突出显示了列表中的所有单词(使用 re-buider,A、B、C 和 D 被突出显示):

"implements\\s-+\\(?:\\(\\sw+\\)\\s-*,\\s-*\\)*\\(\\sw+\\)"

但我无法将它与字体锁定结合起来。

明显地

'("implements\\s-+\\(?:\\(\\sw+\\)\\s-*,\\s-*\\)*\\(\\sw+\\)"
  (1 font-lock-type-face) (2 font-lock-type-face))

不起作用,因为它仅突出显示最后一次出现(C 和 D),忽略*第一次反向引用后的星号 ( )。

有没有办法捕获所有匹配单词的列表,或者可能完全不同的方法来解决这个问题?

4

2 回答 2

2

如果您不希望逗号也被突出显示,那么您的方法就行不通。当您使用表单的subexp-highlighter

(subexp facespec)

thesubexp指的是你的正则表达式的子组,并用给定的facespec. 现在,正则表达式匹配的子组是具有开头和结尾的连续文本范围。事实上,每当您进行正则表达式搜索时,您都可以使用函数(match-beginning subexp)和查询这些值(match-end subexp)

但这意味着您不能将可变数量的类名(不包括逗号)与单个子表达式匹配,因为该子表达式必须是连续的跨度。覆盖可变数量的类名的连续跨度也必须始终包含逗号,这是没有办法的。

这是您的方法不是一个好主意的另一个原因:您的正则表达式明确使用空格。是否将空格从突出显示中排除并不重要,但即使在正则表达式中使用它也不是一个好主意,因为只要允许空格,您也总是会遇到注释。

考虑以下代码行:

class Foo implements A, /*B, C,*/ D { }

在这种情况下,您可能希望使用和周围的类/*B, C,*/突出显示范围中的字符。如果仅在其他所有内容都已突出显示之后才突出显示注释,并且允许注释覆盖其他字体锁定匹配项,您仍然可以实现此效果。但这将导致相当低效的匹配,因为每个注释首先会像代码一样突出显示,然后在第二遍中作为注释突出显示。font-lock-comment-facefont-lock-type-face

这两个问题的解决方案可能是将关键字(“实现”)和类的匹配划分为两个不同的匹配规则,也许您可​​以使用以下内容作为起点:

'(("\\bimplements\\b" . font-lock-keyword-face)
  ("\\b[A-Z]\\w*\\b" . font-lock-type-face))
于 2011-05-29T22:06:21.953 回答
1

像这样的东西似乎在这里工作:

'("\\(implements\\)\\s-+\\(\\(\\sw+\\s-*,\\s-*\\)*\\sw+\\)"
   (1 font-lock-warning-face)
   (2 font-lock-keyword-face))

(显然你可能想要不同的面孔......)

于 2011-05-26T09:20:08.827 回答