2

I am trying to improve Vim's syntax highlighting for YAML files. YAML supports long string literals that begin with either a ">" or "|", like this:

keyA: > A string literal that spans multiple lines keyB: keyC: | Another string literal That spans multiple lines keyD: somevalue 

The scope of the string is indentation-dependent -- everything is included in it until a line with a smaller indent begins.

I have defined a syntax region like this:

syn region yamlLongStringLiteral start="\v\>|\|" end=/^\ze\S/ contains=NONE 

(Note: I've excluded contained from the definition above because it 's irrelevant to this question). This works for string literals stored in top-level keys (e.g. keyA above) but fails for literals stored in nested keys (e.g. keyC above). What I need to do is detect the indentation of the first line of the long literal and terminate the region on the first line with a lesser indent level. This would seem to require accessing captured groups from the start pattern in the end pattern. Is this possible, or is there some other way to accomplish my goal?

1
  • 1
    you can use the special item \z( to mark groups that are available at end section of the pattern. Check $VIMRUNTIME/syntax for the pattern \\z( Read also the help at :h /\z/, it includes an example Commented Mar 1, 2018 at 7:02

1 Answer 1

2

Thanks to Christian's comment above, I came up with the following:

syn region yamlLongStringLiteral \ start="\(>\||\) *\n^\z( \+\)" \ end="^\(\z1\|$\)\@!" \ contains=NONE 

The \z in the start pattern stores a group holding the leading indent, which is then referenced in the end pattern with \z1. \@! does negative lookahead, so ^\(\z1|$\)\@! means: "any non-empty line that does not start with the saved indent group".

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.