我可以级联vim语法强调纳米中的规则吗?

发布于 2025-02-08 12:02:41 字数 1248 浏览 3 评论 0原文

我有一个自定义文件类型,其中包含许多字段,例如

FieldName: FieldValue

我试图在nano和vim中为此filetype创建语法突出显示,因此“ fieldname”以蓝色出现,以及从结肠上开始的任何内容,包括colon,包括结肠,以黄色出现。在Nano中,由于其“级联”性质,我很容易实现这一目标:

color yellow     start="^FieldName: " end="$"   # Make the whole thing yellow
color brightblue       "^FieldName"             # Then change the first part to blue

在VIM中,它看起来不像规则级联,但是我可以使用“ MatchGroup”来实现上述内容,这允许对待“边界”与“内容”的匹配不同:

syn region Yellow matchgroup=Blue start="^FieldName" end="$"                                                                                                                                          

到目前为止,一切都很好。在特殊情况下,出现了问题,即某些野外值需要不同,因为它们很特别。在Nano中,我可以简单地将另一个规则添加到级联:

color yellow         start="^FieldNAme: " end="$"     # Make the whole thing yellow
color bold,lightyellow,red "^FieldName: SpecialValue" # Then change up to the special value to red
color yellow               "^FieldName: "             # Then up to the colon to yellow again
color brightblue           "^FieldName"               # Then up to the fieldname to blue

但是,当我尝试在VIM中做同样的事情时,我就会被卡住。我不知道如何在多个级别上匹配组。有没有办法在VIM中启用这种级联行为?或者,或者,有人可以将我指向正确的方向以实现上述效果吗?

I have a custom file type, which contains lots of fields like

FieldName: FieldValue

I'm trying to create syntax highlighting for this filetype, in nano and vim, such that "Fieldname" appears in blue, and anything from the colon onwards, including the colon, appears in yellow. In nano I achieve this easily due to its 'cascading' nature:

color yellow     start="^FieldName: " end="
quot;   # Make the whole thing yellow
color brightblue       "^FieldName"             # Then change the first part to blue

In vim, it doesn't look like rules cascade, but I can achieve the above using 'matchgroup', which allows treating 'boundary' matches differently to 'content':

syn region Yellow matchgroup=Blue start="^FieldName" end="
quot;                                                                                                                                          

So far so good. The problem arises in the special case that some FieldValues need to be coloured differently, because they are special. In nano, I can simply add another rule onto the cascade:

color yellow         start="^FieldNAme: " end="
quot;     # Make the whole thing yellow
color bold,lightyellow,red "^FieldName: SpecialValue" # Then change up to the special value to red
color yellow               "^FieldName: "             # Then up to the colon to yellow again
color brightblue           "^FieldName"               # Then up to the fieldname to blue

However, when I try to do the same in vim, I am stuck. I have no idea how to match groups at multiple levels. Is there a way to enable such cascading behaviour in vim? Or, alternatively, can someone point me in the right direction to achieve the above effect?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧情别恋 2025-02-15 12:02:42

在VIM中,如果在另一个语法匹配/区域内,则只尝试了一些的。这些匹配必须出现在中包含= xxx,yyy,zzz属性的属性(或者,或者,它们可以具有属性contecation in = aaa,其中> AAA是高级匹配)。此外,子匹配通常应具有包含属性,该属性禁止在全球级别(即未经包含)匹配它们。

最后,如果出现碰撞(即两个或多个子匹配可以在同一位置匹配),则最后一个胜利。因此订单很重要。

更新。这个示例非常简单,不需要很多规则。然而,确切的正则定义可能会有所不同,因此将其提供出于说明目的。

var.1

syn match MyFileFieldWhole /^\w\+: .*/ contains=MyFileFieldName,MyFileFieldSpecial
syn match MyFileFieldName /^\w\+/ contained
syn keyword MyFileFieldSpecial SpecialValue contained

hi def MyFileFieldWhole guifg=yellow
hi def MyFileFieldName guifg=lightblue
hi def MyFileFieldSpecial guifg=red

var.2

syn match MyFileFieldName /^\w\+: /me=e-2 nextgroup=MyFileFieldValue
syn match MyFileFieldValue /: .*/ contains=MyFileFieldSpecial contained
syn keyword MyFileFieldSpecial SpecialValue contained

hi def MyFileFieldName guifg=lightblue
hi def MyFileFieldValue guifg=yellow
hi def MyFileFieldSpecial guifg=red

In Vim if inside another syntax match/region then only some of submatches tried. These matches must appear in contains=xxx,yyy,zzz attribute of an upper level match (or, alternatively, they can have an attribute containedin=aaa, where aaa is an upper-level match). Also the sub-matches should usually have contained attribute that forbids matching them on the global level (i.e. uncontained).

As a final note, if a collision arises (i.e. two or more submatches can match at the same position) then the last one wins. So the order matters.

Upd. This example is pretty straightforward and doesn't need many rules. Yet exact regex definitions may vary, so giving it rather for illustrative purposes.

Var.1

syn match MyFileFieldWhole /^\w\+: .*/ contains=MyFileFieldName,MyFileFieldSpecial
syn match MyFileFieldName /^\w\+/ contained
syn keyword MyFileFieldSpecial SpecialValue contained

hi def MyFileFieldWhole guifg=yellow
hi def MyFileFieldName guifg=lightblue
hi def MyFileFieldSpecial guifg=red

Var.2

syn match MyFileFieldName /^\w\+: /me=e-2 nextgroup=MyFileFieldValue
syn match MyFileFieldValue /: .*/ contains=MyFileFieldSpecial contained
syn keyword MyFileFieldSpecial SpecialValue contained

hi def MyFileFieldName guifg=lightblue
hi def MyFileFieldValue guifg=yellow
hi def MyFileFieldSpecial guifg=red
墨小墨 2025-02-15 12:02:42

这就是我解决上述问题的方式(使用与上述相同的伪场,仅在此处显示相关规则)。希望这对面临同样挑战的人来说可能很有用。

" Vim syntax file
" Language   : myfiletype
" Filenames  : *.myfileextension
" Maintainer : Me
" Last Change: 2022-06-19

" Quit when a (custom) syntax file was already loaded
if exists("b:current_syntax")
  finish
endif

" SpecialValue is special, put it in red box. Fieldname in blue.
syn match Group1 "^FieldName: SpecialValue$"    contains=Group2
syn match Group2 "^FieldName: \zeSpecialValue$" contains=Group3 contained
syn match Group3 "^FieldName\ze: SpecialValue$" contained

" all other values in plain yellow, with fieldname in blue.
syn match Group2 "^FieldName: \(SpecialValue$\)\@!.*$"    contains=Group3
syn match Group3 "^FieldName\ze: \(SpecialValue$\)\@!.*$" contained

" Group-code color definitions ==
hi def Group3             ctermfg=blue
hi def Group2             ctermfg=darkyellow
hi def Group1 cterm=bold  ctermfg=yellow  ctermbg=darkred

let b:current_syntax = "myfiletype"

一些解释性注释:

  • 我使用syn-match而不是syn-region,因为前者保证的单行匹配。

  • \ ze位作用为“剪切”; REGEXP首先匹配,然后“切割”到\ ze部分,然后将其用于突出显示。

  • \@!导致Regexp在上一个原子(在这种情况下为括号中的位)时成功。

  • “外部匹配”相同的各种'coartment'级别,但是在每个级别上,由\ ze引起的“内部匹配” 较短,较短,设法模仿'我追求的效果。但是,必须添加一个添加的案例,不需要添加特殊值,以说明不存在特殊值的“默认”案例(相比之下,只要该“默认”规则是放在“级联”的顶部)。

  • 上面的示例演示了单个特别值的规则。如果您有多个特殊值可以排除(在我的实际问题中是这种情况),则可以转换\(specialValue $ \)\@! \(SpecialValue1 \ | specialValue2 \)\ @!等,以说明“默认”规则中的明确排除所有特殊值。


This is how I solved the above problem, (using the same pseudofields as above, and showing only the relevant rules here). Hopefully this might prove useful to others with the same challenge.

" Vim syntax file
" Language   : myfiletype
" Filenames  : *.myfileextension
" Maintainer : Me
" Last Change: 2022-06-19

" Quit when a (custom) syntax file was already loaded
if exists("b:current_syntax")
  finish
endif

" SpecialValue is special, put it in red box. Fieldname in blue.
syn match Group1 "^FieldName: SpecialValue
quot;    contains=Group2
syn match Group2 "^FieldName: \zeSpecialValue
quot; contains=Group3 contained
syn match Group3 "^FieldName\ze: SpecialValue
quot; contained

" all other values in plain yellow, with fieldname in blue.
syn match Group2 "^FieldName: \(SpecialValue$\)\@!.*
quot;    contains=Group3
syn match Group3 "^FieldName\ze: \(SpecialValue$\)\@!.*
quot; contained

" Group-code color definitions ==
hi def Group3             ctermfg=blue
hi def Group2             ctermfg=darkyellow
hi def Group1 cterm=bold  ctermfg=yellow  ctermbg=darkred

let b:current_syntax = "myfiletype"

Some explanatory notes:

  • I used syn-match instead of syn-region in the end, as the former guaranteed single-line matching.

  • The \ze bit acts as a 'cut'; the regexp first matches fully, then gets 'cut' up until the \ze part, which is then used for the highlighting.

  • The \@! causes the regexp to succeed when the previous atom (in this case the bit in parentheses) is NOT present.

  • The various 'containment' levels, where the 'outer match' is the same, but at each level the 'inner match' caused by \ze is shorter and shorter, manages to emulate the 'cascading' effect I was after. However, an added case explicitly excluding the specialvalue had to be added, to account for 'default' cases where the special value is not present (By contrast, in nano, no explicit exclusion was necessary, as long as this 'default' rule was placed at the top of the 'cascade').

  • The above example demonstrates rules accounting for a single specialvalue. If you have multiple specialvalues to exclude (which was the case in my actual problem), you can convert \(SpecialValue$\)\@! to \(SpecialValue1\|SpecialValue2\)\@!, etc, to account for the explicit exclusion of all special values in the 'default' rule.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文