Ist es möglich, der Gruppe „Todo“ ein Zeichen zuzuweisen?

9

Ist es möglich, ein Zeichen hinzuzufügen, das in der Zeichenspalte angezeigt wird, wenn die Zeile eine ToDo-Gruppe hat (ToDo, FIXME ...).

Durch Ändern meines Farbschemas habe ich das Highlight der Todo-Gruppe geändert, möchte jedoch einen Indikator in der Zeichenspalte haben, z. B. synthetische Fehler und Warnungen.


quelle

Antworten:

9

Versuchen Sie diese Funktion:

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

Rufen Sie nun die Funktion in der Kommandozeile auf:

:call SignKeyword()

Oder fügen Sie eine Zuordnung hinzu ~/.vimrc, um sie aufzurufen:

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

Oder fügen Sie ein Autocmd hinzu. Wenn Sie beispielsweise möchten, dass die Funktion beim Öffnen einer Datei, deren Dateityp Markdown ist, automatisch aufgerufen wird:

autocmd FileType markdown call SignKeyword()

In der ersten Zeile der Funktion wird silent! sign undefine tododas Zeichen todo gelöscht, falls es bereits vorhanden ist. Wenn Ihre Zeichen nach dem Löschen oder Hinzufügen einer Zeile falsch platziert werden, können Sie die Funktion aufrufen, um sie sofort zu beheben.


In der zweiten Zeile wird ein Zeichen definiert, dessen Name todo lautet, dessen Text lautet >>(Sie können ihn nach Ihren Wünschen ändern) und das die Suchmarkierungsgruppe verwendet (dasselbe).


Die dritte Zeile verwendet den globalen Befehl:

:g/pattern/command

Der globale Befehl führt in jeder Zeile einen Befehl aus, der einem Muster entspricht.

Hier ist das Muster \v\C(<TODO>|<FIXME>), was bedeutet, dass jede Zeile entweder das Wort TODO oder FIXME enthält .
Die Regex enthält das Atom, \Csodass die Suche den Fall berücksichtigt (unabhängig davon, welche Option "Ignorieren" ist). Wenn Sie möchten, dass die Suche den Fall nicht berücksichtigt, ändern Sie ihn in \c.

Immer wenn eine solche Zeile gefunden wird, wird die folgende Zeile von der Funktion ausgeführt:

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

Es führt (mit dem :executeBefehl) den Inhalt der folgenden Zeichenfolge aus:

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

Die Zeichenfolge enthält zwei in vim integrierte Funktionen: line()und bufnr().
line('.')Gibt die Nummer der aktuellen Zeile zurück, wenn der globale Befehl eine Übereinstimmung findet, und bufnr('.')gibt die Nummer des aktuellen Puffers zurück.

Wenn der globale Befehl beispielsweise in Zeile 10 im Puffer 5 eine Übereinstimmung findet, gibt er Folgendes aus:

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

Die Punkte verketten die Zeichenfolgen und werden schließlich ausgewertet:

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

Mit diesem :signBefehl wird ein Zeichen in Zeile 10 in Puffer 5 platziert.
9999 ist eine zufällige ID, die für das Zeichen ausgewählt wurde (Sie können eine andere auswählen).


Die vierte Zeile der Funktion :nohlsearchdeaktiviert die Hervorhebung der übereinstimmenden Muster.

Bearbeiten: Ich habe den regulären Ausdruck behoben, das Original war falsch. Ich schrieb, ^[TODO|FIXME]aber stattdessen denke ich, dass es sein sollte \v\C(<TODO>|<FIXME>). Entschuldigung für die Unannehmlichkeiten, ich lerne immer noch Vimscript.

saginaw
quelle
1
Wie entferne ich das Zeichen, nachdem der TODOKommentar entfernt wurde?
1
Das ist nicht das, was ich erwartet habe, weil dadurch alle todoZeichen entfernt werden, aber ich habe gerade bemerkt, dass das Entfernen der Linie das Zeichen entfernt, also ist das in
1
Ok, ich habe diese Zeile am Anfang der Funktion hinzugefügt : silent! sign undefine todo. Das Zeichen todo wird gelöscht, wenn es bereits vorhanden ist. Wenn Ihre Zeichen nach dem Löschen einer Zeile mit dem Schlüsselwort TODO oder FIXME falsch platziert werden, können Sie die Funktion zum sofortigen Beheben der Zeichen aufrufen.
Saginaw
2
Die Regex war falsch, ich habe getippt, ^[TODO|FIXME]aber stattdessen hätte es sein sollen \v(TODO|FIXME). Der neue reguläre Ausdruck stimmt mit einer Zeile überein, die eines der Schlüsselwörter enthält, jedoch nicht den Zeilenanfang, da eine Zeile beispielsweise Code vor einem Kommentar wie diesem enthalten könnte some code # FIXME this line needs to be fixed. Die vorherige Regex war völlig falsch, entschuldigen Sie die Unannehmlichkeiten, ich lerne immer noch Vimscript ...
Saginaw
1
Das Problem bei diesem Ansatz ist, dass er schnell nicht mehr synchron ist, wenn Sie den Puffer ändern, z. B. eine weitere Zeile über einer TODO-Zeile hinzufügen.
Christian Brabandt
6

Sie können mein DynamicSigns- Plugin verwenden. Dies ermöglicht einen sogenannten "SignExpression", der dem Fold-Ausdruck ähnlich ist.

So können Sie einfach tun :SignExpression getline(v:lnum)=~'TODO'?'Warning':0

In der Hilfe finden Sie weitere Beispiele dafür, was möglich ist.

Der Vorteil der Verwendung meines Plugins besteht darin, dass es Änderungen des Puffers verfolgt und die Vorzeichen entsprechend anpasst.

Christian Brabandt
quelle