I have a custom config that involves the following syntax:
key=value
$(var)
represents a variableThe $(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
):
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?
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