Определите область синтаксиса, которая зависит от уровня отступа


Я пытаюсь создать более легкий синтаксический файл для reStructuredText в Vim. Во-первых, литеральные блоки начинаются, когда "::" встречается в конце строки:

I'll show you some code::

    if foo = bar then
        do_something()
    end

Literal blocks end when indentation level is lowered.

Но литеральные блоки могут быть внутри других структур, которые имеют отступы, но не являются литеральными:

.. important::


    Some code for you inside this ".. important" directive::

        Code comes here

    Back to normal text, but it is indented with respect to ".. important".

Итак, проблема заключается в следующем: как сделать область, которая обнаруживает отступ? Я сделал это со следующим правилом:

syn region rstLiteralBlock  start=/^%(..)@!z(s*).*::$/ms=e-1 skip=/^$/ end=/^z1S/me=e-1

Он работает довольно хорошо, но есть проблема: любое совпадение или область, которые появляются в строке, которая должна быть согласованным с помощью "start" берет на себя правила синтаксиса. Пример:

Foo `this is a link and should be colored`_.  Code comes here::
Это не заставит мое правило работать, потому что есть правило" ссылка", которое берет на себя ситуацию. Это потому, что параметры ms и me совпадают, но я не могу их снять, потому что это просто раскрасит всю линию.

В этом есть какая-нибудь помощь?

Спасибо!

1 3

1 ответ:

Сопоставляя текст перед :: в качестве начала области, вы действительно препятствуете применению других синтаксических правил. Я бы решил это с помощью положительного взгляда ; то есть только утверждаю правила для текста перед ::, не включая его в матч. При этом вам даже не нужно ms=e-1, так как единственное, что сопоставляется для начала области, - это само :::

syn region rstLiteralBlock  start=/\%(^\%(\.\.\)\@!\z(\s*\).*\)\@<=::$/ skip=/^$/ end=/^\z1\S/me=e-1

Отступ все равно будет захвачен \z(...\).