Wie lösche ich Zeile (n) unter der aktuellen Zeile in vim?

78

Gibt es einen Befehl zum Löschen einer Zeile (oder mehrerer Zeilen), die unmittelbar unter der aktuellen Zeile liegt? Momentan mache ich es als: jddund dann .nach Bedarf zu wiederholen. Gibt es einen Befehl, der all dies kombiniert?

UPDATE: Der Grund, warum ich einen solchen Befehl haben möchte, ist, dass ich mich nicht von der aktuellen Position entfernen möchte, aber in der Lage bin, die folgenden Zeilen zu löschen.

Valentin Vasilyev
quelle
Ich denke, @Peter Rinckers Antwort sollte als Antwort markiert werden
gixxer
getan @gixxer, danke für die Heads-Ups
Valentin Vasilyev

Antworten:

159

Der Befehl delete ex funktioniert gut.

:+,$d

Dadurch werden alle Zeilen von aktuell +1 bis zum Ende gelöscht ($)

Um die nächsten 2 Zeilen zu löschen, würde der folgende Bereich funktionieren, +1,+2oder Kurzform+,+2

:+,+2d

Wie @ib erwähnt, bewegt der Befehl :deleteoder :dden Cursor an den Anfang der Zeile neben dem gelöschten Text. (Auch mit nostartoflineSet). Um dies zu überwinden, können wir den ``Befehl normal mode ausgeben . ``springt vor dem letzten Sprung an die genaue Position zurück, in diesem Fall den :dBefehl. Unser Befehl ist jetzt

:+,+2denter``

Oder als ein Ex-Befehl

:+,+2d|norm! ``

Um dies zu vereinfachen, fassen wir dies alles in einem Befehl zusammen:

command! -count=1 -register D :+,+<count>d <reg><bar>norm! ``

Löschen Sie nun die nächsten 3 Zeilen:

:3D

Dieser Befehl kann auch einen {reg}wie :deleteund :yanktun. Das Löschen der nächsten 4 Zeilen in das Register awäre also:

:4D a

Für mehr Informationen

:h :d
:h :command
:h :command-register
:h :command-count
:h ``
Peter Rincker
quelle
3
Beachten Sie, dass dies eine ziemlich einfache Lösung ist, die "out of the box" funktioniert und auf andere Befehle verallgemeinerbar ist (z. B. :+1,+5s!a!b!gwird a in den 4 Zeilen nach dem Cursor durch b ersetzt). Weitere Beispiele finden Sie unter: Hilfebefehlsbereiche.
David Winslow
Diese einfache Lösung wäre großartig, wenn sie nur den Cursor nicht bewegen würde. Zumindest sollte der Befehl so aussehen :+,$d|norm!``. Übrigens, wie in der Frage angegeben, möchte der Autor der Frage mehrere Zeilen unterhalb der aktuellen löschen, nicht unbedingt bis zum Ende der Datei.
ib.
@ib: Würde die Antwort durch eine detailliertere Erklärung der Bereiche verbessert? Vielleicht set sol? Wie benutzt man die `Marke?
Peter Rincker
@ Peter: Wahrscheinlich wäre es. Das solAusschalten allein löst das Problem übrigens nicht: Wenn man beispielsweise drei Zeilen mit löscht, :+,+3dwird der Cursor auf die Zeile neben den gelöschten verschoben.
ib.
@ib: Ich habe deine Vorschläge in meine Antwort aufgenommen. Danke für deine Rückmeldung.
Peter Rincker
77

dGsollte arbeiten.
Dies bedeutet, dass alle Zeilen bis zum Ende der Datei vom aktuellen Cursor gelöscht werden.

Anand Nagaraj
quelle
29

Dadurch werden ALLE Zeilen unter der aktuellen gelöscht:

jdG

Leider bewegt sich der Cursor nach dem Löschen an den Anfang der aktuellen Zeile.

ClosedID
quelle
2
Und löscht auch jede Zeile bis zum Ende des Puffers.
ib.
Ich habe die ursprüngliche Frage falsch verstanden, sorry. Dachte, das OP möchte ALLE Zeilen unterhalb der aktuellen löschen. Mein Beitrag wurde geändert.
ClosedID
7

Nun, um es einfach zu machen, könnten Sie den Befehl xxdd verwenden. Die meiste Zeit kenne ich (zumindest habe ich eine Idee) die Größe des Skripts, das ich bearbeite. Der folgende Befehl ist normalerweise mehr als genug:

  • 99dd
  • 999dd, um 999 Zeilen ab der Cursorposition zu entfernen.
  • 9999dd
  • 99999dd für sehr langes Skript;)
xaa
quelle
4

Die anderen Lösungen sind informativ, aber ich denke, es wäre einfacher, ein Makro dafür zu verwenden:

qq (beginnt mit der Aufnahme)

jddk (Gehen Sie nach unten, löschen Sie die Zeile und gehen Sie wieder nach oben - dh das, was Sie tun möchten.)

q (Aufnahme beenden)

Jetzt können Sie @qdiese Aktion ausführen und den Cursor an der aktuellen Position halten. Sie können auch 5@q5 Zeilen unter dem Cursor löschen.

Und schließlich, wenn Sie die Aktion mehr als einmal wiederholen, können Sie sie einfach @@nach der ersten Ausführung @qeingeben (dies wiederholt das zuletzt verwendete Makro - in diesem Fall q).

Mindthief
quelle
2

Dies ist ein Job für Noten!

Versuchen maj20dd`a

maSetzt die dateispezifische Marke 'a', j20ddführt den gewünschten Löschvorgang durch (in diesem Fall 20 Zeilen) und `astellt die Position der Marke (Zeile und Spalte) wieder her.

Natürlich kann dieses Muster erweitert werden, um alles zu tun, was Sie wollen, bevor Sie zur Marke zurückkehren. Wenn Sie mA(oder einen anderen Großbuchstaben) verwenden, ist die Marke tatsächlich für alle Dateien eindeutig, sodass Sie sie vor der Rückkehr sogar an anderer Stelle bearbeiten können. Wenn Sie eine sehr häufige Verwendung haben, können Sie es wie oben vorgeschlagen zu einem Makro machen.

Alex Feinman
quelle
1

Sie können die Anzahl der zu löschenden Zeilen eingeben : j 20 dd k.

Paul Ruane
quelle
Final kbewegt den Cursor über die Anfangszeile. Außerdem geht die Position der Cursorspalte aufgrund von verloren dd.
ib.
@ib: Nicht in meinen Tests. Hast du es tatsächlich versucht? Beachten Sie das anfängliche j .
Paul Ruane
Es tut mir leid, mein erster Punkt war falsch (als ich den Befehl ausprobiert habe, habe ich nicht bemerkt, dass die von mir angegebene Anzahl (in Ihrem Beispiel '20') größer war als die Anzahl der Zeilen bis zum Ende des Puffer). Aber die zweite bleibt: Die Spaltenposition des Cursors ändert sich danach dd(auf das erste nicht leere Zeichen der Zeile neben den gelöschten Zeilen, glaube ich).
ib.
@ib: Ja, ich bin damit einverstanden, dass sich die Spaltenposition ändert.
Paul Ruane
Bitte nehmen Sie eine unbedeutende Änderung Ihrer Antwort vor, damit ich sie positiv bewerten kann. Ich denke, Ihre Antwort verdient doch keinen negativen Rang.
ib.
-1

Nur zum Spaß können Sie eine kleine Funktion definieren, die genau das tut, was Sie beschrieben haben: Löscht die nächsten n Zeilen unter der aktuellen Zeile und stellt die ursprüngliche Cursorposition wieder her.

function! DeleteNextLines(n, reg)
    let l = line('.')
    let m = min([a:n, line('$')-l])
    if m > 0
        let c = col('.')
        exe '+,+'.m 'd' a:reg
        call cursor(l, c)
    endif
endfunction

Sie können auch einen Befehl definieren, der die Anzahl der zu löschenden Zeilen (eine, falls nicht angegeben) und den Registernamen akzeptiert, der als optionales Argument verwendet werden soll (genau wie der :deleteBefehl).

:command! -range=1 -register -bar D call DeleteNextLines(<count>, <q-reg>)

Darüber hinaus können Sie bei Bedarf eine Zuordnung zum Auslösen des obigen :D Befehls definieren .

ib.
quelle
Um beispielsweise ein Komma zuzuordnen, fügen Sie d (drücken Sie ',' gefolgt von d) die folgenden Zeilen ein (nachdem Sie die obige Antwort von @ib eingegeben haben) 1: let mapleader = ","2:nmap <leader>d :D<CR>
Kevin Lee