Czy regiony składniowe vima mogą się dotykać / nakładać?

13

Jakiś czas temu postanowiłem dowiedzieć się więcej o tym, jak działają pliki składniowe vima, tworząc własne. Moim celem było stworzenie prostego pliku składniowego, który podzieliłby ten plik na 3 części w oparciu o ograniczniki i zawierał istniejące pliki składniowe dla dwóch z tych trzech części.

To jest przykładowy plik:

Some text, unstyled

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

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

Celem było zastosowanie git.vimtylko do dziennika i diff.vimtylko do różnicy, z wyłączeniem dwóch nagłówków. 1 Tak wyglądał mój plik składni:

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"

Zwróć uwagę, że endw pierwszym regionie jest taki sam, jak startw drugim regionie. To nie działa; drugi region najwyraźniej nie został wykryty i nie zastosowano podświetlania składni.

Mogę sprawić, by działało, poluzowując wyrażenie regularne do end=/^===/i start=/=== Diff/, aby regiony się nie dotykały, ale nie lubiły tego szczególnie - mniej oczywiste jest, że jeden powinien zacząć się tam, gdzie kończy się drugi.

Czy istnieje sposób, aby pozwolić dwóm definicjom regionu dotknąć tych samych znaków (i / lub uczynić pasujące krawędzie wyłącznymi zamiast włączających), czy też utknąłem z luźniejszym wyrażeniem regularnym?

1 (Tak, wiem, git.vimobejmuje diff.vim, ale to było ćwiczenie edukacyjne)

Izkata
źródło
Myślę, że powinno to być możliwe albo poprzez użycie przesunięcia „Koniec regionu”, aby uczynić krawędzie wyłącznymi (patrz :h :syn-pattern-offset), lub poprzez zmianę regionu GitLog, aby rozciągał się na koniec pliku, i regionu Diff, aby był całkowicie wewnątrz regionu GitLog . Nie mogłem jednak uruchomić żadnej z tych metod.
Bogaty
Testowanie zostało nieco utrudnione przez fakt, że - jak zauważasz - git.vim już wyróżnia wyjście różnicowe. Być może warto odpowiednio zmienić swój przykład!
Bogaty

Odpowiedzi:

4

Możesz powiedzieć silnikowi Vim regex, od którego zacząć następny mecz.

Jak dotąd wiem, że istnieją 2 sposoby:

  1. Użyj, \zeaby ustawić koniec meczu:

    syntax region GitLog
        \ start=/^===* Log/
        \ end=/\ze^===* Diff/
        \ contains=@gitlog
    
  2. Użyj pozytywnego lookahead, \@=który w Vimie nazywa się dopasowywaniem zerowej szerokości:

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

Więc end-of-match „wskaźnik” rodzaj przewinięty do początku ^===* Difflinii, tak że region Diffnic nie startzacznie jej dopasowanie w ^===* Diffznowu linii.

kieroi
źródło