Подсветка синтаксиса Vim для совпадения в несколько строк - PullRequest
5 голосов
/ 23 ноября 2011

Я реализую в vim файл синтаксиса, чтобы выделить иерархию, подобную этой

| text at level 1
| | text at level 2
| | text at level 2
| | | text at level 3
| text at level 1

Например, я использую

syn match myMatch +^\(| \)\++

для выделения индикаторов уровня. Тем не менее, я также хотел бы выделить неправильные шаблоны, подобные этим

| text at level 1
| | | text at level 3

, которые увеличивают уровни более чем на один. Я написал следующее совпадение синтаксиса

syn match myWrongMatch +^\(\(| \)*\)\(\n\|[^|].*\n\)\1\(| \)\{2,}+

Возможно, это не оптимально, но это делает работу. Проблема в том, что vim проверяет совпадения в строке, которая редактируется, поэтому, если я исправлю ошибку, удалив уровень во второй строке, он перестанет выделять вторую строку, но по-прежнему будет выделять первую, пока я не отредактирую (например, удалить и переписать символ).

Эта проблема в том, что я могу сопоставить только строку, используя информацию о следующей строке, но не наоборот. Поскольку это не представляется возможным при сопоставлении с регулярным выражением, я хотел бы знать, возможно ли попросить vim проверить совпадения как в текущей отредактированной строке, так и в предыдущей (или в более широком контексте) ? Другое решение может заключаться в реализации этого в регионе, который проверяет контекст, но я до сих пор не добился этого.

РЕДАКТИРОВАТЬ : Ответ на самом деле находится в справке vim по адресу: syn-sync-linebreaks (спасибо Герберту Ситцу за указание на правильный раздел).

При использовании шаблона, который соответствует нескольким строкам, изменение в одной строке может заставить образец больше не совпадать в предыдущей строке. Это значит, должен начать выше, где изменения были сделаны. Сколько строк можно указать с помощью аргумент "разрывы строк". Например, когда шаблон может содержать одну строку перерыв используйте это:

:syntax sync linebreaks=1

В результате перерисовка всегда начинается хотя бы на одну строку раньше, чем изменение было сделано. Значение по умолчанию для «разрывов строк» ​​равно нулю. Обычно значение для "minlines" больше, чем "разрывы строк".

Это отлично работает.

1 Ответ

2 голосов
/ 23 ноября 2011

Вы можете попробовать автоматизировать синтаксическую операцию синхронизации.Например, попробуйте поместить это в autocmd InsertEnter, который будет синхронизировать синтаксис всякий раз, когда вы выходите из режима вставки:

au InsertLeave * syntax synch minlines=50

Не идеальное решение.Может быть, добавление большего количества autocmds поможет.Частично это зависит от того, как будут выглядеть ваши документы, насколько большими они будут, как вы будете редактировать.

Для получения справки читайте больше о синхронизации синтаксиса: :h syn-sync Это не типичное использование синхронизации, поскольку, как я понимаю, основной целью является автоматический поиск отредактированных строк, когда они находятся в синтаксических областях.Вы не используете регионы, поэтому вам нужно запустить синхронизацию с помощью autocmd.Возможно, вы могли бы определить регион только для того, чтобы убедиться, что синтаксическая синхронизация переоценивает синтаксис по группе строк - без необходимости использования autocmd - даже если этот регион не будет использоваться для выделения.

...