为什么nextgroup与newline不匹配而没有尾随空格?

时间:2013-01-20 16:56:33

标签: regex syntax syntax-highlighting vim

考虑以下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

FillerBar仅在Foo之后匹配;同样地,Qux仅在Baz之后,而Xyz仅在Abc之后。以下示例({1}}为清晰起见,说明了在:set list之后FillerBar不匹配的情况,除非Foo具有尾随空格:

Foo Baz示例验证Qux是否与换行符匹配,因此当\_s分为Baz和{{1}时,为什么这不起作用? }}?来自:help syn-skipnl的引用是相关的:

  

当存在“skipnl”时,可以在下一个中找到与nextgroup的匹配   线。仅当当前项目在当前结束时结束时才会发生这种情况   线!当“skipnl”不存在时,仅在之后找到下一组   当前项目在同一行。

使用Foo Filler且完全没有Abc的{​​{1}} Xyz示例确实在两种情况下都匹配。这是否意味着skipwhite不符合“在同一行中的当前项目之后”?当然它不能成为下一行的一部分?这似乎与以下事实相矛盾:skipnl\_s的正常搜索会导致EOL个字符在同一行上匹配。

1 个答案:

答案 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;