I'm relatively new to vim's syntax highlighting and its regex engine, which seems to be very differnt from others I've used (mainly perl, pcre, posix). This vim syntax highlighting problem has been frustrating me all day.
I have the following syntax defined:
syntax region SourceDirective start=/^\s*SOURCE\s/ end=/$/ oneline contains=SourceKeyword,SourceFilename
syntax match SourceKeyword /^\s*SOURCE\s/ contained
syntax match SourceFilename /\S\+\s*$/ contained
highlight SourceKeyword ctermfg=darkyellow guifg=darkyellow cterm=bold,italic gui=bold,italic
highlight SourceFilename ctermfg=lightyellow guifg=lightyellow cterm=bold,italic gui=bold,italic
highlight SourceDirective cterm=inverse gui=inverse
I don't understand why this sample:
SOURCE alpha.txt
SOURCE beta.txt
# See ID-1234
#SOURCE delta/delta.txt
SOURCE gamma.txt
produces this:
I can't figure out why the comment lines are in a SourceDirective region (as shown by the inverse text, which I added just for debugging). They don't match the region's start=
pattern. Those line should be completely ignored by those syntax rules.
What I am missing?
Since SourceFilename
contains a $
, you need to either:
keepend
to SourceDirective
,excludenl
to SourceFilename
.You would do the former if the region can contain lots of matches because it is just one argument to add to one group and you don't have to think about each match individually.
You would do the latter if your match can be included in several regions because it makes it self-contained.
Or you can be super explicit and do both. "Ceinture-bretelles", as we say around here.
From :help :syn-excludenl
:
When a pattern for a match or end pattern of a region includes a '$'
to match the end-of-line, it will make a region item that it is
contained in continue on the next line. For example, a match with
"\\$" (backslash at the end of the line) can make a region continue
that would normally stop at the end of the line. This is the default
behavior. If this is not wanted, there are two ways to avoid it:
1. Use "keepend" for the containing item. This will keep all
contained matches from extending the match or region. It can be
used when all contained items must not extend the containing item.
2. Use "excludenl" in the contained item. This will keep that match
from extending the containing match or region. It can be used if
only some contained items must not extend the containing item.
"excludenl" must be given before the pattern it applies to.
Here I have used both at the same time for demonstration, but only one is necessary: