Чи можна зробити регістри синтаксису 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, але це була навчальна вправа)


Я думаю, що це повинно бути можливим або за допомогою зміщення "регіону кінця", щоб зробити краї виключними (див. :h :syn-pattern-offset), Або змінивши область GitLog, щоб поширитись до кінця файлу, а область Diff бути повністю всередині області GitLog . Хоча я не міг змусити жоден із цих методів працювати.
Багатий

Тестування було дещо складніше тим, що - як ви зазначаєте - git.vim вже підкреслює різний вихід. Може бути ідея змінити ваш приклад відповідно!
Багатий

Відповіді:


4

Ви можете сказати двигуну Vim regex, з чого розпочати наступний матч.

Поки я знаю, що існує два способи:

  1. Використовуйте \zeдля встановлення кінця матчу:

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

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

Таким чином, з вичерпаним матчу «покажчик» вид перемотано на початок ^===* Diffрядка, наприклад , що region Diff«s startпочне узгодження на ^===* Diffлінії знову.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.