tags:

views:

45

answers:

2

I'm trying to write some matching rules in a Vim syntax file to highlight indented bullets. My problem is that the syntax highlighting uses a background color, so I would like to match only the bullet character and not the preceding whitespace.

How can I say "match \d., +, -, and * only if preceded by ^\s\{0,1} (but do not match the whitespace)"

With the following matching rules,

syn match notesBullet /^\s*\*/
hi def link notesBullet String 
syn match notesNumber /^\s*\d*\./
hi def link notesNumber String
syn match notesMinus /^\s*\-/
hi def link notesMinus Todo 
syn match notesPlus /^\s*+/
hi def link notesPlus Plus

I get the following result:

Is there some way to say "if preceded by, but not including" in Vim regex?

+1  A: 

Is there some way to say "if preceded by" in Vim regex?

Yep, it's called a "zero-width" match, \@<= (it's known as a "look-behind" in the RE sublanguage of Perl and Python). See here for all details.

Alex Martelli
Excellent, thank you Alex. However, /\(\s*\)\@=\*/ matches every '*' and /^\(\s*\)\@=\*/ or /\(^\s*\)\@=\*/ don't match indented '*'. Any idea why this happens?
msutherl
`\s*` means "zero or more spaces" so I'd _expect_ it to match anything. What about `\s+` (meaning "one or more") instead?
Alex Martelli
Look-behind is `\@<=`, not `\@=` which is look-ahead. Did the parser eat `<`?
ZyX
@ZyX, not the parser's fault but mine -- tx for the spotting, +1!
Alex Martelli
+1  A: 

In addition to the lookarounds mentioned by Alex, Vim patterns also have the concept of "match start" and "match end" which are denoted by \zs and \ze, respectively. Vim will only match when the whole pattern is there, but will exclude everything before \zs and\or after \ze (you don't have to specify both) from the match.

So in your case, you can add \zs after your whitespace pattern and before the bullet/number pattern. For example: /^\s*\zs\d*\./

Jay
Thank Jay, exactly what I needed. I think I could have done it with lookarounds, but I couldn't get it to work.
msutherl