Wie kann ich d [count] d zuordnen?

18

NB Dies ist kein Duplikat von Wie funktioniert der Befehl "d3fg"? Bitte lesen Sie es, bevor Sie abstimmen, um zu schließen!

Ich bin in eine Sackgasse geraten, um zu erreichen, dass kleine Löschvorgänge wie große funktionieren . Das Problem, das ich habe, ist, dass ich nicht herausfinden kann, wie Befehle neu zugeordnet werden können d3d. Tatsächlich kann ich nicht einmal verstehen, wie sie überhaupt funktionieren, und ich kann in Vims Hilfe keine Erwähnung finden. *

d3jist einfach: es wendet die dBedienungsperson auf die 3jBewegung an,

3ddist auch einfach: es führt den ddBefehl mit einem "count" von 3 aus.

d3d sieht so aus als sollte es unkompliziert sein, es wendet die dbedienung auf die ... aber was ist das 3d? Es ist keine Bewegung. Wenn Sie 3dalleine tippen , wird dies von Vim als Zählung behandelt, gefolgt von einem Operator, und es wird geduldig auf weitere Eingaben gewartet.

Und Sie können keine Operatoren auf andere Operatoren anwenden. ddwird in der Hilfe nicht als Folge von zwei Operatoren beschrieben. Es ist ein separater Befehl mit zwei Tasten. (vgl dc. was nix macht.)

Es scheint auch nicht der Fall zu sein, dass die Positionierung des Zählers für Befehle flexibel ist, die zwei Tastenanschläge erfordern: 2gjBewegt den Cursor zwei Bildschirmzeilen nach unten, g2jverwirft jedoch die ersten beiden Tastendrücke vollständig und bewegt den Cursor eine Zeile nach unten.

Wie funktioniert es? Ist dies nur ein Sonderfall in Vims internem Code? Kann ich auf irgendeine Weise ein d[count]dMapping erstellen ?

EDIT : Ist es ein Textobjekt? :h text-objectsSchließt es nicht in die Liste der "Befehle zur Auswahl von Textobjekten" ein, aber dann schließt es dd in eine Liste von Löschungen ein, die "von kleinen zu großen Objekten gruppiert" sind. Und d2awlöscht das Wort unter dem Cursor und das folgende. Auf der anderen Seite c2dtut nichts.

* Ich bin sicher, dass einige Erwähnungen existieren müssen, aber ich kann es nicht finden. Ich habe gelesen :help deleting, :help motion.txtund :helpgrep dNdfür alle Werte von N von 1 bis 9 versucht .

Reich
quelle
2
Ich denke, der letzte dwirkt als Bestätigung; So ist es das gleiche wie d3<CR>. y3yund c3cfunktionieren auch gleich ... Ich kann keine Dokumente dazu finden, obwohl entweder in der Vim: help, vi (1), nvi (1) oder der POSIX-Spezifikation ... Es verhält sich in viund nvibtw. gleich .
Martin Tournoij
1
In gewisser Weise ddist identisch mit d_. _Bewegt den Cursor in der ( [count]-1) -ten Zeile nach unten zur ersten nicht leeren Zeile, die jedoch zeilenweise ist. Wenn Sie also mit einem Operator gepaart werden, werden ganze Zeilen bearbeitet. Aus diesem Grund ist es sinnvoll, dass eine Zählung zwischen den beiden ds auftreten kann.
tommcdo

Antworten:

28

Vom Bediener ausstehender Modus

Zwischen einem Operator eingeben (wie d, c, oder gU) und einer Bewegung (wie w, i}, oder /foo<CR>), ist Vim in Operator angemeldeten Modus. Sie können Zuordnungen für erstellen diese mit :omapund :onoremap.

In meinen Beispielen werde ich die Betreiber anhängigen zur Karte dzu w. Dies ist eine zufällige Wahl, weil ich nicht weiß, wofür Sie es eigentlich verwenden wollten.

Erstelle ein Omap

Lassen Sie uns eine Zuordnung für dim Operator-Pending-Modus erstellen . Ich gehe davon aus, dass wir hier VimScript schreiben (wie in Ihrem .vimrc), also werde ich führende :s weglassen .

onoremap d w

Das macht ddhandeln wie dw. Es macht auch d[count]dso d[count]w. Aber ich wette, Sie wollten das Verhalten von dd(dh nicht [count]geliefert) nicht beeinflussen.

Ausdruckszuordnungen

Mit Ausdruckszuordnungen können Sie einen VimScript-Ausdruck auswerten, um die rechte Seite der Zuordnung zu erstellen. Der Ausdruck sollte eine Zeichenfolge ergeben. Ausdruckszuordnungen werden durch das <expr>Schlüsselwort gekennzeichnet.

Vim hat auch einige eingebaute Variablen, die zu verschiedenen Zeiten gefüllt werden und oft während des Mappings nützlich sind. Eine davon ist v:count, welche [count]einem Bediener oder einer Bewegung zugeführt wird.

Lassen Sie uns das alles zusammenfassen. Wenn kein [count]zugeführt wird, v:countwird sein 0. Wir können unser Mapping so einstellen, ddass es nur in diesem Fall verwendet wird.

onoremap <expr> d v:count == 0 ? 'd' : 'w'

Verhält ddsich jetzt wie der Standard (löscht eine Zeile), d[count]dverhält sich aber wie d[count]w. Cool!

Beschränken Sie die Verwendung nach dem dBediener

Sie könnten jedoch etwas bemerken. Jetzt cdverhält sich auch so cw. Dies mag kein Problem sein, aber der Vollständigkeit halber beschränken wir es so, dass es nur nach dem dOperator funktioniert .

Vim hat eine weitere Variable, v:operatordie den zuletzt verwendeten Operator enthält. Lassen Sie uns das auch überprüfen, bevor wir etwas Besonderes tun.

onoremap <expr> d (v:count == 0 \|\| v:operator != 'd') ? 'd' : 'w'

HINWEIS: Da :mapBefehle verkettet werden können |, müssen sie hier in unserem Ausdruck maskiert werden. So ist die logische ODER - Verknüpfung ||wird \|\|.

Cool, also cdund c[count]dwieder nichts zu tun, wie früher. Dies ist gut, damit andere Plugins definieren können cd.

Ich möchte nicht einfach eine andere Bewegung löschen

Wenn Sie d[count]dauf etwas völlig anderes abbilden möchten, das nichts mit dem Löschen von Text zu tun hat, können wir das auch erledigen.

Wenn Sie Befehle im normalen Modus eingeben und versehentlich einen Befehl eingeben, können Sie diesen Befehl durch Drücken <Esc>von abbrechen. Gleiches gilt für Ihre Mappings.

Lassen Sie uns d[count]ddie aktuelle Zeile wie gewünscht ändern [count].

onoremap <expr> d (v:count == 0 \|\| v:operator != 'd') ? 'd' : '<Esc>cc' . v:count . '<Esc>'

Der letzte Teil der Abbildung ist ein VimScript expression: <Esc>cc' . v:count . '<Esc>'. Das heißt <Esc>, Sie müssen den ausstehenden dBefehl abbrechen , dann ccdie aktuelle Zeile ändern, v:countden Wert von [count](im Einfügemodus) eingeben und <Esc>zum normalen Modus zurückkehren. Beachten Sie, dass wir hier eine Zeichenfolge mit dem VimScript-Verkettungsoperator erstellen ..


Ihr tatsächlicher Anwendungsfall wird sich wahrscheinlich von dem unterscheiden, was ich hier skizziert habe, aber dies hilft Ihnen hoffentlich dabei, den Ball ins Rollen zu bringen.

Fröhliches Vimming!

tommcdo
quelle
Gute Antwort! Upvoted. Ich habe zu Beginn der Frage einen Link zu meinem Anwendungsfall (auch auf vi.SE) erstellt, aber Sie müssen ihn übersehen haben. Ich muss im Grunde :omap d d(!) Tun , aber leider wird der Operator-Pending-Modus nie wirklich erreicht, weil ich für d eine Zuordnung vorgenommen habe, mit der die benutzerdefinierte Operatorfunktion festgelegt wird. Hoffentlich ist es möglich, Dinge zu optimieren, damit sie d3dfunktionieren, wie es soll. (Lassen Sie mich wissen, wenn Sie Ideen haben, oder senden Sie eine vollständige Lösung für die andere Frage, wenn Sie dies bevorzugen.) Wenn ich es nicht bald herausfinden kann, werde ich dies akzeptieren und eine weitere, spezifischere Frage stellen. Vielen Dank!
Rich
1
Eigentlich akzeptiere ich das, wenn ich es mir überlege, jetzt. Sie haben sowohl erklärt, wie ein solches Mapping erstellt wird, als auch, wie es unter der Haube funktioniert. Das waren die beiden Dinge, die ich gefragt habe.
Rich