我正在为 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: "\>">
Run Code Online (Sandbox Code Playgroud)
它是一种文本处理语言(想想类固醇降价),所以文本块必须是非限制性的。
我在为此编写 vim 语法文件时遇到了很多麻烦。
我可以
syn region myFunction start='<' end='>' skip='\\>'
syn region myArgs start='(' end=')' skip='\\)'
Run Code Online (Sandbox Code Playgroud)
但myFunction不能包含myArgs,因为在以下示例中括号错误地突出显示:
<function(arg) some text (with parenthesis) that aren't arguments>
Run Code Online (Sandbox Code Playgroud)
具体来说,我希望函数名称和参数列表仅在区域的开头突出显示。然而,我做不到
syn region myFunction start='<(regex to match name and arg list)' ...
Run Code Online (Sandbox Code Playgroud)
因为,即使regex to match name and arg list不可怕,这也会破坏我语法高亮嵌套函数的能力。
我要的是像nextgroup对start的syntax region,但我不能找到一个。
这可能吗?我如何在 vimscript 中做到这一点?
为与区域的前导<字符重叠的函数名称定义一个包含的语法匹配myFunction,然后用于nextgroup尝试myArgs仅在其之后匹配,而不是后续出现的匹配。
:syn region myFunction start='<' end='>' contains=myFunctionName
:syn match myFunctionName '<\i\+' contained nextgroup=myArgs
:syn region myArgs start='(' end=')' contained
Run Code Online (Sandbox Code Playgroud)
编辑:这是具有一个变体matchgroup的<...>元素; 在matchgroup不能被用于启动元件,因为其防止锚固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
Run Code Online (Sandbox Code Playgroud)