Was ist der Unterschied zwischen den Mapping-Befehlen remap
, noremap
, nnoremap
und vnoremap
in Vim?
Antworten
Zu viele Anzeigen?remap
ist eine Option, die Zuordnungen rekursiv arbeiten lässt. Standardmäßig ist sie eingeschaltet und ich würde empfehlen, es dabei zu belassen. Die restlichen sind Zuordnungsbefehle, die unten beschrieben sind:
:map
und :noremap
sind rekursive und nicht-rekursive Versionen der verschiedenen Zuordnungsbefehle. Wenn wir zum Beispiel ausführen:
:map j gg (bewegt den Cursor zur ersten Zeile)
:map Q j (bewegt den Cursor zur ersten Zeile)
:noremap W j (bewegt den Cursor um eine Zeile nach unten)
Dann:
j
wird aufgg
abgebildet.Q
wird auch aufgg
abgebildet, daj
für die rekursive Zuordnung erweitert wird.W
wird aufj
abgebildet (und nicht aufgg
), weilj
für die nicht-rekursive Zuordnung nicht erweitert wird.
Vergessen Sie nicht, dass Vim ein Modus-Editor ist. Es hat einen Normal-Modus, Visual-Modus und andere Modi.
Für jede dieser Zuordnungssätze gibt es eine Zuordnung, die in Normal-, Visual-, Selektions- und Operator-Modi funktioniert (:map
und :noremap
), eine die im Normal-Modus funktioniert (:nmap
und :nnoremap
), eine im Visual-Modus (:vmap
und :vnoremap
) und so weiter.
Für weitere Anleitungen hierzu siehe:
:help :map
:help :noremap
:help recursive_mapping
:help :map-modes
Ich denke, die Vim-Dokumentation sollte die Bedeutung hinter der Benennung dieser Befehle erklärt haben. Nur zu sagen, was sie tun, hilft nicht dabei, sich an die Namen zu erinnern.
map
ist die "Wurzel" aller rekursiven Mapping-Befehle. Die Wurzelform gilt für die Modi "normal", "visual+select" und "operator-pending". (Ich benutze den Begriff "Wurzel" wie in der Linguistik.)
noremap
ist die "Wurzel" aller nicht-rekursiven Mapping-Befehle. Die Wurzelform gilt für die gleichen Modi wie map
. (Denken Sie bei dem nore
-Präfix an "nicht-rekursiv".)
(Beachten Sie, dass es auch die !
Modi wie map!
gibt, die für den Einfüge- & Befehlszeilen-Modus gelten.)
Im Folgenden sehen Sie, was "rekursiv" in diesem Kontext bedeutet.
Ein Voranstellen eines Modus-Buchstabens wie n
ändert die Modi, in denen das Mapping funktioniert. Es kann eine Teilmenge der Liste der anwendbaren Modi auswählen (zum Beispiel nur "visuell"), oder andere Modi wählen, auf die map
nicht zutrifft (zum Beispiel "einfügen").
Die Verwendung von help map-modes
zeigt Ihnen ein paar Tabellen, die erklären, wie gesteuert werden kann, auf welche Modi das Mapping angewendet wird.
Modus-Buchstaben:
n
: nur normalv
: visuell und selektivo
: operator-pendingx
: nur visuells
: nur selektivi
: einfügenc
: Befehlszeilel
: einfügen, Befehlszeile, regexp-suche (und andere. Zusammen als "Lang-Arg" Pseudo-Modus bezeichnet)
"Rekursiv" bedeutet, dass das Mapping zu einem Ergebnis erweitert wird, dann wird das Ergebnis zu einem weiteren Ergebnis erweitert, und so weiter.
Die Expansion endet, wenn eines dieser Dinge wahr ist:
- das Ergebnis ist nicht mehr auf etwas anderes abgebildet.
- ein nicht-rekursives Mapping wurde angewendet (d.h. das "noremap" [oder eines seiner ähnlichen] ist die endgültige Erweiterung).
An diesem Punkt wird die standardmäßige "Bedeutung" des endgültigen Ergebnisses von Vim angewendet/ausgeführt.
"Nicht-rekursiv" bedeutet, dass das Mapping nur einmal erweitert wird und dieses Ergebnis angewendet/ausgeführt wird.
Beispiel:
nmap K H
nnoremap H G
nnoremap G gg
Das oben genannte führt dazu, dass K
zu H
erweitert wird, dann wird H
zu G
erweitert und stoppt. Es stoppt aufgrund des nnoremap
, das sich sofort erweitert und stoppt. Die Bedeutung von G
wird ausgeführt (d.h. "zur letzten Zeile springen"). In einer Erweiterungskette wird höchstens einmal ein nicht-rekursives Mapping angewendet (es wäre die letzte Erweiterung, die passiert).
Das Mapping von G
zu gg
gilt nur, wenn Sie G
drücken, aber nicht, wenn Sie K
drücken. Dieses Mapping wirkt sich nicht darauf aus, K
zu drücken, unabhängig davon, ob G
rekursiv abgebildet wurde oder nicht, da es Zeile 2 ist, die die Erweiterung von K
stoppt, sodass Zeile 3 nicht verwendet wird.
Ein Unterschied ist, dass:
:map
entsprichtnvo
== normal + (visuell + ausgewählt) + Operator ausstehend:map!
entsprichtic
== Einfügen + Befehlszeilenmodus
wie in den help map-modes
Tabellen angegeben.
Also: map
mappt nicht zu allen Modi.
Um zu allen Modi zu mappen, brauchst du sowohl :map
als auch :map!
.
Ich werde Mapping-Befehle einfach erklären.
Zunächst haben wir zwei allgemeine Mapping-Befehle:
map
- funktioniert rekursiv in den Modi normal, visual, select und operator pending.map!
- funktioniert rekursiv in den Modi insert und command-line.
Die nicht-rekursiven Variationen dieser Befehle sind:
noremap
- funktioniert nicht rekursiv in den Modi normal, visual, select und operator pending.noremap!
- funktioniert nicht rekursiv in den Modi insert und command-line.
Dann haben wir modusspezifische Befehle:
nmap
- funktioniert rekursiv im normal Modus.imap
- funktioniert rekursiv im insert Modus.vmap
- funktioniert rekursiv in den Modi visual und select.xmap
- funktioniert rekursiv im visual Modus.smap
- funktioniert rekursiv im select Modus.cmap
- funktioniert rekursiv im command-line Modus.omap
- funktioniert rekursiv im operator pending Modus.
Und ihre nicht-rekursiven Variationen:
nnoremap
- funktioniert nicht rekursiv im normal Modus.inoremap
- funktioniert nicht rekursiv im insert Modus.vnoremap
- funktioniert nicht rekursiv in den Modi visual und select.xnoremap
- funktioniert nicht rekursiv im visual Modus.snoremap
- funktioniert nicht rekursiv im select Modus.cnoremap
- funktioniert nicht rekursiv im command-line Modus.onoremap
- funktioniert nicht rekursiv im operator pending Modus.
Außerdem ist remap
eine boolesche Option, die es ermöglicht, dass Mapping-Befehle rekursiv funktionieren. Es ist erwähnenswert, dass Sie diese Option immer auf dem Standardwert on
belassen sollten.