2013-01-20 89 views
1

考慮以下3套高亮組和語法匹配:爲什麼nextgroup不匹配換行而沒有結尾空白?

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 

FillerBarFoo後匹配;同樣地,Qux僅在BazXyz之後僅在Abc之後。下面的例子,用:set list爲清楚起見,說明如何FillerBar不匹配後Foo除非Foo一直尾隨空白:

BazQux例子驗證\_s匹配換行符,所以爲什麼不這樣工作時Baz分爲FooFiller?這從:help syn-skipnl報價是相關的:

當「skipnl」存在,與之相匹配的nextgroup可能會在未來 線被發現。只有當前項目在當前 行結束時纔會發生!當「skipnl」不存在時,只有在同一行中的當前項目 之後纔會找到下一個組。

AbcXyz例如,使用skipwhiteskipnl和不完全\_s,確實在這兩種情況下匹配。這是否意味着EOL不符合「在同一行中的當前項目之後」?當然,它不能成爲下一行的一部分?這似乎與以下事實相矛盾:正常搜索\_s\n導致EOL字符在同一行上匹配。

+0

我不完全相信你問什麼。你的截圖中的結果似乎與你想要做的相匹配(正如我從你的代碼中理解的那樣)。 – romainl

+0

我不明白爲什麼'Filler'與第2行的'EOL'不匹配,這會導致'Bar'與第3行匹配。 –

回答

0

如果比賽\n之前剛剛結束後,nextgroup參數將被忽略,除非還指定了skipnl,即使在nextgroup組的人會匹配開始\n

在給出的示例中,由於第一Foo比賽立即結束\nFoo之前沒有指定skipnl,Vim不會甚至嘗試匹配Filler。引入其他空格允許Filler在第二個Foo匹配後匹配,並且由於Filler包括\n,所以Bar也可以匹配,而不指定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; 

/* handle next_list, unless at end of line and no "skipnl" or 
* "skipempty" */ 
current_next_list = cur_si->si_next_list; 
current_next_flags = cur_si->si_flags; 
if (!(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY)) 
     && syn_getcurline()[current_col] == NUL) 
    current_next_list = NULL; 
相關問題