Können vim-Syntaxbereiche so eingestellt werden, dass sie sich berühren / überlappen?

13

Vor einiger Zeit hatte ich mich entschlossen, mehr über die Funktionsweise von vims Syntaxdateien zu erfahren, indem ich meine eigenen erstellte. Mein Ziel war es, eine einfache Syntaxdatei zu erstellen, die die Datei basierend auf Trennzeichen in drei Teile aufteilt und bereits vorhandene Syntaxdateien für zwei dieser drei Teile enthält.

Dies ist eine Beispieldatei:

Some text, unstyled

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

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

Das Ziel bestand darin git.vim, nur das Protokoll und diff.vimnur den Unterschied zu berücksichtigen, ohne die beiden Header. 1 So sah meine Syntaxdatei aus:

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"

Beachten Sie, dass enddie erste Region startmit der zweiten Region identisch ist. Das funktioniert nicht. Der zweite Bereich wird anscheinend nicht erkannt und die Syntaxhervorhebung wird nicht angewendet.

Ich kann es schaffen, indem ich den regulären Ausdruck auf end=/^===/und löse start=/=== Diff/, damit sich die Regionen nicht berühren, aber nicht besonders mögen - es ist weniger offensichtlich, dass man dort beginnen soll, wo der andere endet.

Gibt es eine Möglichkeit, zuzulassen, dass zwei Regionsdefinitionen die gleichen Zeichen berühren (und / oder die übereinstimmenden Kanten exklusiv statt inklusiv machen), oder bin ich mit dem loseren regulären Ausdruck festgefahren?

1 (Ja, ich weiß, git.vimbeinhaltet diff.vim, aber dies war eine Lernübung)

Izkata
quelle
Ich denke, dies sollte möglich sein, indem entweder ein Versatz " :h :syn-pattern-offsetRegionsende " verwendet wird, um die Kanten exklusiv zu machen (siehe ), oder indem die GitLog-Region so geändert wird, dass sie sich bis zum Ende der Datei erstreckt, und die Diff-Region vollständig innerhalb der GitLog-Region liegt . Ich konnte jedoch keine dieser Methoden zum Laufen bringen.
Rich
Das Testen wurde etwas erschwert, da git.vim - wie Sie bereits bemerkt haben - bereits die diff-Ausgabe hervorhebt. Könnte eine Idee sein, Ihr Beispiel entsprechend zu ändern!
Rich

Antworten:

4

Sie können der Vim Regex-Engine mitteilen, wo sie das nächste Spiel starten soll.

Soweit ich weiß, gibt es zwei Möglichkeiten:

  1. Verwenden Sie \zediese Option , um das Ende eines Matches festzulegen:

    syntax region GitLog
        \ start=/^===* Log/
        \ end=/\ze^===* Diff/
        \ contains=@gitlog
    
  2. Verwenden Sie den positiven Lookahead, \@=der in Vim als Null-Breiten-Matching bezeichnet wird:

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

So ist die End-of-match „Zeiger“ Art von spult an den Anfang der ^===* DiffLinie, so dass region Diff‚s startseine Anpassung an beginnen ^===* DiffLinie wieder.

cychoi
quelle