È possibile assegnare un segno al gruppo “Todo”?


9

È possibile aggiungere un segno da visualizzare nella colonna dei segni ogni volta che la linea ha un gruppo ToDo (ToDo, FIXME ...).

Modificando il mio schema di colori ho cambiato il momento saliente del gruppo Todo, ma vorrei avere un indicatore nella colonna dei segni, come errori e avvertimenti sintetici.

Risposte:


9

Prova questa funzione:

function! SignKeyword()

    silent! sign undefine todo

    sign define todo text=>> texthl=Search

    g/\v\C(<TODO>|<FIXME>)/execute "sign place 9999 line=" . line('.')
    \ . " name=todo buffer=" . bufnr('')

    nohlsearch

endfunction

Ora chiama la funzione dalla riga di comando:

:call SignKeyword()

Oppure aggiungi un mapping nel tuo ~/.vimrcper chiamarlo:

nnoremap <your mapping> :call SignKeyword()<cr>

Oppure aggiungi un autocmd. Ad esempio, se si desidera che la funzione venga chiamata automaticamente all'apertura di un file il cui tipo di file è contrassegnato come markdown:

autocmd FileType markdown call SignKeyword()

La prima riga della funzione silent! sign undefine todoelimina il segno da fare se esiste già, in modo che se i segni sono fuori posto dopo aver eliminato o aggiunto una linea, è possibile richiamare la funzione per risolverli immediatamente.


La seconda riga definisce un segno il cui nome è todo, il cui testo è >>(è possibile modificarlo in base alle proprie preferenze) e che utilizza il gruppo di evidenziazione Cerca (stessa cosa).


La terza riga utilizza il comando globale:

:g/pattern/command

Il comando globale esegue un comando su ogni riga che corrisponde a un modello.

Qui è il modello \v\C(<TODO>|<FIXME>), che significa qualsiasi riga contenente la parola TODO o FIXME .
La regex include l'atomo in \Cmodo che la ricerca rispetti il ​​caso (indipendentemente dall'opzione "ignorecase"). Se si desidera che la ricerca non rispetti il ​​caso, modificarlo in \c.

Ogni volta che viene trovata una tale linea, la seguente riga viene eseguita dalla funzione:

execute "sign place 9999 line=" . line('.')
    \ . " name=todo buffer=" . bufnr('')

Esegue (con il :executecomando) il contenuto della seguente stringa:

"sign place 9999 line=" . line('.') . " name=todo buffer=" . bufnr('')

La stringa include due funzioni incorporate vim: line()e bufnr().
line('.')restituisce il numero della riga corrente quando viene trovata una corrispondenza dal comando globale e bufnr('.')restituisce il numero del buffer corrente.

Ad esempio, se il comando globale trova una corrispondenza sulla riga 10 nel buffer 5, fornirà:

"sign place 9999 line=" . 10 . " name=todo buffer=" . 5

I punti concatenano le stringhe e quindi valuteranno infine:

"sign place 9999 line=10 name=todo buffer=5"

Qual è il :signcomando che posiziona un segno sulla riga 10 nel buffer 5.
9999 è un ID casuale scelto per il segno (puoi sceglierne un altro).


La quarta riga della funzione :nohlsearchdisabilita l'evidenziazione dei motivi abbinati.

Modifica: ho corretto il regex, l'originale era sbagliato. Ho scritto ^[TODO|FIXME]ma invece penso che dovrebbe essere \v\C(<TODO>|<FIXME>). Ci scusiamo per l'inconveniente, sto ancora imparando vimscript.


1
come rimuovere il segno una volta TODOrimosso il commento?

1
non è quello che mi aspettavo, perché rimuove tutti i todosegni, ma comunque ho notato che rimuovendo la linea il segno viene rimosso, quindi va bene

1
Ok, ho aggiunto questa linea all'inizio della funzione: silent! sign undefine todo. Elimina il segno todo se esiste già, in modo che se i segni sono fuori posto dopo aver eliminato una riga contenente la parola chiave TODO o FIXME, è possibile richiamare la funzione per risolverli immediatamente.
saginaw,

2
Il regex era sbagliato, ho digitato ^[TODO|FIXME]ma invece avrebbe dovuto essere \v(TODO|FIXME). Il nuovo regex corrisponderà a una riga contenente una delle parole chiave ma non all'inizio della riga, poiché suppongo che una riga possa contenere del codice prima di un commento, ad esempio come questo some code # FIXME this line needs to be fixed. Il regex precedente era completamente sbagliato, mi dispiace per l'inconveniente, sto ancora imparando vimscript ...
saginaw

1
Il problema con questo approccio è che, se modifichi il buffer, sarà leggermente fuori sincrono, ad esempio aggiungi un'altra riga sopra una riga TODO.
Christian Brabandt,

6

Puoi usare il mio plugin DynamicSigns . Ciò consente i cosiddetti "SignExpression" che sono simili all'espressione fold.

Quindi puoi semplicemente farlo :SignExpression getline(v:lnum)=~'TODO'?'Warning':0

Leggi l'aiuto per ulteriori esempi di ciò che è possibile.

Il vantaggio di usare il mio plugin è che tiene traccia delle modifiche del buffer e regola i segni di conseguenza.

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.