最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

syntax - Unexpected vim region match - Stack Overflow

programmeradmin2浏览0评论

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?

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?

Share Improve this question edited Mar 15 at 4:58 romainl 197k21 gold badges297 silver badges334 bronze badges asked Mar 15 at 1:25 Laser128erLaser128er 513 bronze badges 2
  • 1 "its regex engine, which seems to be very differnt from others" - you might want to read :help perl-patterns for a comparison of Vim's and Perl's regexps. – Friedrich Commented Mar 17 at 20:59
  • 1 Thanks for the tip. I've been looking at the Vim help for patterns but did not know there's an explicit comparison to perl. – Laser128er Commented Mar 19 at 19:08
Add a comment  | 

1 Answer 1

Reset to default 2

Since SourceFilename contains a $, you need to either:

  • add keepend to SourceDirective,
  • or add 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:

发布评论

评论列表(0)

  1. 暂无评论