Vim 语法区域模式中的关键字

Keyword in Vim syntax region pattern

我试图或多或少地为 Python 重现 Vim 中类似 C 文件的 if0 语法突出显示,其中代码被 #if 0#endif 变灰(突出显示为 Comment)。 我想将以 if 0:if False:.

开头的 Python 代码块变灰,而不是预处理器指令

受到的启发,我想出了以下几乎可以工作的代码:

syn region pyIfFalse start=/^\(\s*\)if \%(0\+\|False\):\n\+\z(\s\+\)\S/ skip=/^\%(\z1\S\|^$\)/ end=/^\z1\@!.*/me=s-1
hi def link pyIfFalse Comment

结果如下

 if 0: # grayed out (there is a space at the beginning)
   pass
if 0: # not grayed out
  pass

如果我将所有 if 替换为 ef(在示例和模式中),两个块都将变灰,这意味着问题一定出在关键字 if.

this question 之后,可以将 if 重新定义为 keyword contained,但这样它就不会在常规文本中突出显示,因此这似乎不是一个令人满意的解决方案。

令我感到非常惊讶的是,突出显示适用于第一个块而不是第二个块,唯一的区别是 if.

之前的 space

答案就在:help syn-priority.

  1. When multiple Match or Region items start in the same position, the item defined last has priority.
  2. A Keyword has priority over Match and Region items.
  3. An item that starts in an earlier position has priority over items that start in later positions.

在示例的第三行中,关键字优先于区域 (2.),但在第一行中,区域优先,因为它开始得早 (3.)。

由于没有更好的选择,解决方法是将 if 的突出显示降级为在区域 (1.) 之前定义的匹配项。

syn clear pythonConditional
syn keyword pythonConditional elif else
syn match pythonIf /\<if\>/
syn region pyIfFalse start=/^\(\s*\)if \%(0\+\|False\):\n\+\z(\s\+\)\S/ skip=/^\%(\z1\S\|^$\)/ end=/^\z1\@!.*/me=s-1
hi def link pythonConditional  Conditional
hi def link pythonIf  Conditional
hi def link pyIfFalse Comment