【问题标题】:How do I use the same pattern as begin and end in a vim syntax-region?如何在 vim 语法区域中使用与开始和结束相同的模式?
【发布时间】:2019-06-01 16:55:33
【问题描述】:

所以,我正在尝试为 OCaml 的 Menhir parser-generator 构建语法。

在那种语言中,一个文件由三个部分组成,由 %% 分隔(不,它不漂亮;不幸的是,它继承自古老的 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 像这样将文件的语法高亮拆分成多个部分?

【问题讨论】:

    标签: vim vim-syntax-highlighting


    【解决方案1】:

    您的问题是@@ 分隔符包含在区域的开始和结束模式中,因此一个区域的结束匹配掩盖了下一个区域的潜在开始匹配。换句话说,如果部分由@@@@ 而非@@ 分隔,您的代码将起作用。

    由于您确实需要断言节的两侧,因此您可以通过: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 组的多次重复匹配(也可以用相同的方法解决),我只是通过/\%$/ 让它在缓冲区的末尾结束。

    【讨论】:

    • 在您发布此内容之前不久,我尝试使用lc 而不是me — 我不太明白为什么我的类似方法不起作用!此外,奇怪的是,我在第一个区域的 start 处没有匹配的初始字符的情况下进行了 一些 尝试确实 有效,但大多数都没有。这修复了我以前的许多方法,以及在您的特定配置中工作。 谢谢!
    猜你喜欢
    • 2015-10-19
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-05
    • 1970-01-01
    • 2011-03-02
    相关资源
    最近更新 更多