3

I have a line-delimited language syntax containing a command that allows multi-line strings, similar to how Python handles '''...''' and """...""" constructs.

I want to define a region within that is delimited by the triple quotes, but which does not itself include the triple quotes. The gist of the problem: define the file bar.txt containing the following:

foo [other stuff] bar '''
   more stuff
'''

The triple quotes end the line in both cases. I want the entire thing to be one region, and within that region, the triple-quoted text should be another region. The following syntax highlighting file (which I called "test.vim") almost does what I want it to do:

syntax region specialCommand start='\<foo\s' end='$' skip='&$'
\   keepend contains=tripleQuoted
syntax region tripleQuoted start=+\<bar\s\+\z("""\|'''\)+ms=e+1
\   end='\ze\z1' contained extend
hi def specialCommand ctermbg=gray guibg=lavender
hi def tripleQuoted ctermbg=lightgray guibg=pink

If you then issue ":source test.vim" (or otherwise set the syntax highlighting to include the lines above), I get only the first line contained within specialCommand and nothing within tripleQuoted. If I put a space after the first ''', however, I get the first line highlighted as specialCommand (except the final space), the entire second line highlighted and the space after the first triple quote as tripleQuoted, and the last line highlighted as part of specialCommand again.

The desired behavior is to have everything within the quotes highlighted as tripleQuoted, and everything else highlighted as specialcommand.

Put another way; it looks like this:

foo [other stuff] bar '''
    more stuff
''' still more stuff

and it should look like

foo [other stuff] bar '''
    more stuff
''' still more stuff

where boldface denotes the specialCommand region and italics denotes the tripleQuoted region. Adding a space after the first ''' makes it work as expected.

1 Answer 1

1

Matches are bound to lines, so ms=e+1 won't work as it points after EOL.

An easy fix here is :h :syn-matchgroup. So this will do

syntax region tripleQuoted matchgroup=specialCommand
    \ start=+\<bar\s\+\z("""\|'''\)+
    \ end='\z1' contained extend
2
  • Ahhhh, you have to set matchgroup to the parent region. I had read that section of the help file, but it didn't click until I read your post. Thanks!
    – karlh
    Jun 30, 2022 at 14:09
  • To anyone else reading: it is also significant that "matchgroup=specialCommand" comes before the start and end match pattern specifications. If you have it at the end (as I did prior to posting), it won't work as expected.
    – karlh
    Jun 30, 2022 at 21:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.