考虑以下3组高亮组和语法匹配:
hi Foo ctermfg=black ctermbg=red guifg=black guibg=red
hi Filler ctermfg=black ctermbg=green guifg=black guibg=green
hi Bar ctermfg=black ctermbg=blue guifg=black guibg=blue
syn match Foo "foo" nextgroup=Filler
syn match Filler "\_s*" nextgroup=Bar contained
syn match Bar "bar" contained
hi Baz ctermfg=black ctermbg=cyan guifg=black guibg=cyan
hi Qux ctermfg=black ctermbg=yellow guifg=black guibg=yellow
syn match Baz "baz\_s*" nextgroup=Qux
syn match Qux "qux" contained
hi Abc ctermfg=black ctermbg=magenta guifg=black guibg=magenta
hi Xyz ctermfg=black ctermbg=white guifg=black guibg=white
syn match Abc "abc" nextgroup=Xyz skipwhite skipnl
syn match Xyz "xyz" contained
Filler
和Bar
仅在Foo
之后匹配;同样地,Qux
仅在Baz
之后,而Xyz
仅在Abc
之后。以下示例({1}}为清晰起见,说明了在:set list
之后Filler
和Bar
不匹配的情况,除非Foo
具有尾随空格:
Foo
Baz
示例验证Qux
是否与换行符匹配,因此当\_s
分为Baz
和{{1}时,为什么这不起作用? }}?来自:help syn-skipnl
的引用是相关的:
当存在“skipnl”时,可以在下一个中找到与nextgroup的匹配 线。仅当当前项目在当前结束时结束时才会发生这种情况 线!当“skipnl”不存在时,仅在之后找到下一组 当前项目在同一行。
使用Foo
Filler
且完全没有Abc
的{{1}} Xyz
示例确实在两种情况下都匹配。这是否意味着skipwhite
不符合“在同一行中的当前项目之后”?当然它不能成为下一行的一部分?这似乎与以下事实相矛盾:skipnl
或\_s
的正常搜索会导致EOL
个字符在同一行上匹配。
答案 0 :(得分:0)
如果匹配在\n
之前结束,则nextgroup
参数将被忽略,除非skipnl
也被指定,即使nextgroup
中的某个组匹配以\n
开头。
在给定的示例中,由于第一个Foo
匹配在\n
之前结束且Foo
未指定skipnl
,因此Vim甚至不会尝试匹配{{1} }}。其他空格的引入允许Filler
在第二次Filler
匹配后匹配,并且由于Foo
包含Filler
,\n
也可以在没有Bar
的情况下匹配指定Filler
。
相关代码位于skipnl
:
src/syntax.c
和
/* nextgroup ends at end of line, unless "skipnl" or "skipempty" present */
if (current_next_list != NULL
&& syn_getcurline()[current_col + 1] == NUL
&& !(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY)))
current_next_list = NULL;