Можно ли сделать так, чтобы области синтаксиса vim касались / перекрывались?

13

Некоторое время назад я решил узнать больше о том, как работают файлы синтаксиса vim, создав свои собственные. Моя цель состояла в том, чтобы создать простой файл синтаксиса, который бы разделял файл на 3 части на основе разделителей и включал ранее существующие файлы синтаксиса для двух из этих трех частей.

Это пример файла:

Some text, unstyled

==================== Log
(Output of git log)

==================== Diff
(Output of diff)

Цель состояла в том, чтобы применить git.vimтолько к журналу и diff.vimтолько к разнице, исключая два заголовка. 1 Вот как выглядит мой синтаксический файл:

if exists("b:current_syntax")
    finish
endif

syntax include @gitlog $VIMRUNTIME/syntax/git.vim
syntax region GitLog
    \ start=/^===* Log/
    \ end=/^===* Diff/
    \ contains=@gitlog

syntax include @gitdiff $VIMRUNTIME/syntax/diff.vim
syntax region Diff
    \ start=/^===* Diff/
    \ end=/\n\n/
    \ contains=@gitdiff

let b:current_syntax = "logdiff"

Обратите внимание, что endв первом регионе так же, как startво втором регионе. Это не работает; вторая область, по-видимому, не обнаружена и подсветка синтаксиса не применяется.

Я могу заставить его работать, ослабив регулярное выражение end=/^===/и start=/=== Diff/, чтобы регионы не соприкасались, но особенно не нравились - менее очевидно, что один должен начинаться там, где заканчивается другой.

Есть ли способ разрешить двум определениям областей касаться одних и тех же символов (и / или сделать соответствующие края исключительными, а не включающими), или я застрял с более слабым регулярным выражением?

1 (Да, я знаю, в том git.vimчисле diff.vim, но это было учебное упражнение)

Izkata
источник
Я думаю, что это должно быть возможно либо с помощью смещения «Конец области», чтобы сделать края исключительными (см. :h :syn-pattern-offset), Либо путем изменения области GitLog, чтобы она продолжалась до конца файла, и области Diff, чтобы быть полностью внутри области GitLog , Я не мог заставить ни один из этих методов работать, все же.
Богатый
Тестирование было несколько сложнее из-за того, что - как вы заметили - git.vim уже выделяет результаты diff. Может быть, идея изменить ваш пример соответственно!
Богатый

Ответы:

4

Вы можете указать движку Vim regex, с чего начать следующий матч.

Пока я знаю, что есть 2 способа:

  1. Используйте \zeдля установки конца матча:

    syntax region GitLog
        \ start=/^===* Log/
        \ end=/\ze^===* Diff/
        \ contains=@gitlog
    
  2. Используйте положительный взгляд, \@=который называется сопоставлением нулевой ширины в Vim:

    syntax region GitLog
        \ start=/^===* Log/
        \ end=/\(^===* Diff\)\@=/
        \ contains=@gitlog
    

Таким образом, с истекшим матча «указатель» вид перематывается на начало ^===* Diffстроки, например , что region Diff«s startначнет согласование на ^===* Diffлинии снова.

cychoi
источник