Les régions de syntaxe vim peuvent-elles être mises en contact / se chevauchent?

13

Il y a quelque temps, j'avais décidé d'en savoir plus sur le fonctionnement des fichiers de syntaxe de vim, en créant les miens. Mon objectif était de créer un fichier de syntaxe simple qui diviserait le fichier en 3 parties en fonction des délimiteurs, et inclurait des fichiers de syntaxe préexistants pour deux de ces trois parties.

Voici un exemple de fichier:

Some text, unstyled

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

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

Le but était de ne s'appliquer git.vimqu'au logarithme et diff.vimau diff, à l'exclusion des deux en-têtes. 1 Voici à quoi ressemblait mon fichier de syntaxe:

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"

Notez que endla première région est la même que startla deuxième région. Cela ne fonctionne pas; la deuxième région n'est apparemment pas détectée et la coloration syntaxique n'est pas appliquée.

Je peux le faire fonctionner en desserrant l'expression régulière en end=/^===/et start=/=== Diff/pour que les régions ne se touchent pas, mais n'aiment pas particulièrement cela - il est moins évident que l'une est censée commencer là où l'autre se termine.

Existe-t-il un moyen d'autoriser deux définitions de régions à toucher les mêmes caractères (et / ou à rendre les bords correspondants exclusifs au lieu d'inclure) ou suis-je coincé avec l'expression régulière plus lâche?

1 (Oui, je sais, git.viminclut diff.vim, mais c'était un exercice d'apprentissage)

Izkata
la source
Je pense que cela devrait être possible soit en utilisant un décalage "Region End" pour rendre les bords exclusifs (voir :h :syn-pattern-offset), soit en modifiant la région GitLog pour s'étendre jusqu'à la fin du fichier, et la région Diff pour être entièrement à l'intérieur de la région GitLog . Je n'ai pas réussi à faire fonctionner l'une ou l'autre de ces méthodes.
Rich
Le tester a été rendu un peu plus difficile par le fait que - comme vous le constatez - git.vim met déjà en évidence la sortie diff. Ce pourrait être une idée de modifier votre exemple en conséquence!
Rich

Réponses:

4

Vous pouvez indiquer à Vim regex engine où commencer le prochain match.

Jusqu'à présent, je sais qu'il y a 2 façons:

  1. Utilisez \zepour définir la fin d'une correspondance:

    syntax region GitLog
        \ start=/^===* Log/
        \ end=/\ze^===* Diff/
        \ contains=@gitlog
    
  2. Utilisez l'anticipation positive \@=, qui est appelée correspondance de largeur nulle dans Vim:

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

Ainsi , la fin de match « pointeur » sorte de rembobiner au début de la ^===* Diffligne, de sorte que region Diffl » startcommencera son correspondant à ^===* Diffnouveau sur la ligne.

cychoi
la source