Le regioni di sintassi di VIM possono essere toccate / sovrapposte?


13

Quindi qualche tempo fa avevo deciso di saperne di più su come funzionano i file di sintassi di Vim, creando il mio. Il mio obiettivo era quello di creare un semplice file di sintassi che dividesse il file in 3 parti basate su delimitatori e includesse file di sintassi preesistenti per due di queste tre parti.

Questo è un file di esempio:

Some text, unstyled

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

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

L'obiettivo era applicare git.vimsolo al log e diff.vimsolo al diff, escludendo le due intestazioni. 1 Ecco come si presentava il mio file di sintassi:

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"

Nota come endnella prima regione è uguale startalla seconda regione. Questo non funziona; la seconda regione apparentemente non viene rilevata e l'evidenziazione della sintassi non viene applicata.

Posso farlo funzionare allentando la regex end=/^===/e start=/=== Diff/, in modo che le regioni non si tocchino, ma non piacciano particolarmente - è meno ovvio che uno dovrebbe iniziare dove finisce l'altro.

C'è un modo per consentire a due definizioni di regione di toccare gli stessi caratteri (e / o rendere esclusivi i bordi corrispondenti anziché inclusivi) o sono bloccato con la regex più libera?

1 (Sì, lo so git.viminclude diff.vim, ma questo è stato un esercizio di apprendimento)


Penso che ciò dovrebbe essere possibile utilizzando un offset "Fine regione" per rendere esclusivi i bordi (vedi :h :syn-pattern-offset) o modificando la regione GitLog per estenderla fino alla fine del file e la regione Diff in modo che sia interamente all'interno della regione GitLog . Tuttavia, non sono riuscito a far funzionare nessuno di questi due metodi.
Ricco

Il test è stato reso un po 'più difficile dal fatto che - come notate - git.vim evidenzia già l'output diff. Potrebbe essere un'idea per modificare di conseguenza il tuo esempio!
Ricco

Risposte:


4

Puoi dire al motore regex di Vim dove iniziare la prossima partita.

Finora so che ci sono 2 modi:

  1. Usa \zeper impostare la fine di una partita:

    syntax region GitLog
        \ start=/^===* Log/
        \ end=/\ze^===* Diff/
        \ contains=@gitlog
    
  2. Usa lookahead positivo \@=, che in Vim è chiamato corrispondenza a larghezza zero:

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

Così la fine partita "puntatore" tipo di si ritorna all'inizio della ^===* Difflinea, in modo che region Diff's startinizierà la sua corrispondenza in ^===* Difflinea di nuovo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.