Pregunta:
Así que hace un tiempo decidí aprender más sobre cómo funcionan los archivos de sintaxis de vim, creando los míos. Mi objetivo era crear un archivo de sintaxis simple que dividiera el archivo en 3 partes según los delimitadores e incluyera archivos de sintaxis preexistentes para dos de esas tres partes.
Este es un archivo de ejemplo:
Some text, unstyled
==================== Log
(Output of git log)
==================== Diff
(Output of diff)
El objetivo era aplicar git.vim
solo al registro y diff.vim
solo al diff, excluyendo los dos encabezados. 1 Así es como terminó mi archivo de sintaxis:
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"
Tenga en cuenta que el end
de la primera región es lo mismo que el start
de la segunda región. Esto no funciona; la segunda región aparentemente no se detecta y no se aplica el resaltado de sintaxis.
Puedo hacer que funcione aflojando la expresión regular para end=/^===/
y start=/=== Diff/
, para que las regiones no se toquen, pero no me guste particularmente, es menos obvio que uno se supone que comienza donde termina el otro.
¿Hay alguna manera de permitir que dos definiciones de región toquen los mismos caracteres (y / o hacer que los bordes coincidentes sean exclusivos en lugar de inclusivos) o estoy atrapado con la expresión regular más suelta?
1 (Sí, sé que git.vim
incluye diff.vim
, pero este fue un ejercicio de aprendizaje)
Respuesta:
Puede decirle al motor de expresiones regulares Vim dónde comenzar el próximo partido.
Hasta ahora sé que hay 2 formas:
-
Use
\ze
para establecer el final de una partida:syntax region GitLog \ start=/^===* Log/ \ end=/\ze^===* Diff/ \ contains=@gitlog
-
Utilice una búsqueda anticipada positiva,
\@=
, que se denomina coincidencia de ancho cero en Vim:syntax region GitLog \ start=/^===* Log/ \ end=/\(^===* Diff\)\@=/ \ contains=@gitlog
Así que el "puntero" de fin de coincidencia se rebobina al principio de ^===* Diff
line, de modo que el inicio de ^===* Diff
de la region Diff
start
a coincidir en ^===* Diff
line nuevamente.