I’m playing with vim-ruby indent, and there are some pretty complex regexes there:
" Regex used for words that, at the start of a line, add a level of indent.
let s:ruby_indent_keywords = '^\s*\zs\<\%(module\|class\|def\|if\|for' .
\ '\|while\|until\|else\|elsif\|case\|when\|unless\|begin\|ensure' .
\ '\|rescue\):\@!\>' .
\ '\|\%([=,*/%+-]\|<<\|>>\|:\s\)\s*\zs' .
\ '\<\%(if\|for\|while\|until\|case\|unless\|begin\):\@!\>'
With the help of vim documentation I deciphered it to mean:
start-of-line <any number of spaces> <start matching> <beginning of a word> /atom
<one of provided keywords> <colon character> <nothing> <end of word> ...
I have some doubts:
- Is it really matching ‘:’? Doesn’t seem to work like that, but I don’t see anything about colon being some special character in regexes.
- why is there
\zs(start of the match) and no\ze(end of the match)? - what does \%() do? Is it just some form of grouping?
:\@!says to match only if there is not a colon, if I read it correctly. I am not familiar with the ruby syntax that this is matching against so this may not be quite correct. See:help /\@!and the surrounding topics for more info on lookarounds.You can have a
\zswith no\ze, it just means that the end of the match is at the end of the regex. The opposite is also true.\%(\)just creates a grouping just as\(\)would except that the group is not available as a backreference (like would be used in a:substitutecommand).