Вопрос

Here is what I got so far:

syntax match cfg_Comment '#.*$' contains=cfg_DocTag
syntax match cfg_DocTag  '#\s*\zs[\\@]\l\+' contained

highlight default link cfg_Comment Comment
highlight default link cfg_DocTag  SpecialComment

Works perfectly for something like:

##
#   @brief The maximum.
#    @type number
# @default 1

What I want to do next is to highlight the next word after @type with Type group. So I did the following:

syntax match cfg_Comment '#.*$' contains=cfg_DocTag,cfg_DocField_type
syntax match cfg_DocTag  '#\s*\zs[\\@]\l\+' contained

syntax match cfg_DocTag_type   '@type' containedin=cfg_DocTag nextgroup=cfg_DocField_type skipwhite
syntax match cfg_DocField_type '\a\+' contained

highlight default link cfg_Comment       Comment
highlight default link cfg_DocTag        SpecialComment
highlight default link cfg_DocField_type Type

There are 2 issues with this:

  1. Now @type is not highlighted, and I get it because obviously I didn't specify the group for it, but I expected it to sort of inherit the color from its parent container cfg_DocTag.
  2. Of course now everything in comments is of Type color and not just the word after @type, and I get it again because I specified that cfg_Comment is a container of cfg_DocField_type.

I know where the issues stem from, but I don't know how to elegantly solve them and write as less boilerplate code as possible.

Finally, can someone tell me why

syntax match cfg_DocTag_type '@type' containedin=cfg_DocTag nextgroup=cfg_DocField_type skipwhite

and

syntax keyword cfg_DocTag_type @type containedin=cfg_DocTag nextgroup=cfg_DocField_type skipwhite

are not the same? I.e. in the first case it's as I described above: @type is no longer highlighted since the group is not specified, but this is expected. But in the second case, it is highlighted even though the group is not specified, which is unexpected, so it feels like as a keyword it doesn't match at all. And it is easily provable with the simplest test case possible:

  1. Highlighting works:

    syntax match Test '@type'
    
    highlight default link Test Keyword
    
  2. Highlighting doesn't work:

    syntax keyword Test @type
    
    highlight default link Test Keyword
    

Update


Following Ingo's answer the proposed solution indeed works. However what is interesting to me is why this one doesn't?

syntax match cfg_Comment '#.*$' contains=cfg_DocTag
syntax match cfg_DocTag  '#\s*\zs[\\@]\l\+' contained

syntax match cfg_DocTag_type   '@type' transparent containedin=cfg_DocTag nextgroup=cfg_DocField_type skipwhite
syntax match cfg_DocField_type '\a\+' contained

highlight default link cfg_Comment       Comment
highlight default link cfg_DocTag        SpecialComment
highlight default link cfg_DocField_type Type

This one would be perfect if only it worked. It frees us from duplication of the comment match, and does the natural inheritance. Omitting @ before type does not change anything by the way, i.e. the inheriting effect stays intact. But why cfg_DocField_type is not highlighted? Any ideas?

Это было полезно?

Решение

You're quite close already. Your containment of cfg_DocTag_type in cfg_DocTag doesn't work because they would both match at the same position. Leaving off the leading @ from the former would fix it, but the nextgroup=cfg_DocField_type still wouldn't match, because apparently the end of the match for cfg_DocTag (after the tag) makes Vim not apply the nextgroup.

What I've done is putting cfg_DocTag_type on the same level as cfg_DocTag, i.e. not contained in the latter. There's only the duplication of the pre-match #\s*\zs as a downside.

syntax match cfg_Comment '#.*$' contains=cfg_DocTag,cfg_DocTag_type
syntax match cfg_DocTag  '#\s*\zs[\\@]\l\+' contained

syntax match cfg_DocTag_type   '#\s*\zs@type' nextgroup=cfg_DocField_type skipwhite
syntax match cfg_DocField_type '\a\+' contained

highlight default link cfg_Comment       Comment
highlight default link cfg_DocTag        SpecialComment
highlight default link cfg_DocTag_type   cfg_DocTag
highlight default link cfg_DocField_type Type

Re 1.: It is not contained; only if you leave off the @. Then, adding transparent would get you the inheriting effect.

Re "finally": I suspect that @ is not part of 'iskeyword' (it's not by default), but it has to be for :syn keyword.

Protip: Syntax script development is easier when you install the SyntaxAttr.vim - Show syntax highlighting attributes of character under cursor plugin.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top