Ich möchte meinen Workflow zum Suchen und Ersetzen in Vim optimieren. Das ist etwas, was ich oft mache, wie ich mir sicher bin, dass die meisten von Ihnen es auch tun. Normalerweise kopieren Sie einen Block und ändern den Namen einer Variablen an einigen Stellen. Ich weiß, ich weiß, das löst wahrscheinlich deinen Reflex "Warum kopierst du und fügst du Code ein" aus, aber lass uns diesen Weg nicht beschreiten ... Es gibt viele gültige Anwendungsfälle :)
Ich bin mir der Befehle zum Suchen und Ersetzen sehr wohl bewusst: :s
oder :%s
aber ich mag sie nicht. Es zwingt mich, sowohl den vollständigen Variablennamen, den ich suche, als auch den Namen einzugeben, in den ich ihn ändere. Vielleicht gibt es eine bessere Möglichkeit, die Anzahl der Tippvorgänge zu korrigieren :%s
? Ich verwende oft lange beschreibende Variablennamen, so dass das für mich wirklich ein Deal Breaker ist. Ich mag es auch nicht, dass das Herausschreiben eines Variablennamens von Grund auf für Tippfehler anfällig ist und Zeit und Nerven kostet, um Tippfehler aufzuspüren. Ich bevorzuge es, es einmal zu tippen und dann zu kopieren und einzufügen, um dies nach Möglichkeit ganz zu vermeiden.
In meinem aktuellen Arbeitsablauf wird eine Kombination aus "Verschieben" / "Ziehen" / "Auswählen" / "Suchen" / "Platzieren" verwendet, um die Datei zu verschieben und einzeln zu ersetzen. Es ist nicht besonders gut, hat aber den Vorteil, dass Sie keine vollständigen Variablennamen eingeben müssen. Ich muss möglicherweise nur die ersten paar Buchstaben mit /
einem anderen Bewegungsbefehl (z. B. fx
) eingeben und dann ve
das ganze Wort auswählen. Es macht mir auch nichts aus, dass ich das für jeden Fall wiederholen muss. Ich führe niemals einen vollständigen Ersatz durch, ohne jede Änderung zu bestätigen. Es wäre jedoch viel besser, wenn ich die Ersetzungsaktion mit einem einzigen Tastendruck wiederholen könnte (was mit dieser Methode nicht möglich ist). jeder Austausch ist in der Regel so etwas wie n
dann ve
dann p
(oder noch schlimmer "0p
)
Gibt es einen schnelleren Weg?
quelle
.
wiederholt den letzten "Befehlsblock" (der genaue Begriff ist nicht bekannt. Zum Beispiel: Verschieben + Aktion + Text. Zum Beispiel:cwtoto<Esc>
(Wechsel vom Cursor zum Ende des Wortes mit "toto"),c/foo<enter>bar<Esc>
(Wechsel vom Cursor zu kurz vor " foo ", und durch" bar "ersetzen. Sie können dann verschieben (mit Cursor, hjkl oder einer Zahl + hjkl (macht es n-mal), G (gehen Sie zum Ende der Datei), / etwas (gehen Sie kurz vor" etwas "), etc) und dann drücken.
, um den gleichen" Befehlsblock "zu wiederholenn
ve
"0p
. Was leider nicht mit nur einem repliziert werden kann.
n ce ctrl-r 0 <esc> n.n.n.n.n.n.
Antworten:
Ich habe tatsächlich einen ähnlichen Arbeitsablauf wie Sie (Kopieren und Einfügen von Blöcken, die ähnlich sind, und dann
:s
Ändern von Variablennamen), insbesondere wenn ich viele Zeilen schreibe, die ähnlich sind, mit Ausnahme der Variablen, die sie verwenden. Aber ich mache ein paar Dinge, die Sie vielleicht nützlich finden.Allgemeine vim Dinge
Das Erste, was Ihnen helfen wird, ist zu erkennen, dass
:s//foo/g
der zuletzt verwendete Suchbegriff durch foo ersetzt wird . Das allein kann viel Zeit sparen, aber wenn Sie es mit dem Sternchen-Befehl (Suche nach dem Wort unter dem aktuellen Cursor) kombinieren, spart es Tonnen von Zeit. Zum Beispiel, um allefoo
zu ändernspam
, anstatt zu tunUm sowohl foo als auch spam (möglicherweise lange Variablen) auszutippen, navigieren Sie einfach zu foo und führen Folgendes aus:
Auf diese Weise können Sie schnell den Namen der Variablen ermitteln, die Sie ändern, indem Sie danach suchen. Sie müssen ihn dann nicht mehr eingeben. Dies funktioniert auch gut mit Ihrem aktuellen Arbeitsablauf, wenn Sie
n
viel verwenden. Es ist auch hilfreich, ein zu habenhlsearch
, weil Sie dann visuell erkennen können, wo sich die Variablen befinden, die Sie ersetzen.(Randnotiz: Mit dem Sternchen-Befehl werden Wortgrenzen hinzugefügt, dh
\<
und\>
um das Wort unter dem Cursor. Wenn Sie dies nicht möchten, verwenden Sieg*
stattdessen.)Mit können Sie
@:
den letzten Ersatzbefehl wiederholen. Das ist schön, wenn Sie einen:s
Befehl für viele Zeilen ausführen möchten , aber nicht für alle, so:%s
dass dies nicht funktioniert. Eine andere Option ist das Bestätigungsflag, dh:%s///gc
. Auf diese Weise können Sie bei jedem Auftreten eingebeny
odern
entscheiden, ob Sie es ersetzen möchten oder nicht.Wie Desty betont hat , können Sie auch &den letzten Ersatzbefehl erneut ausführen. Beachten Sie jedoch, dass dadurch Ihre Flags (wie z. B. oder ) nicht beibehalten werden . Ob das gut oder schlecht ist, hängt von Ihrer persönlichen Meinung ab. Wenn Sie dies verwenden möchten, aber Ihre Flaggen auch behalten sollen, können Sie dies tun
global
confirm
Wenn Sie jedes Vorkommen in einem Block ändern möchten, aber nicht jede Übereinstimmung in der Datei, können Sie immer eine visuelle Auswahl des Blocks verwenden, der ausgefüllt wird
zu Ihrem Stellvertreter, der es auf die Zeilen beschränkt, die Sie ausgewählt haben. In Kombination mit dem Asterisk-Ansatz finde ich dies äußerst nützlich. Wenn Sie mehrere Ersatzbefehle für denselben gvZeilenblock ausführen, können Sie dieselben Zeilen auch erneut auswählen, um einen anderen Befehl auszuführen . (ob es ein
:substitute
oder ein normaler Befehl ist)Wenn Sie einen anderen Ersatz - Befehl tun, nicht wahr brauchen die gleichen Linien erneut auszuwählen, weil
:'<,'>
nach wie vor auf den gleichen Leitungen betrieben werden kann . Es ist jedoch bequemer zu tippeneher, als
Plugins / Mappings gefallen mir
Ich habe die folgende Zuordnung in meinem,
.vimrc
die den Sternchenansatz erweitert, so dass ich nur den neuen gewünschten Namen eingeben muss:Um dies zu verwenden, setzen Sie einfach den Cursor auf das Wort, das Sie ändern möchten,
<leader>rNewVarName<cr>
und geben Sie ein, und Sie sind fertig. Beachten Sie, dass hierdurch alle Übereinstimmungen ersetzt werden, ohne dass Sie die Option erhalten, sie zu bestätigen, sodass Sie möglicherweise nicht so begeistert sind. Natürlich können Sie es auch einfach in ändernUm die Bestätigungsoption zuzulassen.
edit : Nach den beiden Antwort der Masse und rcorre Kommentar , können Sie auch diese schreiben als
Das hat den Vorteil, dass Ihr unbenanntes Register gleich bleibt.
Wenn Sie beispielsweise Gruppen ähnlicher Variablen gleichzeitig umbenennen, ändern Sie
zu
Es kann schwierig sein, alle einzeln zu ersetzen. Hier bietet sich tpope / vim-abolish an. Sie können all diese in einem Befehl ersetzen durch:
und es kümmert sich für Sie um die Großschreibung.
Dies sollte Ihnen viel helfen, aber lassen Sie mich wissen, wenn Sie etwas an diesen Ansätzen nicht mögen oder das Gefühl haben, dass sie fehlen. Ich spreche gerne über weitere Ansätze. :)
Literatur-Empfehlungen:
:h s_c
:h *
:h g*
:h @:
:h /\<
:h &
quelle
<leader>rc
(odercr
), dies/c
am Ende hinzuzufügen . Außerdem habe ichset gdefault
eingestellt, weil ich fast nie ein einziges Ergebnis ersetzen möchte, also wäre es einfachyiw:%s/\<<C-r>"\>//<left><left>
ctrl+r-ctrl+w
in der Zuordnung verwenden (wie von @Mass vorgeschlagen), sollte es das gleiche funktionieren, aber nicht mit Ihrem Yank-Register (was wünschenswert oder nicht wünschenswert sein kann).
weitere Ersetzungen vornehmen .Die
c_CTRL-R
Kartenfamilie kann Ihren Workflow erheblich verbessern:Sie müssen bei der Verwendung keine Variablennamen eingeben, sondern müssen
:s/
nurCTRL-R
CTRL-W
das Wort unter dem Cursor in die Befehlszeile einfügen (Warnung: Sonderzeichen werden hierdurch nicht ausgeblendet, wie dies der*
Fall ist).Nachdem Sie mit eine kleine Änderung vorgenommen haben
ce
, können Sie mit nach dem alten Wort suchen/
CTRL-R
-
. Dann.
mit die Änderung wiederholen.Wenn Sie Änderungen am Suchmuster vornehmen müssen,
CTRL-R
/
wird die vorhandene Suche in die Befehlszeile eingefügt.Schließlich können Sie den Inhalt jedes Registers mit setzen
CTRL-R
{register}
quelle
Ctrl-R
/
? Ich verwende dies ziemlich häufig in:s
Befehlen, wenn ich einen Suchbegriff verwenden möchte, der fast, aber nicht ganz genau mit dem vorherigen übereinstimmt.Es gibt noch ein paar Methoden, die (zu meiner Überraschung!) Noch nicht erwähnt wurden.
Verwenden des
gn
BefehlsgnFunktioniert wie der nBefehl, mit der Ausnahme, dass nicht nur zum Spiel gesprungen wird, sondern auch der visuelle Modus aufgerufen wird, bei dem das gesamte Spiel ausgewählt ist.
Wenn Sie also ein Wort ändern möchten (oder etwas, das Sie mit einem regulären Ausdruck abgleichen können!), Suchen Sie zuerst danach 1 und drücken cgnSie dann, gefolgt von dem Text, durch den Sie die Übereinstimmung ersetzen möchten, und Esckehren Sie zum normalen Modus zurück.
(Sie erwähnen, dass manchmal der Ersatztext, den Sie verwenden möchten, im
"0
Ruckregister gespeichert wird. Beachten Sie, dass Sie diesen schnell eingeben können, ohne ihn erneut eingeben zu müssen, indem Sie Ctrl+R0im Einfügemodus auf drücken .)Sie können dann zum nächsten Spiel springen und die Änderung mit einem einzigen .Tastendruck wiederholen !
Wenn es Stellen gibt, an denen Sie keine Ersetzung vornehmen möchten, drücken Sie einfach un, um die Änderung rückgängig zu machen und zum nächsten Spiel zu springen.
1: Schnell, indem Sie die anderen Vorschläge auf dieser Seite verwenden, z. B. *, Ctrl+RCtrl+Wusw. Weitere Vorschläge zum erstmaligen Auffüllen Ihrer Suche finden Sie in Peter Rinckers Kommentar .
Verwenden des Auswahlmodus
( Das erfuhr ich von romainl ‚s Beitrag auf der vim subreddit . Ich weiß nicht , ob er es erfunden selbst oder vorging es nur auf.)
Der Auswahlmodus ähnelt dem visuellen Modus, außer wenn Sie mit der Eingabe beginnen, wird der ausgewählte Text sofort durch den von Ihnen eingegebenen Text ersetzt (so wie die Auswahl in den meisten anderen Editoren funktioniert).
Sie können dieses Trio von Zuordnungen verwenden, um ein sehr schnelles Suchen / Ersetzen durchzuführen, das Sie bei Bedarf in der Mitte der Datei ändern können:
Normalmodus-Zuordnung : Aktiviert den Auswahlmodus mit dem Wort, das dem ausgewählten Cursor am nächsten steht.
Sie können dann Ihre Ersetzung für das ausgewählte Wort eingeben und ( ohne zu drücken Esc) Folgendes verwenden:
Einfügemodus-Zuordnung : Springt zum nächsten Treffer und wechselt in den Auswahlmodus.
Sie können dann entweder eine neue Ersetzung eingeben oder auf drücken ., um Folgendes zu verwenden:
Moduszuordnung auswählen : Gibt den zuletzt eingefügten Text erneut ein - wiederholt im Wesentlichen die letzte Einfügung.
quelle
gn
Methode gestern am Ende meiner Antwort vi.stackexchange.com/a/13696/488 erwähnt, wofür es sich lohnt! Ihre Antwort ist jedoch viel besser formatiert.gn
einmal auf), und es ist die spezifische Methode (und nicht nur dergn
Befehl), von der ich überrascht war, dass sie noch nicht erwähnt wurde.gn
. Bietet Ihnen mehr Suchoptionen. Armer visuelles Sterne - Mapping:xnoremap * :<c-u>let @/=@"<cr>gvy:let [@/,@"]=[@",@/]<cr>/\V<c-r>=substitute(escape(@/,'/\'),'\n','\\n','g')<cr><cr>
. Vimcasts-Folge zum Thema: Mit gn bei Suchergebnissen aktivDas Plugin https://github.com/terryma/vim-multiple-cursors kümmert sich zum größten Teil um dieses Problem.
Mein Arbeitsablauf sieht normalerweise folgendermaßen aus:
ctrl-n
bis alles ausgewählt ist.c
und geben Sie den Ersatz ein.Das Praktische dabei ist, dass Sie auch kompliziertere Operationen ausführen können als nur Suchen-Ersetzen. Wenn Sie dies jedoch zu weit treiben, zeigt das Plug-in einige Störungen an.
quelle
Eine andere Möglichkeit, Dinge zu tun, die noch nicht erwähnt wurden: Sie können das Befehlszeilenfenster (geöffnet
q:
im normalen Modus - siehe:help q:
für weitere Informationen) verwenden, in dem Sie vollen Zugriff auf die Autovervollständigungsfunktionen von Vim (i_CTRL-N
/i_CTRL-P
und die verschiedeneni_CTRL-X
Sequenzen) haben unter ihnen sein).Im Befehlszeilenfenster können Sie auch Befehle im normalen Modus zum Bearbeiten der Befehlszeile verwenden. Dies bedeutet beispielsweise, dass Sie Teile vorheriger Befehle in Ihren Befehlszeilenverlauf ziehen und einfügen können.
Beachten Sie, dass der Cursor bei der Verwendung in das Befehlszeilenfenster verschoben wird. Dies bedeutet, dass
CTRL-R CTRL-W
ähnliche Methoden, bei denen der Text unter dem Cursor eingefügt wird, anders als in der normalen Befehlszeile nicht funktionieren.quelle
:substitute
Befehls fertig sind, indem Sie<ctrl-f>
Die Lösung dafür liegt für mich etwas zwischen den anderen Antworten:
Angenommen, Sie haben 6 identische Zeilen und möchten "Apfel" in den beiden mittleren ersetzen:
Was ich mache ist:
v
, um in den visuellen Modus zu gelangen2j
:s/<C-R><C-W>/
Dies verwendet die visuelle Auswahl als Bereich für:s
und fügt dann das Wort unter dem Cursor ein<C-F>
drücke, um dich in einen Modus zu versetzen, in dem du deinen Befehl bearbeiten kannst, als wäre es ein Puffer. Sie können also beliebige Vervollständigungen oder Plugins verwenden, um das Ersatzwort auszuwählen, und schon sind Sie fertig.Alles in allem wäre der Fluss dafür
/apples<CR>2nv/apples<CR>nn:s/<C-R><C-W/oranges<CR>
aber das sieht schlimmer aus als es ist.In Ihrem Fall, können Sie die anhängen
/c
an den:s
Befehl an diejenigen , überspringen Sie nicht wollen, wenn Ihr Angebot ein paar enthält , die Sie überspringen wollen::s/<C-R><C-W/orange/c
.Alternativ (und vielleicht auch einfacher) können Sie nach dem gesamten Wort suchen, das Sie ersetzen möchten,
c
es dann änderngn
und.
die Suche wiederholen und dieselbe Änderung erneut anwenden. Es sieht so aus/\<apple\><CR>viwcorange<ESC>gn.gn.gn..ngn.
, als würde man es bei drei wiederholen, dann eine Instanz überspringen und ein letztes Mal wiederholen.quelle
vim -Nu NONE
). Es piept nur, wenn ich die erste drücke.
. Irgendeine Idee warum das so ist? In jedem Fall wäre es einfacher, zu verwenden ,ciw
stattviw
undn
die stattdessengn
auf diese Weise , um Änderungen vorzunehmen.Dies hängt nicht ganz mit der Frage zusammen, sollte aber dennoch bei der Auswahl des zu ersetzenden Wortes helfen.
Mit der inkrementellen Suche (
set incsearch
) können Sie das Präfix des gesuchten Wortes eingeben, und vim springt automatisch zum ersten Vorkommen des Präfixes, wenn Sie mehr und mehr eingeben. Die Suche wird bestätigt, wenn Sie die Eingabetaste drücken und mit Esc verwerfen.Die inkrementelle Suche bietet jedoch eine weitere nützliche Funktion. Wenn Sie das Präfix eines Wortes bereits eingegeben haben und sich der Cursor an der richtigen Position befindet, drücken Sie
<C-L>
, um Zeichen aus dem Wort unter dem Cursor in die Suchzeichenfolge einzufügen. Auf diese Weise können Sie die ersetzte Zeichenfolge fast ohne Tastendruck eingeben.Also, wenn ich ersetzen möchten
someOddVariableName
mitevenOdderVariableName
, ich/someOddV
und kommen zum Auftreten vonsomeOddVariableName
;<C-L>
bissomeOddVariableName
in der Suchzeile vollständig angezeigt wird;:%s//evenOdderVariableName/g
oder welcher Ersetzungsbefehl auch immer benötigt wird; Vielleicht möchten Sie hier anderen Antworten folgen.quelle
Sie können den Variablennamen zuerst in den Puffer schreiben (
yw
um ein Wort zu kopieren) und es dann:%s
durch Drücken von in den Puffer einfügen<C-r>"
.quelle
Wenn Sie eine Variable innerhalb des neuen (eingefügten) Blocks ersetzen möchten, habe ich zwei Vorschläge:
Automatisches Ersetzen
Gehe in die erste Zeile des neuen Blocks und drücke
ma
. Dies markiert einen Ort und benennt ihna
.Gehe zur letzten Zeile des neuen Blocks, drücke
mb
. Jetzt haben Sie zwei benannte Standorte.Jetzt ersetzt zwischen den beiden Linien, etwa so:
:'a,'bs/oldVarName/newVarName/g
.Das heißt, der Ersetzungsbereich liegt zwischen Ihren beiden Markierungen.
Der manuelle Weg
Gehen Sie in die erste Zeile des neuen Blocks.
Verwenden Sie
/oldVarName
, um die erste Instanz von zu findenoldVarName
.Ändere es wie
cwnewVarName<Esc>
folgt:, was das Wort ändertnewVarName
und Flucht schlägt.Verwenden Sie
n
, um zur nächsten Instanz von zu wechselnoldVarName
.Verwenden Sie
.
diese Taste, um die letzte Änderung zu wiederholen (dh, um diese zu wiederholencw
).quelle
Viele der anderen Antworten befassen sich bereits mit den integrierten Möglichkeiten zur Verbesserung des Such- und Ersetzungs-Workflows, aber ich wollte abolish.vim erwähnen , ein Plugin von Tim Pope. Es werden Ersetzungen vorgenommen, bei denen Sie eine größere Bandbreite von Fällen abdecken möchten, die normalerweise durch Variationen in den einzelnen Fällen oder dadurch verursacht werden, dass Sie sich sowohl mit der Singular- als auch mit der Pluralform eines Wortes befassen müssen.
:S/child{,ren}/adult{,s}/g
richtig konvertiertchild
nachadult
,Children
nachAdults
undCHILD
nachADULT
.Wenn Sie sich mit Wörtern in Kamelschalen beschäftigen, müssen Sie die Kapitelle, in denen Sie sie benötigen, in die Original- und Ersatzwörter aufnehmen.
%:S/wordWrap/textBreak/g
richtig behandelt beidewordWrap
undwordwrap
.quelle
Wie andere bereits gezeigt haben, können Sie, wenn Sie den Cursor über Ihrem Wort positionieren, die Befehlsfamilie Strg + r verwenden, wobei Strg + r Strg + w wahrscheinlich am besten geeignet ist.
Diese Methode funktioniert jedoch nur für das Einfügen eines Wortes (des Wortes direkt unter dem Cursor). Was ist, wenn sich mehrere Textteile im Puffer befinden, die wir verwenden möchten? Während Sie sich in der Befehlszeile befinden, können Sie den Cursor nicht bewegen. Der beste Weg, dies zu tun, besteht darin, Textteile, die Sie benötigen, in verschiedene Register zu kopieren. Dies können Sie tun, indem Sie dem Kopierer "{reg_letter} (Anführungszeichen und den Buchstaben aus dem Register) voranstellen. Auf diese Weise ist es möglich, füge später mit Strg + r {reg_letter} verschiedene Wörter in die Kommandozeile ein. Dies ist etwas umständlich, funktioniert aber.
Zurück zur vorherigen Idee, wäre es großartig, wenn wir die Cursorposition über den Puffer bewegen würden, während wir ein Muster schreiben. Auf diese Weise konnten wir mit Strg + R Strg + W Text von verschiedenen Positionen "auswählen". Deshalb habe ich ein Plugin erstellt, das genau das tut: EXtend.vim Das Plugin verfügt auch über viele andere Funktionen, um Ersetzungsoperationen durchzuführen.
quelle