Resaltado Vim Markdown (elementos de lista y conflictos de bloque de código)
Pregunta
Decido aprender más sobre vim y su resaltado de sintaxis. Usando ejemplos para otros, estoy creando mi propio archivo de sintaxis para Markdown. He visto mkd.vim y también tiene este problema. Mi problema es entre los elementos de la lista y el resaltado de bloque de código.
Bloque de código definición :
- la primera línea está en blanco
- la segunda línea comienza con al menos 4 espacios o 1 pestaña
- el bloque termina con una línea en blanco
Ejemplo:
Regular text
this is code, monospaced and left untouched by markdown
another line of code
Regular Text
Sintaxis de My Vim para bloque de código:
syn match mkdCodeBlock /\(\s\{4,}\|\t\{1,}\).*\n/ contained nextgroup=mkdCodeBlock
hi link mkdCodeBlock comment
elemento de la lista de desorden definición :
- la primera línea está en blanco
- la segunda línea comienza con un [- + *] seguido de un espacio
- la lista finaliza con una línea en blanco y luego una línea normal (sin lista)
- entre líneas de pedido se puede agregar cualquier número de líneas en blanco
- una sublista se especifica mediante sangría (4 espacios o 1 pestaña)
- se incluye una línea de texto normal después de un elemento de la lista como continuación de ese elemento de la lista
Ejemplo:
Regular text
- item 1
- sub item 1
- sub item 2
- item 2
this is part of item 2
so is this
- item 3, still in the same list
- sub item 1
- sub item 2
Regular text, list ends above
Sintaxis de My Vim para la definición de elementos de la lista de pedidos (solo resalto [- + *]
):
syn region mkdListItem start=/\s*[-*+]\s\+/ matchgroup=pdcListText end=".*" contained nextgroup=mkdListItem,mkdListSkipNL contains=@Spell skipnl
syn match mkdListSkipNL /\s*\n/ contained nextgroup=mkdListItem,mkdListSkipNL skipnl
hi link mkdListItem operator
No puedo hacer que el resaltado funcione con las dos últimas reglas para la lista y con un bloque de código.
Este es un ejemplo que rompe mi resaltado de sintaxis:
Regular text
- Item 1
- Item 2
part of item 2
- these 2 line should be highlighted as a list item
- but they are highlighted as a code block
Actualmente no puedo entender cómo hacer que el resaltado funcione de la manera que lo quiero también
Se olvidó de agregar un " global " regla de sintaxis utilizada en las dos reglas enumeradas a continuación. Es para asegurarse de que comiencen con una línea en blanco.
syn match mkdBlankLine /^\s*\n/ nextgroup=mkdCodeBlock,mkdListItem transparent
Otra nota: debería haber sido más claro. En mi archivo de sintaxis, las reglas de la Lista aparecen antes de las Reglas de Blockquote
Solución
Solo asegúrese de que la definición de mkdListItem sea posterior a la definición de mkdCodeBlock, así:
syn match mkdCodeBlock /\(\s\{4,}\|\t\{1,}\).*\n/ contained nextgroup=mkdCodeBlock
hi link mkdCodeBlock comment
syn region mkdListItem start=/\s*[-*+]\s\+/ matchgroup=pdcListText end=".*" contained nextgroup=mkdListItem,mkdListSkipNL contains=@Spell skipnl
syn match mkdListSkipNL /\s*\n/ contained nextgroup=mkdListItem,mkdListSkipNL skipnl
hi link mkdListItem operator
syn match mkdBlankLine /^\s*\n/ nextgroup=mkdCodeBlock,mkdListItem transparent
La documentación de Vim dice en : help: syn-define
:
" En caso de que más de un elemento coincida en la misma posición, el que estaba Las últimas victorias definidas. Por lo tanto, puede anular los elementos de sintaxis previamente definidos por usando un elemento que coincide con el mismo texto. Pero una palabra clave siempre va antes de una partido o región. Y una palabra clave con mayúsculas y minúsculas siempre va antes que un palabra clave con ignorar mayúsculas y minúsculas. "
Otros consejos
hcs42 era correcto. Recuerdo haber leído esa sección ahora, pero lo olvidé hasta que hcs24 me lo recordó.
Aquí está mi sintaxis actualizada (algunos otros ajustes) que funciona:
""""""""""""""""""""""""""""""""""""""" " Code Blocks: " Indent with at least 4 space or 1 tab " This rule must appear for mkdListItem, or highlighting gets messed up syn match mkdCodeBlock /\(\s\{4,}\|\t\{1,}\).*\n/ contained nextgroup=mkdCodeBlock """"""""""""""""""""""""""""""""""""""" " Lists: " These first two rules need to be first or the highlighting will be " incorrect " Continue a list on the current line or next line syn match mkdListCont /\s*[^-+*].*/ contained nextgroup=mkdListCont,mkdListItem,mkdListSkipNL contains=@Spell skipnl transparent " Skip empty lines syn match mkdListSkipNL /\s*\n/ contained nextgroup=mkdListItem,mkdListSkipNL " Unorder list syn match mkdListItem /\s*[-*+]\s\+/ contained nextgroup=mkdListSkipNL,mkdListCont skipnl
Tao Zhyn, que tal vez cubre tus casos de uso pero no cubre la sintaxis de Markdown. En Markdown, un elemento de la lista podría contener un bloque de código. Puede consultar mi solución aquí
TL; DR; el problema es que vim no te permite decir algo como: un bloque que tiene la misma sangría que su contenedor + 4 espacios . La única solución que encontré es generar reglas para cada tipo de bloques que podrían estar contenidos en una lista de elementos para cada nivel de sangría (en realidad, yo apoyo el nivel de sangría de 42, pero es un número arbitrario)
Por lo tanto, tengo markdownCodeBlockInListItemAtLevel1 que debe estar contenido en un markdownListItemAtLevel1 y debe tener al menos 8 espacios iniciales, luego markdownCodeBlockInListItemAtLevel2 que debe estar contenido en un markdownListItem de ese elemento debe estar contenido en un markdownListItemAtLevel1 y debe tener al menos 10 espacios iniciales, ecc ...
Sé que han pasado algunos años, pero tal vez alguien consideraría útil esta respuesta, ya que toda la sintaxis basada en la sangría sufre el mismo problema