vim - 如何在语法文件中匹配链接序列

3

我希望在vim中为我自定义的文件类型创建一个语法文件。其中一部分语法是这行:

entry: 1,02:15:00,03:15:00,56,Some String

我希望能够将每个部分分别匹配以分配不同的颜色。其中entry应该是一个部分,1应该是一个部分,02:15:00应该是一个部分,03:15:00应该是另一个部分,56应该是另一个部分,Some String应该是一个不同的部分,所有的,都是一个部分。每个部分都应该有不同的名称,以便我可以根据需要使用不同的颜色对它们进行着色。
我尝试使用contains来匹配它们,但是相似的值(第一次和第二次)会得到相同的名称。我还尝试使用nextgroup将它们链接在一起,但这样会导致,拥有许多我需要单独着色的名称(而且原始文件中有很多逗号,不像我在这里展示的简单示例)。
是否有一种正确的方法来进行这种语法高亮?
1个回答

3
您可以通过以下方式将所有逗号分隔的名称链接到一个名称:
" Adjust the below to make commas have another color.
" It is common that instead of defining colors directly you link 
" new highlighting groups to some standard one.
hi def link MySyntaxComma Delimiter

hi def link MySyntaxCommaAfterNumber       MySyntaxComma
hi def link MySyntaxCommaAfterFirstTime    MySyntaxComma
hi def link MySyntaxCommaAfterSecondTime   MySyntaxComma
hi def link MySyntaxCommaAfterSecondNumber MySyntaxComma

您也可以使用循环和:execute来隐藏重复的规则:
syntax match MySyntaxEntryStart /^entry:\s*/ nextgroup=MySyntaxNumber1
let s:rules=[['Number1', '\d\+'], ['Time1', '\d\d:\d\d:\d\d'], ['Time2', '\d\d:\d\d:\d\d'], ['Number2', '\d\+'], ['String', '.*']]
while !empty(s:rules)
    let [s:name, s:reg]=remove(s:rules, 0)
    let s:cmd='syntax match MySyntax'.s:name.' /'.s:reg.'/ contained'
    if !empty(s:rules)
        let s:cmd.=' nextgroup=MySyntaxCommaAfter'.s:name
        execute 'syntax match MySyntaxCommaAfter'.s:name.' /,/ contained nextgroup=MySyntax'.s:rules[0][0]
        execute 'hi def link MySyntaxCommaAfter'.s:name.' MySyntaxComma'
    endif
    execute s:cmd
endwhile
unlet s:rules s:cmd s:name s:reg

如果你想一想,这与给它们每个着色是一样的,因为我仍然需要将它们链接起来。你提出的建议是一个好的实践。最初的问题是有很多逗号,所以我想也许有一个像 separatorinbetween 这样的命令,就像有 startend 一样。我会标记你的答案,因为我猜这已经是最好的了。 - ccit
@ccit 你不能使用一个分隔符匹配规则来创建正常的nextgroup链。最好的方法是将所有的冗余代码组合成一个较小的循环,并使用:execute命令(我会在答案中更新示例)。 - ZyX
你很棒。新的建议正是我所需要的。我从未想过使用编程(如循环等)来解决它。聪明的解决方案,因此也点了个赞。谢谢。 - ccit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接