如何在 vim 语法区域中使用与开始和结束相同的模式?
How do I use the same pattern as begin and end in a vim syntax-region?
所以,我正在尝试为 OCaml 的 Menhir 解析器生成器构建语法。
在该语言中,一个文件分为三个部分,由 %%
分隔(不,它不漂亮;不幸的是,它继承自古老的 ocamlyacc。)
我正在尝试为这三个中的每一个创建一个单独的语法区域,再加上一个用于无关的第三个 %%
:
之后的任何内容
this should be in `menhirDeclarations`
%%
this should be in `menhirRules`
%%
this should be in `menhirOcamlFooter`
%%
this should be in `menhirSeparatorError`
%%
this should still be in the same `menhirSeparatorError`
我今天一直在研究 :h syn-define
文档,我已经定义了一个与第一个声明中的所有内容匹配的组:
syn region menhirDeclarations start=/\%^/ end=/%%/
\ contains=@menhirComments
… 但是我在扩展它以正确匹配以下部分时遇到了很多麻烦。天真的方法对我不起作用,例如:
" These break each document into the three sections of a Menhir parser definition:
syn region menhirSeparatorError start=/%%/ end=/%%/
\ contained contains=@menhirComments
syn region menhirOcamlFooter start=/%%/ end=/%%/
\ contained contains=@menhirCommentsnextgroup=menhirSeparatorError
syn region menhirRules start=/%%/ end=/%%/
\ contained contains=@menhirComments nextgroup=menhirOcamlFooter
syn region menhirDeclarations start=/\%^/ end=/%%/
\ contains=@menhirComments nextgroup=menhirRules
我怎样才能 Vim 将一个文件的语法突出显示分成多个部分,就像这样?
您的问题是 @@
分隔符包含在区域的开始和结束模式中,因此一个区域的结束匹配会掩盖下一个区域的潜在开始匹配。换句话说,如果部分由 @@@@
而不是 @@
.
分隔,则您的代码将有效
由于您确实需要断言一个部分的两边,您可以通过:help :syn-pattern-offset
停止结束区域的匹配。 me=s-1
(匹配结束是匹配开始前的一个字符)偏移量仍然断言一个部分以 @@
结束,但不消耗这两个字符不再。这样,nextgroup
就可以发挥它的魔力,在上一组结束后立即开始下一组:
syn region menhirDeclarations start=/\%^./ end=/%%/me=s-1 nextgroup=menhirRules
syn region menhirRules start=/%%/ end=/%%/me=s-1 contained nextgroup=menhirOcamlFooter
syn region menhirOcamlFooter start=/%%/ end=/%%/me=s-1 contained nextgroup=menhirSeparatorError
syn region menhirSeparatorError start=/%%/ end=/\%$/ contained
请注意,我不知何故必须匹配缓冲区开头的至少一个字符; /\%^/
对我不起作用(在 Vim 版本 8.1.536 中)。为了避免实现最后 menhirSeparatorError
组的多次重复匹配(也可以用相同的方法解决),我只是让它通过 /\%$/
.[=22 在缓冲区的末尾结束=]
所以,我正在尝试为 OCaml 的 Menhir 解析器生成器构建语法。
在该语言中,一个文件分为三个部分,由 %%
分隔(不,它不漂亮;不幸的是,它继承自古老的 ocamlyacc。)
我正在尝试为这三个中的每一个创建一个单独的语法区域,再加上一个用于无关的第三个 %%
:
this should be in `menhirDeclarations`
%%
this should be in `menhirRules`
%%
this should be in `menhirOcamlFooter`
%%
this should be in `menhirSeparatorError`
%%
this should still be in the same `menhirSeparatorError`
我今天一直在研究 :h syn-define
文档,我已经定义了一个与第一个声明中的所有内容匹配的组:
syn region menhirDeclarations start=/\%^/ end=/%%/
\ contains=@menhirComments
… 但是我在扩展它以正确匹配以下部分时遇到了很多麻烦。天真的方法对我不起作用,例如:
" These break each document into the three sections of a Menhir parser definition:
syn region menhirSeparatorError start=/%%/ end=/%%/
\ contained contains=@menhirComments
syn region menhirOcamlFooter start=/%%/ end=/%%/
\ contained contains=@menhirCommentsnextgroup=menhirSeparatorError
syn region menhirRules start=/%%/ end=/%%/
\ contained contains=@menhirComments nextgroup=menhirOcamlFooter
syn region menhirDeclarations start=/\%^/ end=/%%/
\ contains=@menhirComments nextgroup=menhirRules
我怎样才能 Vim 将一个文件的语法突出显示分成多个部分,就像这样?
您的问题是 @@
分隔符包含在区域的开始和结束模式中,因此一个区域的结束匹配会掩盖下一个区域的潜在开始匹配。换句话说,如果部分由 @@@@
而不是 @@
.
由于您确实需要断言一个部分的两边,您可以通过:help :syn-pattern-offset
停止结束区域的匹配。 me=s-1
(匹配结束是匹配开始前的一个字符)偏移量仍然断言一个部分以 @@
结束,但不消耗这两个字符不再。这样,nextgroup
就可以发挥它的魔力,在上一组结束后立即开始下一组:
syn region menhirDeclarations start=/\%^./ end=/%%/me=s-1 nextgroup=menhirRules
syn region menhirRules start=/%%/ end=/%%/me=s-1 contained nextgroup=menhirOcamlFooter
syn region menhirOcamlFooter start=/%%/ end=/%%/me=s-1 contained nextgroup=menhirSeparatorError
syn region menhirSeparatorError start=/%%/ end=/\%$/ contained
请注意,我不知何故必须匹配缓冲区开头的至少一个字符; /\%^/
对我不起作用(在 Vim 版本 8.1.536 中)。为了避免实现最后 menhirSeparatorError
组的多次重复匹配(也可以用相同的方法解决),我只是让它通过 /\%$/
.[=22 在缓冲区的末尾结束=]