如何将 vim 语法组分配给 'Foo( ... )'?对于任意...包括包含的括号

  • 本文关键字:于任意 包括包 Foo vim 语法 分配 vim
  • 更新时间 :
  • 英文 :


我正在尝试为我的调试宏提供不同的颜色,不仅仅是宏名称,而且至少是相同颜色的左括号和右括号。

作为测试,我当前使用以下行:

,--- Uncolored paren!?
v
int foobar; Dout( (( ) ) ( ) ); f((char*)x);
^^^^^^^^^^^^^^^^^^
__ all of this should be colored.

如果我尝试以下语法规则:

syn region Debug matchgroup=DebugDelim start=/Dout(/ end=/)/ contains=cParen

那么这是行不通的:应该是 cParen 一部分的第一个右括号不再是任何突出显示组的一部分,因此保持无色。

这是 vim 中的错误还是我做错了什么?

注意:这里的cParen被定义为"通常"(在vim的c.vim语法文件中)。

编辑:在弄清楚我之前问题的答案(即包含的组在开始和结束模式内匹配,除非您使用 matchgroup 参数),我将我的问题更改为对我来说仍然是一个问题。

经过一个多星期的研究和尝试;主要结论是 vim 的语法系统需要重新设计。它是有缺陷的。

话虽如此,最好的答案是"这不可能做到",因为系统太破碎了;但是 - 通过大量的努力,可以锻造一种可怕的工作(对于这种情况 - 不是我真正需要的),如下所示:

" Highlight my debug macros.
" A group with things that are normally already excluded from cParen.
syn cluster cwNotInParen contains=@cParenGroup,cCppParen,cErrInBracket,cCppBracket,@cStringGroup,@Spell
" Create a new cParen syntax group that will have Debug highlighting.
syn region cwDebugParen transparent matchgroup=cwDebugParenDelim contains=ALLBUT,@cwNotInParen
       start='(' end=")@="
" Define cParen last, so it will overrule the previous one.
syn clear cParen
syn region cParen transparent contains=ALLBUT,@cwNotInParen,cwDebugParen
       start='(' end=')'
" Redefine cCppParen to also exclude cwDebugParen
syn clear cCppParen
syn region cCppParen transparent contained contains=ALLBUT,@cParenGroup,cErrInBracket,cParen,cwDebugParen,cBracket,cString,@Spell
      start='(' skip='\$' excludenl end=')' end='$'
" Redefine cCppBracket to also exclude cwDebugParen.
syn clear cCppBracket
syn region cCppBracket transparent contained contains=ALLBUT,@cParenGroup,cErrInParen,cParen,cwDebugParen,cBracket,cString,@Spell
      start='[|<::@!' skip='\$' excludenl end=']|:>' end='$'
" Add a syntax group for "Debug( ... );".
syn region cwDebugMacros transparent matchgroup=cwDebugMacrosDelim contains=cwDebugParen
       start="vW(Debug|DoutFatal|DoutEntering|Dout|ASSERT|assert)(@="hs=s+1
       start="v^(Debug|DoutFatal|DoutEntering|Dout|ASSERT|assert)(@="
       end="v);?"
hi link cwDebugMacrosDelim Debug       " Highlight 'Debug' and the close paren of that macro.
hi link cwDebugParenDelim Debug        " Highlight the open paren of the Debug macro.

其工作原理如下:

将创建一个名为cwDebugParen的新语法组。它基本上与cParen相同,但括号会突出显示。由于语法定义在许多地方都包含ALLBUT,因此现在将在任何地方都接受这个新组。可以 - 但不是很方便 - 只需用您自己的语法文件替换整个语法文件,然后将新cwDebugParen添加到所有ALLBUT,...列表中,但在这种情况下,删除cParen并在定义cwDebugParen后重新定义它更容易,有效地隐藏它,因为将使用匹配的最后一个规则。不幸的是,cParen的定义取决于一些条件,所以整体会变得非常复杂;因此,我只是根据我的 .vimrc 选择了一个 cParen 定义。

因为cParen没有matchgroup所以我发现它的启动模式仍然cwDebugParen?! --匹配,这对我来说似乎是一个错误,但至少可以通过向ALLBUT列表中添加cwDebugParen来避免cParen

cwDebugParen本身确实有一个matchgroup,这当然是括号的语法高亮所必需的。注意,虽然它以结束')'结束,但我使用零匹配(:help @=),因为需要相同的帕伦来结束封闭cwDebugMacros区域。请注意,使用end=')'me=s-1在这里会产生相同的效果。

最后添加了一个新的区域,cwDebugMacros,它从Debug(这样的模式开始,到);结束。这两个start=参数是必要的,因为它们使用不同的突出显示开始 (hs),因为一个从行的开头开始,而另一个要求在Debug前面有一个非单词字符。此外,这里的开场白是零匹配,因为我们需要它来启动我们在此区域中包含的cwDebugParen区域(幸运的是我们可以在这里使用零匹配;因为me=s-1不支持start!?)。然后,这将吞噬所有输入,直到结束括号,因此我们不必担心我们的结束将匹配不是调试宏的结束参数的结束参数。请注意,我在分号后使用了带有问号的end="v);?",因此如果分号直接跟随结束参数,那么它也被涂成相同的颜色(我喜欢这样),而如果出于某种原因之间有空格(包括注释),那么事情就不会被破坏 - 只有分号不再着色。

编辑:为cCppParen和cCppBracket添加了重新定义,它们使用构造ALLBUT=...,cParen,...,因此现在还需要排除cwDebugParen

最新更新