3

I have a custom config that involves the following syntax:

  • key=value
  • $(var) represents a variable

The $(var) part can appear in both key and value, i.e. message="hello $(FirsName) $(LastName)". The value part must be surrounded by double quote " if it contains space characters.

I want to match key, value and $(var) and highlight them separately in vim.

Here is what in my vim syntax file:

syn match configValue "\(\S\+=\)\@<=\"[^\"]*\"\|\(\S\+=\)\@<=\S\+"
syn match configKey "^\s*[a-zA-Z0-9_.]\+\(\s*=\)\@="
syn match configVar "\$(.*)"

The code successfully matches configValue and configKey, but not configVar if it is within key=value. This is ruled by the syntax match priority (h:syn-priority):

  1. When multiple Match or Region items start in the same position, the item defined last has priority.
  2. A Keyword has priority over Match and Region items.
  3. An item that starts in an earlier position has priority over items that start in later positions.

Rule 3 gives the other two matches higher priority than that of configVar.

My problem is that, how to match the three patterns separately, with configVar having the highest priority?

1 Answer 1

3

To have configVar match inside configValue, you have to contain it; this is done via the contained (leave this off if the var can also match anywhere, not just inside key=value) and contains=... attributes:

syn match configValue "\(\S\+=\)\@<=\"[^\"]*\"\|\(\S\+=\)\@<=\S\+" contains=configVar
syn match configVar "\$([^)]*)" contained

Note that I've changed the pattern for configVar to avoid matching $(foo) and $(bar) as one element.


You said that configVar can also appear in configKey, but for that, the range of allowed characters needs to include $(), too. Then, the containment works just as well:

syn match configKey "^\s*[a-zA-Z0-9_.$()]\+\(\s*=\)\@=" contains=configVar
Sign up to request clarification or add additional context in comments.

2 Comments

It works. Didn't know that match can also have contains. Cool.
It can do a lot of cool things like that. I recommend going through :help syntax (:help :syn-arguments would also make a decent starting point) for more on match etc. :)

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.