Est-il possible d'affecter un signe au groupe «Todo»?

9

Est-il possible d'ajouter un signe à afficher dans la colonne des signes chaque fois que la ligne a un groupe ToDo (ToDo, FIXME ...).

En ajustant mon schéma de couleurs, j'ai changé la surbrillance du groupe Todo, mais j'aimerais avoir un indicateur dans la colonne des signes, comme des erreurs et des avertissements syntaxiques.


la source

Réponses:

9

Essayez cette fonction:

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

Appelez maintenant la fonction sur la ligne de commande:

:call SignKeyword()

Ou ajoutez un mappage dans votre ~/.vimrcpour l'appeler:

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

Ou ajoutez un autocmd. Par exemple, si vous souhaitez que la fonction soit appelée automatiquement lors de l'ouverture d'un fichier dont le type de fichier est markdown:

autocmd FileType markdown call SignKeyword()

La première ligne de la fonction silent! sign undefine todosupprime le signe à faire s'il existe déjà, de sorte que si vos signes sont mal placés après la suppression ou l'ajout d'une ligne, vous pouvez rappeler la fonction pour les corriger immédiatement.


La deuxième ligne définit un signe dont le nom est todo, dont le texte est >>(vous pouvez le modifier selon vos préférences) et qui utilise le groupe de surbrillance Recherche (même chose).


La troisième ligne utilise la commande globale:

:g/pattern/command

La commande globale exécute une commande sur chaque ligne qui correspond à un modèle.

Ici, le modèle est \v\C(<TODO>|<FIXME>), ce qui signifie toute ligne contenant le mot TODO ou FIXME .
Le regex inclut l'atome \Cafin que la recherche respecte le cas (quelle que soit votre option 'ignorecase'). Si vous souhaitez que la recherche ne respecte pas la casse, remplacez-la par \c.

Chaque fois qu'une telle ligne est trouvée, la ligne suivante est exécutée par la fonction:

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

Il exécute (avec la :executecommande) le contenu de la chaîne suivante:

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

La chaîne comprend deux fonctions intégrées à vim: line()et bufnr().
line('.')renvoie le numéro de la ligne en cours lorsqu'une correspondance est trouvée par la commande globale et bufnr('.')renvoie le numéro du tampon en cours.

Ainsi, par exemple, si la commande globale trouve une correspondance sur la ligne 10 dans le tampon 5, elle donnera:

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

Les points concaténent les chaînes, et donc il va finalement évaluer:

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

Quelle est la :signcommande plaçant un signe sur la ligne 10 dans le tampon 5.
9999 est un identifiant aléatoire choisi pour le signe (vous pouvez en choisir un autre).


La quatrième ligne de la fonction :nohlsearchdésactive la mise en évidence des motifs correspondants.

Edit: j'ai corrigé l'expression régulière, l'original était faux. J'ai écrit ^[TODO|FIXME]mais je pense que ça devrait être le cas \v\C(<TODO>|<FIXME>). Désolé pour le dérangement, j'apprends toujours vimscript.

saginaw
la source
1
comment supprimer le signe une fois le TODOcommentaire supprimé?
1
ce n'est pas ce à quoi je m'attendais, car cela supprime tous les todosignes, mais j'ai juste remarqué qu'en supprimant la ligne, le signe est supprimé, donc ça va
1
Ok, je l' ai ajouté cette ligne au début de la fonction: silent! sign undefine todo. Il supprime le signe todo s'il existe déjà, de sorte que si vos signes sont égarés après la suppression d'une ligne contenant le mot clé TODO ou FIXME, vous pouvez rappeler la fonction pour les corriger immédiatement.
saginaw
2
Le regex était faux, j'ai tapé ^[TODO|FIXME]mais au lieu de cela il aurait dû l'être \v(TODO|FIXME). La nouvelle expression régulière correspondra à une ligne contenant l'un des mots clés mais pas au début de la ligne, car je suppose qu'une ligne pourrait contenir du code avant un commentaire, par exemple comme celui-ci some code # FIXME this line needs to be fixed. Le regex précédent était complètement faux, désolé pour le dérangement, j'apprends toujours vimscript ...
saginaw
1
Le problème avec cette approche est qu'elle se désynchronisera rapidement si vous modifiez le tampon, par exemple ajoutez une autre ligne au-dessus d'une ligne TODO.
Christian Brabandt
6

Vous pouvez utiliser mon plugin DynamicSigns . Cela permet ce que l'on appelle "SignExpression" qui sont similaires à l'expression de repli.

Vous pouvez donc simplement faire :SignExpression getline(v:lnum)=~'TODO'?'Warning':0

Lisez l'aide pour plus d'exemples de ce qui est possible.

L'avantage d'utiliser mon plugin est qu'il suit les modifications du tampon et ajuste les signes en conséquence.

Christian Brabandt
la source