Search code examples
vimsyntax-highlightingvim-syntax-highlighting

Sub-match syntax highlighting in Vim


First, I'll show the specific problem I'm having, but I think the problem can be generalized.

I'm working with a language that has explicit parenthesis syntax (like Lisp), but has keywords that are only reserved against the left paren. Example:

(key key)

the former is a reserved word, but the latter is a reference to the variable named "key"

Unfortunately, I find highlighting the left paren annoying, so I end up using

syn keyword classification key

instead of

syn keyword classification (key

but the former triggers on the variable uses as well.

I'd take a hack to get around my problem, but I'd be more interested in a general method to highlight just a subset of a given match.


Solution

  • Using syn keyword alone for this situation doesn't work right because you want your highlighting to be more aware of the surrounding syntax. A combination of syn region, syn match, and syn keyword works well.

    hi link lispFuncs Function
    hi link lispFunc Identifier
    hi link sExpr Statement
    
    syn keyword lispFuncs key foo bar contained containedin=lispFunc
    syn match lispFunc "(\@<=\w\+" contained containedin=sExpr contains=lispFuncs
    syn region sExpr matchgroup=Special start="(" end=")" contains=sExpr,lispFuncs
    

    The above will only highlight key, foo, and bar using the Function highlight group, only if they're also matched by lispFunc.

    If there are any words other than key, foo, and bar which come after a (, they will be highlighted using the Identifier highlight group. This allows you to distinguish between standard function names and user-created ones.

    The ( and ) will be highlighted using the Special highlight group, and anything inside the () past the first word will be highlighted using the Statement highlight group.