我正在为DSL编写vim语法高亮,其中函数遵循以下格式:
# A function with no arguments
<function>
# A function with arguments
<function(arg1, arg2)>
# A function with text
<function block of normal text>
# A function with args and text
<function(arg1,arg2) text>
# Line breaks are allowed pretty much everywhere.
<function(
arg1,
arg2)
a block of text>
# As is nesting
<function(<subfunc>) Some text with <another(subfunction) etc.>>
# Backslash escape
<function(single arg with a comma: "\,") contained bracket between quotes: "\>">
这是一种文本处理语言(想想类固醇上的降价),因此文本块必须是非限制性的。
我在为此编写vim语法文件时遇到了很多麻烦。
我能做到
syn region myFunction start='<' end='>' skip='\\>'
syn region myArgs start='(' end=')' skip='\\)'
但myFunction
不能包含myArgs
,因为以下示例中错误地突出显示了parens:
<function(arg) some text (with parenthesis) that aren't arguments>
具体来说,我希望功能名称和参数列表仅在区域的开头突出显示。但是,我做不到
syn region myFunction start='<(regex to match name and arg list)' ...
因为,即使regex to match name and arg list
不是可怕的,这也会破坏我对语法高亮嵌套函数的能力。
对于nextgroup
的{{1}},我想要的是start
,但我找不到。{/ p>
这可能吗?我如何在vimscript中执行此操作?
答案 0 :(得分:4)
为与<
区域的前导myFunction
字符重叠的函数名称定义包含的语法匹配,然后使用nextgroup
尝试仅与myArgs
匹配直接在它之后,而不是后续的事件。
:syn region myFunction start='<' end='>' contains=myFunctionName
:syn match myFunctionName '<\i\+' contained nextgroup=myArgs
:syn region myArgs start='(' end=')' contained
修改:这是matchgroup
元素上<...>
的变体; matchgroup
不能用于start元素,因为这会阻止myFunctionName
的锚定:
:syn region myFunction start='<' matchgroup=myMarker end='>' contains=myFunctionName
:syn match myFunctionName '<\i\+' contained nextgroup=myArgs contains=myMarker
:syn match myMarker '<' contained
:syn region myArgs start='(' end=')' contained
答案 1 :(得分:2)
也许您也可以尝试使用这些来更好地控制亮点:
syn region myFunction start='<' end='[^\\]>' contains=myFunctionName
syn match myFunctionName '<\i\+'hs=s+1 contained nextgroup=myArgs
syn region myArgs start='('hs=s+1 end=')'he=s-1 contained contains=myFunction