Evidenziazione di Vim Markdown (voci di elenco e conflitti di blocchi di codice)
Domanda
Decido di saperne di più su vim e sulla sua evidenziazione della sintassi. Utilizzando esempi per altri, sto creando il mio file di sintassi per Markdown. Ho visto mkd.vim e ha anche questo problema. Il mio problema è tra le voci dell'elenco e l'evidenziazione del blocco di codice.
Blocco di codice definition :
- la prima riga è vuota
- la seconda riga inizia con almeno 4 spazi o 1 scheda Il blocco
- è terminato con una riga vuota
Esempio:
Regular text
this is code, monospaced and left untouched by markdown
another line of code
Regular Text
Sintassi di My Vim per blocco di codice:
syn match mkdCodeBlock /\(\s\{4,}\|\t\{1,}\).*\n/ contained nextgroup=mkdCodeBlock
hi link mkdCodeBlock comment
Unorder List item definition :
- la prima riga è vuota
- la seconda riga inizia con un [- + *] seguito da uno spazio
- l'elenco è terminato con una riga vuota quindi una riga normale (non elenco)
- tra gli elementi pubblicitari è possibile aggiungere un numero qualsiasi di righe vuote
- un sottoelenco è specificato per rientro (4 spazi o 1 scheda)
- una riga di testo normale dopo che un elemento dell'elenco è incluso come continuazione di tale elemento dell'elenco
Esempio:
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
La mia sintassi Vim per la definizione dell'elemento dell'elenco non ordinato (evidenzio solo [- + *]
):
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
Non riesco a far funzionare l'evidenziazione con le ultime due regole per l'elenco e con un blocco di codice.
Questo è un esempio che interrompe l'evidenziazione della mia sintassi:
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
Al momento non riesco a capire come far funzionare l'evidenziazione nel modo in cui lo voglio anche io
Hai dimenticato di aggiungere un " globale " regola di sintassi utilizzata in entrambe le regole elencate di seguito. È per garantire che inizino con una riga vuota.
syn match mkdBlankLine /^\s*\n/ nextgroup=mkdCodeBlock,mkdListItem transparent
Un'altra nota: avrei dovuto essere più chiaro. Nel mio file di sintassi, le regole dell'elenco vengono visualizzate prima delle regole Blockquote
Soluzione
Assicurati solo che la definizione di mkdListItem sia dopo la definizione di mkdCodeBlock, in questo modo:
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 documentazione di Vim dice in : help: syn-define
:
" Nel caso in cui più di un oggetto corrisponda alla stessa posizione, quello che era ULTIME vittorie definite. Pertanto è possibile sovrascrivere gli elementi di sintassi precedentemente definiti con utilizzando un elemento che corrisponde allo stesso testo. Ma una parola chiave precede sempre a partita o regione. E una parola chiave con maiuscole / minuscole precede sempre a parola chiave con maiuscole / minuscole. "
Altri suggerimenti
hcs42 era corretto. Ricordo di aver letto quella sezione ora, ma me ne sono dimenticato fino a quando hcs24 me lo ha ricordato.
Ecco la mia sintassi aggiornata (poche altre modifiche) che funziona:
""""""""""""""""""""""""""""""""""""""" " 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, che forse copre i tuoi casi d'uso ma non copre la sintassi di Markdown. In Markdown una voce di elenco potrebbe contenere un blocco di codice. Puoi dare un'occhiata alla mia soluzione qui
TL; DR; il problema è che vim non ti consente di dire qualcosa del tipo: un blocco che ha la stessa rientranza del suo contenitore + 4 spazi . L'unica soluzione che ho trovato è quella di generare regole per ogni tipo di blocchi che potrebbero essere contenuti in un elenco di voci per ciascun livello di rientro (in realtà supporto 42 livelli di rientro ma è un numero arbitrario)
Quindi ho markdownCodeBlockInListItemAtLevel1 che deve essere contenuto in un markdownListItemAtLevel1 e deve avere almeno 8 spazi iniziali, quindi markdownCodeBlockInListItemAtLevel2 che deve essere contenuto in un markdownListItemAtem deve essere contenuto in un markdownListItemAtLevel1 la formica deve avere almeno 10 spazi iniziali, ecc ...
So che sono trascorsi alcuni anni ma forse qualcuno considererebbe questa risposta utile poiché tutta la sintassi basata sul rientro soffre dello stesso problema