为什么 taskinfo 语法文件不能按预期工作?

Why taskinfo syntax file does not work as expect?

我有以下语法文件:

syn match TaskName /^\[.*\]/
syn match TaskType  /^\[.*\]\s*\zs[a-z]*/
syn match TaskDescription  /^\[.*\]\s*[a-z]*\s\+\zs.*/
hi def link TaskName Title
hi def link TaskType Todo
hi def link TaskDescription Comment

上下文是:

Task          Type          Command
[file-run]    local         no description

为什么只有 [file-run] 匹配?

如果我在正常模式下键入 /^\[.*\]\s*\zs[a-z]*,将匹配 local

不匹配的原因是:syn match没有尝试 评估它已经匹配的文本。因此,它 不能 匹配已经被 :syn match TaskName 匹配的文本。


此外,您的模式还有很多可以改进的地方,特别是:

  • 您有很多匹配空字符串的模式原子。 这会使模式匹配变慢,因为像 [a-z]* 这样的模式将匹配 无处不在(特别是这种模式甚至被指出作为一个例子 :syn-pattern 的帮助文档中应避免的模式)。多数情况 在某些情况下,与 0 或 0 相比,1 或更多 \+ 匹配更好 更多 匹配 *.
  • 您可以使用其他方法使所有模式更简洁、更清晰 :syn match.
  • 的参数

我建议结合使用 nextgroup 论点的力量 使用 skipwhite 参数 :syn match:

  • nextgroup 让你知道 Vim 尝试匹配此匹配后指定的组。
  • skipwhite 参数允许您跳过制表符和空格 尝试将下一组与 nextgroup.
  • 匹配

牢记这些,您可以将模式重写为:

syn match TaskName /^\[.\+\]/ nextgroup=TaskType skipwhite
syn match TaskType /[a-z]\+/ nextgroup=TaskDescription skipwhite
syn match TaskDescription /\w\+\(\s\+\w\+\)*/

为此,我还将您的 TaskDescription 匹配项编辑为“一个词, 后跟 0 个或多个由空格分隔的单词。

你可以看到利用 nextgroupskipwhite 使每个语法匹配 更简洁,也让每组的内容更清晰。


相关 :help 查询:

:h :syn-match
:h :syn-pattern
:h :syn-nextgroup
:h :syn-skipwhite