Ersetzen Sie durch reines Vimscript (ohne `: s`)


11

Ich habe folgendes in meinem vimrc:

func! AddSpaceBeforeEqual()
  s/\([a-z)_0-9"'\[\]]\)=/\1 =/ge
endfunc

Ich benutze vint, um mein vimrc zu fusseln, und habe die folgende Warnung erhalten:

ProhibitCommandWithUnintendedSideEffect Vermeiden Sie Befehle mit unbeabsichtigten Nebenwirkungen. Vermeiden Sie die Verwendung von: s [ubstitute], da dies den Cursor bewegt und Fehlermeldungen druckt. Bevorzugen Sie Funktionen (wie search ()), die besser für Skripte geeignet sind. Für viele vim-Befehle gibt es Funktionen, die dasselbe mit weniger Nebenwirkungen tun. Unter: help functions () finden Sie eine Liste der integrierten Funktionen. Google Vimscript Style Guide

Ich denke jedoch nicht, dass dies eine Möglichkeit ist, die Ersetzung ohne Verwendung des :sBefehls durchzuführen.

Zum Beispiel gibt die search()Funktion die Linien an, die einem Muster entsprechen, aber es gibt keine Möglichkeit, eine Substitution durchzuführen. Die substitute()Funktion arbeitet mit einer Zeichenfolge und ersetzt nicht eine ganze Datei.

Sollte ich selbst eine Ersatzmethode implementieren oder ist dies eine intelligentere Möglichkeit, meine Funktion neu zu schreiben?

Antworten:


9

Der Grund, warum Sie vor unbeabsichtigten Nebenwirkungen gewarnt werden, liegt darin, dass Sie :substituteden Cursor bewegen und die vorherige Suche überschreiben (falls diese außerhalb einer Funktion verwendet wird) . Dies bedeutet jedoch nicht, dass Sie es nicht verwenden sollten, da Sie die Nebenwirkungen von umkehren können :substitute. Hier ist zum Beispiel eine Funktion, die ich erstellt habe und die den Ersatzbefehl verwendet, um nachgestellte Leerzeichen zu entfernen:

function! StripTrailingWhitespace()
    " Save cursor position
    let l:save = winsaveview()
    " Remove trailing whitespace
    %s/\s\+$//e
    " Move cursor to original position
    call winrestview(l:save)
    echo "Stripped trailing whitespace"
endfunction

Beachten Sie, dass Sie den :markBefehl auch zum Speichern der Cursorposition verwenden können. Dies bedeutet jedoch auch, dass Sie die Markierung überschreiben, für die Sie sich entscheiden. Ich habe noch nie Vint verwendet, aber ein Tipp für Linters ist, dass Sie ihre Warnungen mit einem Körnchen Salz nehmen können. In diesem Fall hat es :substitutezwar Nebenwirkungen, aber es sind Nebenwirkungen, die verhindert werden können. Außerdem gibt es sowieso keine bessere Möglichkeit, eine Datei zu suchen und zu ersetzen.


6
Der zuletzt verwendete Suchbegriff wird nach dem Verlassen einer Funktion automatisch wiederhergestellt. Daher sollte das Speichern und Wiederherstellen nicht erforderlich sein, wenn Sie ihn in einer Funktion verwenden. Siehe:help function-search-undo
Martin Tournoij

1
Verwenden Sie lieber Winsaveview () / Winrestview () anstelle von Cursor ()
Christian Brabandt

8

Hier ist eine vereinfachte Implementierung Ihrer Funktion, geschrieben mit substitute():

function! AddSpaceBeforeEqualInWholeBuffer()
    let l = 1
    for line in getline(1,"$")
        call setline(l, substitute(line, '\([^= ]\)=', '\1 =', "g"))
        let l = l + 1
    endfor
endfunction

Passen Sie das Suchmuster nach Geschmack an.


1

Der :sBefehl ist ein reiner Vimscript-Ansatz.

Ich vermute, die Warnung bedeutet nur, dass der Cursor höchstwahrscheinlich nach seiner Verwendung falsch positioniert wird (was Sie umgehen können, indem Sie die winsaveview()Funktion vor und den winrestview()Befehl nach seiner Verwendung verwenden). Außerdem müssen Sie sich um mögliche Fehler kümmern, die auftreten können. Dies wird normalerweise mithilfe des eFlags erledigt . Außerdem muss man sich um einige Einstellungen kümmern, wie zum Beispiel die gdefaultEinstellung, die die Bedeutung des gFlags umkehrt .

Man muss sich um diese Besonderheiten kümmern und das ist wahrscheinlich die Hauptursache für diese Warnungen. Dies bedeutet jedoch nicht, die Verwendung des :sBefehls zu vermeiden . Es ist vollkommen in Ordnung, den :sBefehl zu verwenden , wenn Sie etwas im aktuellen Puffer ersetzen möchten.

(Beachten Sie, dass Sie natürlich alle Zeilen durchlaufen und einen search () / getline () / setline () -Ansatz verwenden können. Dies ist jedoch normalerweise langsamer.)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.