I try to extend the cmake syntax highlighting by our in-house cmake functions. For this I drafted a file to be saved in ~/.vim/after/syntax/cmake.vim, such that one extends the default cmake syntax highlighting, as suggested in this stackoverflow post.

What I am struggeling with is that we use INCLUDE_DIRS as keyword, whereas standard cmake uses INCLUDE_DIRECTORIES, and I want the syntax highlighting to point out to a developer that they used the wrong convention for the function at hand. (Yes, I could also try to push towards fixing our inhouse style, but the general problem of what-are-possible-keywords-here would remain).

The standard cmake syntax file I'm testing against is here

So, I want

add_library( # this is a standard cmake function
          INCLUDE_DIRECTORIES somepath # highlight the first word here, it's spelled right
          INCLUDE_DIRS  otherpath      # don't highlight this, it's spelled wrong

fancy_wrapper( # this is from the inhouse modules
           INCLUDE_DIRECTORIES   somepath   # don't highlight
           INCLUDE_DIRS otherpath)          # highlight

My understanding was that I can use in my extension the following:

if exists("b:current_syntax")
  if b:current_syntax != "cmake"
let s:keepcpo= &cpo
set cpo&vim

syn region OurArgs start="(" end=")" contains=OurArguments

syn case match

syn keyword OurArguments contained
        \ INCLUDE_DIRS

syn case ignore

syn keyword cmakeOurs
            \ fancy_wrapper
            \ nextgroup=OurArgs

hi def link cmakeOurs Function
hi def link OurArguments ModeMsg

let &cpo = s:keepcpo
unlet s:keepcpo

my understanding is that fancy_wrapper now gets recognised as an inhouse function and the next group will be a OurArgs region instead of the normal cmakeArguments. And for the normal add_library the official cmake style should kick in (copy and pasting their code):

syn keyword cmakeCommand
        \ add_library
        \ nextgroup=cmakeArguments

Such that the parentheses thereafter are a cmakeArguments region and INCLUDE_DIRECTORIES gets recognized therein.

However, what I observe is that INCLUDE_DIRECTORIES never gets highlighted and INCLUDE_DIRS always gets highlighted. Using the debugging hints here) I see that the region after add_library is recognized as OurArgs (last definition taking precedence, afaiu. instead of - what i had hoped - the nextgroup deciding what happens).

So my question is:

  • How can I highlight different sets of keywords within parentheses regions, that all look the same in start= and end=? Is that not what nextgroup is good for?
  • Ideally (depending how the answer on the first turns out), can I still do that without modifying kitware's cmake.vim file?

1 Answer 1


Superficially, all that is missing is the contained attribute for the OurArgs definition. Without it, that may match anywhere, not just after cmakeOurs via the nextgroup=. Very often, when you explicitly ask for parsing to continue with nextgroup, you want that syntax to be contained, to avoid accidental matches elsewhere.

syn region OurArgs start="(" end=")" contains=OurArguments contained

Unfortunately, it's not that easy with the cmake syntax. Looking at the "competing" cmakeArguments region, it has this definition:

syn region cmakeArguments start="(" end=")"
\ contains=ALLBUT,cmakeCommand,cmakeCommandConditional,cmakeCommandRepeat,
\ cmakeCommandDeprecated,cmakeArguments,cmakeTodo

The problem is the ALLBUT, which indirectly again introduces OurArgs and OurArguments into the regular cmake block, which causes the matching that you don't want there.

Now, if syntax/cmake.vim were written with extension in mind, it would include an (empty) :help :syn-cluster in that contains clause, allowing you to add your groups to the exclusion list. As it does not, you need to override the original definition, like this:

syn clear cmakeArguments
syn region cmakeArguments start="(" end=")"
\ contains=ALLBUT,cmakeCommand,cmakeCommandConditional,cmakeCommandRepeat,
\ cmakeCommandDeprecated,cmakeArguments,cmakeTodo,OurArgs,OurArguments

With that, the coloring will only apply to the fancy_wrapper block.

PS: The OurArgs and OurArguments are not very expressive (hopefully just because you've obfuscated them for us), and should also start with the cmake prefix like the original syntax items.

  • I didn't so much have obfuscation in mind but rather having a minimum working example instead of a huge list of equally meaningless functions and arguments, in the large file I am using more expressive names (though naming things is hard.)
    – pseyfert
    Nov 6, 2018 at 21:23
  • the pointer to :syn-cluster turns out very helpful!
    – pseyfert
    Nov 6, 2018 at 21:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.