¿Cuál es la diferencia entre los comandos de mapeo remap, noremap, nnoremap y vnoremap en Vim?
¿ Cuál es la diferencia entre los comandos remap
, y mapeo en Vim?noremap
nnoremap
vnoremap
remap
es una opción que hace que las asignaciones funcionen de forma recursiva. De forma predeterminada, está activado y te recomiendo que lo dejes así. El resto son comandos de mapeo , que se describen a continuación:
:map
y :noremap
son versiones recursivas y no recursivas de los distintos comandos de mapeo. Por ejemplo, si ejecutamos:
:map j gg (moves the cursor to the first line)
:map Q j (moves the cursor to the first line)
:noremap W j (moves the cursor down one line)
Entonces:
j
se asignará agg
.Q
también se asignará agg
, porquej
se expandirá para el mapeo recursivo.W
se asignará aj
(y no agg
) porquej
no se expandirá para el mapeo no recursivo.
Ahora recuerda que Vim es un editor modal . Tiene un modo normal , modo visual y otros modos.
Para cada uno de estos conjuntos de asignaciones, hay una asignación que funciona en los modos normal, visual, de selección y de operador ( :map
y :noremap
), una que funciona en modo normal ( :nmap
y :nnoremap
), otra en modo visual ( :xmap
y :xnoremap
), etc.
Para obtener más orientación sobre esto, consulte:
:help :map
:help :noremap
:help recursive_mapping
:help :map-modes
Creo que la documentación de Vim debería haber explicado el significado detrás de la denominación de estos comandos. Simplemente decirte lo que hacen no te ayuda a recordar los nombres.
map
es la "raíz" de todos los comandos de mapeo recursivo. La forma raíz se aplica a los modos "normal", "visual+selección" y "pendiente del operador". (Estoy usando el término "raíz" como en lingüística ).
noremap
es la "raíz" de todos los comandos de mapeo no recursivos. La forma raíz se aplica a los mismos modos que map
. (Piense en el nore
prefijo como "no recursivo".)
(Tenga en cuenta que también existen !
modos como map!
ese que se aplican a insertar y línea de comandos).
Consulte a continuación lo que significa "recursivo" en este contexto.
Al anteponer una letra de modo, n
se modifican los modos en los que funciona el mapeo. Puede elegir un subconjunto de la lista de modos aplicables (por ejemplo, solo "visual"), o elegir otros modos a los que map
no se aplicaría (por ejemplo, "insertar").
Use help map-modes
le mostrará algunas tablas que explican cómo controlar a qué modos se aplica el mapeo.
Letras de modo:
n
: solo normalv
: visual y seleccionaro
: operador pendientex
: solo visuals
: seleccionar soloi
: insertarc
: línea de comandol
: insertar, línea de comandos, búsqueda de expresiones regulares (y otros. En conjunto se denomina pseudomodo "Lang-Arg")
" Recursivo " significa que el mapeo se expande a un resultado, luego el resultado se expande a otro resultado, y así sucesivamente.
La expansión se detiene cuando se cumple una de estas condiciones:
- el resultado ya no se asigna a nada más.
- se ha aplicado un mapeo no recursivo (es decir, el "noremap" [o uno de su tipo] es la expansión final).
En ese punto, se aplica/ejecuta el "significado" predeterminado de Vim del resultado final.
" No recursivo " significa que el mapeo solo se expande una vez y ese resultado se aplica/ejecuta.
Ejemplo:
nmap K H
nnoremap H G
nnoremap G gg
Lo anterior hace K
que se expanda hasta H
, luego H
se expanda hasta G
y se detenga. Se detiene debido a nnoremap
, que se expande y se detiene inmediatamente. El significado de G
se ejecutará (es decir, "saltar a la última línea"). Como máximo, se aplicará un mapeo no recursivo en una cadena de expansión (sería la última expansión en ocurrir).
La asignación de G
a gg
solo se aplica si presiona G
, pero no si presiona K
. Este mapeo no afecta la presión K
independientemente de si G
se mapeó recursivamente o no, ya que es la línea 2 la que hace que se K
detenga la expansión, por lo que la línea 3 no se usaría.
Explicaré los comandos de mapeo de manera simple.
Primero, tenemos dos comandos de mapeo generales:
map
- Funciona de forma recursiva en los modos normal , visual , de selección y pendiente del operador .map!
- Funciona de forma recursiva en los modos de inserción y línea de comandos .
Las variaciones no recursivas de estos comandos son:
noremap
- Funciona de forma no recursiva en los modos normal , visual , de selección y de operador pendiente .noremap!
- Funciona de forma no recursiva en los modos de inserción y línea de comandos .
Puede considerarlo como no[remap] {lhs} {rhs}
lo que significa asignar la secuencia de teclas {lhs}
a {rhs}
, pero no reasignar ningún comando {rhs}
para evitar asignaciones anidadas y recursivas.
Luego, tenemos comandos específicos del modo:
nmap
- funciona de forma recursiva en modo normal .imap
- funciona de forma recursiva en modo de inserción .vmap
- Funciona de forma recursiva en modos visual y de selección .xmap
- funciona recursivamente en modo visual .smap
- funciona de forma recursiva en modo de selección .cmap
- funciona de forma recursiva en modo de línea de comandos .omap
- Funciona recursivamente en modo pendiente de operador .
Y sus variaciones no recursivas:
nnoremap
- funciona de forma no recursiva en modo normal .inoremap
- funciona de forma no recursiva en modo de inserción .vnoremap
- Funciona de forma no recursiva en modos visual y de selección .xnoremap
- funciona de forma no recursiva en modo visual .snoremap
- funciona de forma no recursiva en modo de selección .cnoremap
- funciona de forma no recursiva en modo de línea de comandos .onoremap
- Funciona de forma no recursiva en modo pendiente de operador .
Finalmente, remap
hay una opción booleana que permite que las asignaciones funcionen de forma recursiva. Cabe mencionar que siempre debes mantener esta opción en su valor predeterminado on
.
Una diferencia es que:
:map
hacenvo
== normal + (visual + seleccionar) + operador pendiente:map!
haceic
== insertar + modo de línea de comando
como se indica en help map-modes
las tablas.
Entonces: map
no se asigna a todos los modos .
Para asignar a todos los modos necesita ambos :map
y :map!
.