我试图给调试宏一种不同的颜色,不仅是宏名,而且至少是同一颜色的左括号和右括号。
作为测试,我当前使用以下行:
[A-Za-z0-9!#$%&(){|}~:;<=>?@*+,./^_`\'\" \t\r\n\f-]+
如果我尝试以下语法规则:
,--- Uncolored paren!?
v
int foobar; Dout( (( ) ) ( ) ); f((char*)x);
^^^^^^^^^^^^^^^^^^
\__ all of this should be colored.
然后这不起作用:应该作为cParen一部分的第一个右括号不再是任何突出显示组的一部分,因此保持不变色。
这是vim中的错误还是我做错了什么?
注意:这里的cParen被定义为“通常”(在vim的c.vim语法文件中)。
编辑:在弄清楚我上一个问题的答案(即除非您使用matchgroup参数,否则包含的组在开始和结束模式内匹配)之后,我将问题更改为对我来说仍然是一个问题。
答案 0 :(得分:0)
经过一个多星期的研究和尝试;主要结论是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="\v\W(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
,所以这个新组现在将在任何地方被接受。可以-但不是很方便-只是用您自己的 whole 语法文件替换,然后将新的cwDebugParen
添加到所有ALLBUT,...
列表中,但是在这种情况下,更容易删除cParen
并在cwDebugParen
的定义之后重新定义它,由于使用了最后一个匹配的规则,因此有效地隐藏了它。不幸的是cParen
的定义取决于一些条件,因此整个情况会变得非常复杂。因此,我只是选择了一个基于.vimrc的cParen定义。
因为cParen
没有matchgroup
,我发现它的开始模式是 still 还与cwDebugParen
匹配? ! -对我来说似乎是一个错误,但至少可以通过在cwDebugParen
的{{1}}列表中添加ALLBUT
来避免。
cParen
本身确实具有cwDebugParen
,这当然是突出显示语法的必要条件。请注意,尽管它以结束括号matchgroup
结尾,但是我使用零匹配(')'
),因为需要相同的括号来结束封闭的:help \@=
区域。请注意,在这里使用cwDebugMacros
具有相同的效果。
最后,添加了一个新区域end=')'me=s-1
,该区域以类似cwDebugMacros
的模式开始,并以Debug(
结束。这两个);
参数是必需的,因为它们使用了不同的突出显示开始(hs),因为一个在行的开头开始,而另一个则要求在start=
前面有一个非单词字符。另外,此处的开头括号为零匹配,因为我们需要它来开始包含在该区域中的Debug
区域(幸运的是,我们可以在此处使用零匹配;因为{{ 1}}不支持cwDebugParen
!?)。然后,它将吞噬所有输入,直到结束括号,因此我们不必担心我们的终端将匹配不是调试宏的结束括号的结束括号。请注意,我在分号后使用了me=s-1
,并带有问号,因此如果分号直接跟在结束括号后面,则它也会被涂成相同的颜色(我喜欢这样),而无论出于何种原因在这之间没有空格(包括注释),那么事情就不会破裂-那时只不再使用分号了。
编辑:为使用结构start
的cCppParen和cCppBracket添加了重新定义,因此现在还需要排除end="\v\);?"
。