Gibt es in Vim eine Möglichkeit zum Löschen, ohne Text in das Register aufzunehmen?


470

Mit Vim möchte ich oft einen Codeblock durch einen Block ersetzen, den ich gerade gezogen habe.

Aber wenn ich den Codeblock lösche, der ersetzt werden soll, geht dieser Block selbst in das Register, das den Block löscht, den ich gerade gezogen habe. Ich habe mir angewöhnt, zu ziehen, dann einzufügen und dann zu löschen, was ich nicht wollte, aber bei großen Codeblöcken wird es chaotisch, den eingefügten Block und den zu löschenden Block getrennt zu halten.

Was ist der einfachste und schnellste Weg, um Text in Vim zu ersetzen?

  • Gibt es eine Möglichkeit, Text zu löschen, ohne ihn in das Register aufzunehmen?
  • Gibt es eine Möglichkeit zu sagen, z. B. "nächstes Wort ersetzen" oder "bis zum nächsten Absatz ersetzen"?
  • oder ist der beste Weg, die Multi-Register-Funktion irgendwie zu nutzen?

1
vim-easyclip ( github.com/svermeulen/vim-easyclip ) wurde entwickelt, um genau dieses Problem anzugehen
Steve Vermeulen

1
Ich habe eine Frage gestellt, die (zu der Zeit) unwissentlich Ihr tatsächliches Problem dupliziert , aber nicht so sehr die Titelfrage. TL; DR - durch das ersetzen, was Sie mit viwp(for word) gezogen haben.
OJFord

Antworten:


429

Um etwas zu löschen, ohne es in einem Register zu speichern, können Sie das "Schwarzlochregister" verwenden:

"_d

Natürlich können Sie auch eines der anderen Register verwenden, die nichts enthalten, woran Sie interessiert sind.


4
Zuerst dachte ich, dass dieser Befehl nicht richtig funktioniert. Dann wurde mir klar, dass ich eine "Dead Keys" -Version der amerikanischen Tastatur verwendete. Mit diesem Tastaturlayout muss ich tippen "<space>_d. Der Platz wird benötigt, um das ".
Sebastián Grignoli

4
Irgendwelche Ideen, dies selektiv nur in leeren Zeilen zu tun? (Wenn ich ddauf einer leeren Linie bin , geht es in das Schwarze Loch, sonst ist es ddwie normal).
Jonathan Dumaine

6
Um ein Zeichen zu entfernen, versuchen Sie:"_x
Kenorb

54
Dies ist ein Bereich, in dem ein Standard-Texteditor gewinnt. Sie drücken einfach die Löschtaste.
Vince Panuccio

22
Sie können auch etwas mit yyoder '3yy' (oder was auch immer) ziehen, wodurch es in das unbenannte Register, aber auch in 0 eingefügt wird. Sie können es dann weiter einfügen "0p, obwohl Sie es danach verwendet haben d.
Halfgaar

102

Ja. Es ist etwas komplizierter als das Löschen des "alten" Textes zuerst, aber:

Ich beginne mit ..

line1
line2
line3
line4

old1
old2
old3
old4

I shift+ vwähle die Zeilen 1, 2, 3 und 4 aus und lösche sie mit dem dBefehl

Dann lösche ich die alten 1-4 Zeilen auf die gleiche Weise.

Dann mach

"2p

Dadurch werden die vorletzten Zeilen (Zeile 1-4) eingefügt. "3pwird den vorletzten machen und so weiter ..

Also ende ich mit

line1
line2
line3
line4

Referenz: Vim-Dokumentation zum nummerierten Register


Wenn Sie Zeilen mit <Shift-v> auswählen, löschen Sie sie nur mit d, nicht mit dd
Heikki Naski

31
1 bis 9 funktioniert für Löschungen. Um das letzte wirklich eingezogene Element (mit 'y') einzufügen, müssen Sie "0p" verwenden. Dies ist nützlich, wenn Sie zuerst etwas ziehen, das etwas anderes ersetzen soll, aber dann das Standard-Einfügeregister überschreibt.
Rafael de F. Ferreira

Weitere Informationen zum Rückgängigmachen finden Sie im Gundo- Skript (grafisches Rückgängigmachen) .
Lumi

@ RafaeldeF.Ferreira: Ihr Kommentar ist keine Antwort auf diese Frage, aber er löst wahrscheinlich das eigentliche Problem, das das OP dazu veranlasst hat, die Frage überhaupt zu stellen. Für mich war das das eigentliche Problem.
0xc0de

76

VIM-Dokumente: Das nummerierte Register 0 enthält den Text des letzten Yank-Befehls, es sei denn, der Befehl hat ein anderes Register mit ["x] angegeben.

ZB ziehen wir "foo" und löschen "bar" - die Registrierung 0 enthält noch "foo"! Daher kann "foo" mit eingefügt werden"0p


53

Es ist praktisch, eine einfache Zuordnung zu haben, mit der Sie die aktuelle Auswahl durch Puffer ersetzen können.

Zum Beispiel, wenn Sie dies in Ihre .vimrc einfügen

vmap r "_dP       // it's a capital 'p' on the end

Nachdem Sie etwas in das Register kopiert haben (dh mit 'y'), können Sie einfach den Text auswählen, den Sie ersetzen möchten, und einfach 'r' auf Ihrer Tastatur drücken. Die Auswahl wird durch Ihr aktuelles Register ersetzt.

Erläuterung:

vmap - mapping for visual mode
"_d - delete current selection into "black hole register"
P - paste

1
Eine erweiterte Version finden Sie unter: stackoverflow.com/questions/290465/…
Luc Hermitte

Ich würde gerne benutzenvmap <C-P> "_dP
Harry Lee

7
Sie können den Text einfach einfügen, ohne die Auswahl zu löschen. VpErsetzt beispielsweise Ihre aktuelle Zeile sofort durch die abgerissene.
Bobby Marinoff

Diese Lösung behebt kein Problem d, das häufig zum Löschen verwendet wird.
Victor Yarema

35

Ich habe folgendes in mein vimrc eingefügt:

noremap  y "*y
noremap  Y "*Y
noremap  p "*p
noremap  P "*P
vnoremap y "*y
vnoremap Y "*Y
vnoremap p "*p
vnoremap P "*P

Jetzt ziehe ich in das Register der Zwischenablage und lege es aus dem Register der Zwischenablage. Es ist mir egal, was mit dem Standardregister passiert. Ein zusätzlicher Vorteil ist, dass ich mit minimalem Aufwand aus anderen Apps einfügen kann. Ich weiß, dass ich einige Funktionen verliere, aber ich kann sowieso nicht mehr als ein Register / eine Zwischenablage verfolgen.


6
Anstelle all dieser Neuzuordnungen können Sie auch set clipboard=unnamedoder set clipboard=unnamedplus, wodurch die Standard-Zwischenablage in *bzw. geändert wird +.
Steve

5
@Steve Wenn Sie das tun, überschreibt d auch den letzten Ruck in das Register der Zwischenablage, was die Frage zu vermeiden versucht.
79E09796

1
@ 79E09796, ich wollte nicht implizieren, dass es würde; Ich habe diese Antwort kommentiert und nicht die ursprüngliche Frage.
Steve

1
Ich habe diese in meine .vimrc eingefügt und jetzt funktioniert das Ziehen nicht mehr. Irgendeine Idee warum?
tba

2
@tba noremap durch nnoremap (zwei n) ersetzen und es sollte gut funktionieren.
Meain

24

Für das spezifische Beispiel, das Sie gegeben haben, könnte dies funktionieren, wenn ich die Frage verstehe:

*Highlight what you want to put somewhere else
*delete (d)
*Highlight the code that you want it to replace
*paste (p)

6
Dies funktioniert gut, außer wenn Sie mehrere Auswahlen einfügen möchten.

23

Alle Ruck- und Löschvorgänge schreiben standardmäßig in das unbenannte Register. Der letzte Ruck und der letzte Löschvorgang werden jedoch immer (getrennt) in den nummerierten Registern gespeichert. Das Register 0enthält den letzten Ruck. Die Register enthalten 1-9die 9 letzten Löschungen ( 1wobei die neuesten sind).

Mit anderen Worten, ein Löschen überschreibt den letzten Ruck im unbenannten Register, aber es ist immer noch im 0Register vorhanden. Der "_ddin den anderen Antworten erwähnte Blackhole-Register-Trick ( ) funktioniert, weil er das Überschreiben des unbenannten Registers verhindert, aber nicht erforderlich ist.

Sie verweisen mit doppelten Anführungszeichen auf ein Register, sodass das Einfügen des zuletzt gerissenen Textes folgendermaßen erfolgen kann:

"0p

Dies ist eine hervorragende Referenz:


16

Um zu betonen, was EBGreen gesagt hat :

Wenn Sie beim Auswählen von Text einfügen, wird der ausgewählte Text durch den eingefügten Text ersetzt.

Wenn Sie Text kopieren und dann an mehreren Stellen einfügen möchten, verwenden Sie "0pzum Einfügen. Das nummerierte Register 0 enthält den Text des letzten Yank-Befehls.


Sie können auch den Inhalt aller Ihrer Register auflisten:

:registers

Mit diesem Befehl können Sie leichter herausfinden, welches Register Sie möchten, wenn Sie die Antwort von dbr ausführen . Sie sehen auch die Register /,%, #. (Siehe auch :help registers)


Und schließlich überprüfen cWund cWändern Sie ein Wort, das ein nachfolgendes Leerzeichen enthält und nicht. (Die Verwendung von Kapital Wbeinhaltet Interpunktion.)


10

Wenn Sie Vim verwenden, haben Sie den visuellen Modus, der der Auswahl ähnelt, aber mit den Trennmodi ist dies die Grundlage von vi / vim.

Sie möchten den visuellen Modus verwenden, um die Quelle auszuwählen, dann ziehen und dann erneut den visuellen Modus verwenden, um den Bereich des Ziels auszuwählen, und dann aus dem Standardpuffer in Text einfügen.

Beispiel:

In einer Textdatei mit:

1 | qwer
2 | asdf
3 | zxcv
4 | Poiu

mit der folgenden Reihenfolge: ggVjyGVkpSie enden mit:

1 | qwer
2 | asdf
3 | qewr
4 | asdf

Erklärt:

  • gg: gehe zur ersten Zeile
  • V: Starten Sie den visuellen Modus mit ganzen Linien
  • j: eine Zeile nach unten gehen (mit der Auswahl in den vorherigen Zeilen wird die Auswahl um eine Zeile nach unten vergrößert)
  • y: Ziehen Sie an den Standardpuffer (die beiden ausgewählten Zeilen, und Sie verlassen automatisch den visuellen Modus).
  • G: gehe zur letzten Zeile
  • V: Starten Sie den visuellen Modus (wie zuvor)
  • k: eine Zeile nach oben gehen (wie zuvor, wenn der visuelle Modus aktiviert ist, vergrößert sich die Auswahl um eine Zeile)
  • p: Einfügen (mit der Auswahl in den beiden letzten Zeilen werden diese Zeilen durch alles ersetzt, was sich im Puffer befindet - in diesem Fall die beiden ersten Zeilen)

Dies hat den kleinen Nachteil, dass der letzte Block in den Puffer gestellt wird, so dass es für wiederholte Einfügungen derselben Sache irgendwie nicht erwünscht ist. Sie sollten die Quelle daher in einem benannten Puffer mit so etwas wie "ay(in einem Puffer namens "a" speichern ") und mit so etwas einfügen "ap(aber wenn Sie programmieren, möchten Sie wahrscheinlich nicht mehrmals einfügen, sondern eine Funktion erstellen und aufrufen, oder? RICHTIG ?).

Wenn Sie nur vi verwenden, müssen Sie unsichtbare Markierungen anstelle des visuellen Modus verwenden. :he markMehr dazu. Es tut mir leid, aber ich bin nicht sehr gut mit dieser Sache mit unsichtbaren Markierungen. Ich bin ziemlich kontaminiert mit dem visuellen Modus.



9

Eine minimalinvasive Lösung für die Faulen:

Register 0enthält immer den letzten Ruck (wie Rafael , alex2k8 und idbrii bereits erwähnt haben). Leider 0kann es ziemlich ärgerlich sein, ständig ein Register auszuwählen , daher wäre es schön, wenn es standardmäßig pverwendet "0wird. Dies kann erreicht werden, indem Sie die folgenden Zeilen in Ihre einfügen .vimrc:

noremap p "0p
noremap P "0P
for s:i in ['"','*','+','-','.',':','%','/','=','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
    execute 'noremap "'.s:i.'p "'.s:i.'p'
    execute 'noremap "'.s:i.'P "'.s:i.'P'
endfor

Die erste Zeile ordnet jeden pStrich zu "0p. Dies verhindert jedoch den pZugriff auf andere Register. Daher werden alle pStriche mit einem explizit ausgewählten Register dem entsprechenden Befehlszeilenausdruck innerhalb der for-Schleife zugeordnet. Das gleiche gilt für P.

Auf diese Weise bleibt das Standardverhalten erhalten, mit Ausnahme der impliziten pund PStriche, die jetzt 0standardmäßig das Register verwenden .

Tipp 1: Der Befehl cut ist jetzt "0dstatt nur noch d. Aber da ich faul bin, ist mir das viel zu lang;) Deshalb verwende ich folgendes Mapping:

noremap <LEADER>d "0d
noremap <LEADER>D "0D

Die Führungstaste ist \standardmäßig aktiviert, sodass Sie Text einfach durch Eingabe von \doder ausschneiden können \D.

Tipp 2: Das Standardzeitlimit für Mehrschlüsselzuordnungen ist ziemlich kurz. Sie können es erhöhen, um mehr Zeit bei der Auswahl eines Registers zu haben. Siehe :help timeoutlenfür Details, ich benutze:

set timeout timeoutlen=3000 ttimeoutlen=100

7

Führen Sie zuerst diesen Befehl aus:

:h d

Dann werden Sie feststellen, dass Sie in ein bestimmtes Register löschen können. Auf diese Weise ändern Sie nicht, was sich in Ihrem Standardregister befindet.


1
["x]d{motion} Delete text that {motion} moves over [into register x]- Vim:h d
Wes Turner

5

Meine Situation: NormalWenn ich im Modus Zeichen mit dem xTastendruck lösche , überschreiben diese Löschungen mein letztes Register - was die Bearbeitung erschwert, bei der ich Zeichen mit löschen möchtex etwas und in mein letztes Register einfügen (z. B. den gleichen Text um zwei oder zwei einfügen) mehr Orte).

Ich habe den Vorschlag in der akzeptierten Antwort versucht ("_d ) , aber er hat nicht funktioniert.

Aus den akzeptierten Antworten / Kommentaren unter /vi/122/performing-certain-operations-without-clearing-register habe ich dies jedoch zu meinem hinzugefügt ~/.vimrc, was funktioniert (möglicherweise müssen Sie Vim neu starten ):

nnoremap x "_x

Das heißt, ich kann jetzt meine normalen Befehle yank ( y), delete ( d) und paste ( p) ausführen - und Zeichen, die ich lösche, füllen xnicht mehr die neuesten Register.


4

Gelöschter Text wird im Einfügemodus nicht in das Standardregister übernommen.


2
Das Löschen einer signifikanten Textmenge im Standardmodus ist jedoch LANGSAM
Hamish Downer

3

Die zwei Lösungen, die ich im richtigen Kontext verwende, sind:

  • Markieren Sie, was Sie im Vims- VISUALModus ersetzen möchten , und fügen Sie das Register ein.

Ich benutze dies meistens aus Gewohnheit, da ich die zweite Lösung erst viel später gefunden habe, z

yiw   " yank the whole word
viwp  " replace any word with the default register
  • YankRing . Mit diesem Plugin können Sie die Tastenkombination verwenden <ctrl>+<p>, um das zuvor nummerierte Register durch das gerade eingefügte zu ersetzen.

Grundsätzlich fügen Sie das Einfügen wie gewohnt ein, aber wenn Sie feststellen, dass Sie das Standardregister inzwischen überschrieben haben, verlieren Sie das, was Sie tatsächlich einfügen <C-P>möchten, und können es aus dem YankRing-Verlauf suchen und ersetzen!

Eines davon muss Plugins haben ...



2

In der Windows-Version (wahrscheinlich auch unter Linux) können Sie mit in den Copy / Paste-Puffer des Systems ziehen "*y (dh vor Ihrem yank-Befehl mit doppelten Anführungszeichen und Sternchen) .

Sie können dann die austauschbaren Zeilen normal löschen und den kopierten Text mit einfügen "*p.


2

Ich mache oft einen Fehler, wenn ich den Befehlen folge, 'y'ank then' "_d'elete in ein schwarzes Loch, dann 'p'aste. Ich bevorzuge' y'ank, dann lösche, wie ich möchte, dann '" 0p' von das 0-Register, in das der zuletzt kopierte Text verschoben wird.


2

Für emacs-böse Benutzer kann die Funktion (evil-paste-pop)nach dem Einfügen ausgelöst werden und durch vorherige Einträge im Kill-Ring durchlaufen werden. Angenommen, Sie haben es gebunden <C-p>(Standard in Spacemacs), würden Sie treffen, pgefolgt von so vielen <C-p>wie nötig.


1

Für Dvorak-Benutzer besteht eine sehr bequeme Methode darin, nicht benötigten Text in das Register "1" anstelle des Registers "_ black hole" zu löschen, schon allein deshalb, weil Sie "+ 1" mit derselben Umschalttaste und einer schnellen kleinen Bewegung seit 1 drücken können der Schlüssel unmittelbar darüber "in Dvorak (PLUS d ist in der anderen Hand, was den gesamten Befehl höllisch schnell macht).

Dann könnte das "1-Register" aus Bequemlichkeitsgründen für andere Zwecke verwendet werden, aber wenn Sie keinen Zweck haben, der häufiger ist als das Ersetzen von Text, würde ich sagen, dass es eine ziemlich gute Verwendung des Registers ist.


1

Für diejenigen unter Ihnen, die hauptsächlich daran interessiert sind, das unbenannte Register nicht zu überschreiben, wenn Sie einen Text durch virtuelles Auswählen und Einfügen ersetzen.

Sie könnten die folgende Lösung verwenden, die einfach ist und für mich am besten funktioniert:

xnoremap <expr> p 'pgv"'.v:register.'y'

Es ist aus den Antworten (und Kommentaren) hier: Wie man einfügt, ohne das Register zu überschreiben

Zuerst wird die Auswahl überschritten, dann wird die Auswahl mit dem neuen Text erneut ausgewählt (gv). Jetzt das Register, das zuletzt im visuellen Modus verwendet wurde (normalerweise das unbenannte Register, funktioniert aber auch nebenwirkungsfrei, wenn Sie ein anderes Register zum Einfügen verwenden). Und dann ziehen Sie den neuen Wert erneut in das Register.

PS: Wenn Sie eine einfachere Variante benötigen, die auch mit dem Intellj Idea Plugin Vim-Simulation funktioniert, können Sie diese verwenden (Nachteil: Unbenanntes Register überschreiben, auch wenn ein anderes Register zum Einfügen angegeben wurde):

vnoremap p pgvy



0

Die gelegentliche Präferenz von Vim für Komplexität gegenüber Praktikabilität belastet den Benutzer mit dem Anwenden von Registern auf Kopier- / Löschaktionen - wenn man meistens nur das Kopierte einfügen und das Gelöschte "vergessen" möchte.

Anstatt jedoch die komplizierten Register von vim zu bekämpfen, sollten Sie sie bequemer gestalten: Wählen Sie ein "Standard" -Register, um Ihre letzte Löschung zu speichern. Senden Sie beispielsweise Löschungen an das d-Register (lassen Sie ac für die Ad-hoc-Verwendung offen; d ist eine nette Mnemonik):

nnoremap d "dd           "send latest delete to d register
nnoremap D "dD           "send latest delete to d register 
nnoremap dd "ddd         "send latest delete to d register
nnoremap x "_x           "send char deletes to black hole, not worth saving
nnoremap <leader>p "dp   "paste what was deleted
nnoremap <leader>P "dP   "paste what was deleted

Dieser Ansatz verhindert, dass Löschvorgänge die Zerrungen zerstören, ABER die Registrierung des Löschvorgangs verfällt nicht - man kann das Gelöschte einfügen (zurücksetzen), anstatt es in einem schwarzen Loch zu verlieren (wie in der akzeptierten Antwort). Im obigen Beispiel erfolgt dieser Rückruf mit zwei Leader-p-Zuordnungen. Ein Vorteil dieses Ansatzes besteht darin, dass Sie auswählen können, was eingefügt werden soll: (a) was gerade gezogen wurde oder (b) was gerade gelöscht wurde.


0

Register 0 bis 9 sind die neuesten Dinge, die Sie ziehen oder schneiden usw., und enthalten KEINE gelöschten Dinge usw. Wenn Sie also etwas ziehen / schneiden, befindet es sich auch in Register 0, selbst wenn Sie den ganzen Tag danach gelöschte Sachen sagen, registrieren Sie 0 ist immer noch das letzte Zeug, das du gerissen / geschnitten hast.

yiw # geht sowohl zum Standardregister als auch zum Register 0

es zieht das Wort, in dem sich der Cursor befindet

Gelöschte Sachen usw. werden in das Standardregister verschoben, aber NICHT in das Register 0

im Standardmodus:

"0p # Geben Sie den Inhalt von Register 0 ein

im Einfügemodus:

Strg-R 0 # Geben Sie den Inhalt von Register 0 ein

Ich hatte auch einen Freund, der immer riss / schnitt, um x lol zu registrieren.

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.