¿Cuál es la diferencia entre los comandos de mapeo remap, noremap, nnoremap y vnoremap en Vim?

1114

¿Cuál es la diferencia entre los remap, noremap, nnoremapy vnoremaplos comandos de asignación en Vim?

Chetan
fuente
1
Precaución, vnoremapy vmaptrabaje en modo Visual AND Select. Para tener una asignación solo en modo Visual, use xmapy xnoremap.
Benoit

Respuestas:

1628

remapes una opción que hace que las asignaciones funcionen de forma recursiva. Por defecto está activado y le recomiendo que lo deje así. El resto son comandos de mapeo , que se describen a continuación:

:mapy :noremapson versiones recursivas y no recursivas de los diversos comandos de mapeo. Lo que eso significa es que si haces:

:map j gg
:map Q j
:noremap W j

jserá asignado a gg. Qserá también ser asignada a gg, porque jserá ampliado para la asignación recursiva. Wse asignará a j(y no a gg) porque jno se expandirá para la asignación no recursiva.

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 modo normal, visual, de selección y de operador ( :mapy :noremap), una que funciona en modo normal ( :nmapy :nnoremap), otra en modo visual ( :vmapy :vnoremap) y así sucesivamente.

Para obtener más orientación sobre esto, consulte:

:help :map
:help :noremap
:help recursive_mapping
:help :map-modes
DrAl
fuente
8
¡Gracias por tu respuesta! Además, ¿cuándo se usa recursivo y cuándo se usa no recursivo?
Chetan
14
@Chetan: Depende de lo que quieras lograr. Tiendo a usar no recursivo con más frecuencia, pero si ha definido un mapeo relativamente complicado usando no recursivo y qué otro mapeo hace todo lo que hace el primer mapeo y más, puede ser más fácil usar un mapeo recursivo que incluya el original en lugar de volver a escribir todo el no recursivo nuevamente (especialmente si necesita ajustar el original).
DrAl
10
Supuse noremapque era algo opuesto a map. Me refiero a algo que elimina un mapeo. Gracias por la respuesta. Me aclaró
Pavan Manjunath
44
No es tan importante para la mayoría de los casos de uso, pero debe tenerse en cuenta que :map, etc., no funcionan en todos los modos, exactamente, solo en todos los comunes (específicamente, modo normal, modo visual, modo de selección y modo de operador pendiente). Si desea que una asignación funcione en modo de inserción, línea de comandos o lang-arg, debe usar :map!, etc. (Fuente: vimdoc.sourceforge.net/htmldoc/map.html#map-overview )
Ken Bellows
3
@whytheq noremap = mapeo no recursivo
Dan Bechard
281

Creo que la documentación de Vim debería haber explicado el significado detrás de la denominación de estos comandos. Solo decirte lo que hacen no te ayuda a recordar los nombres.

mapes la "raíz" de todos los comandos de mapeo recursivo. La forma raíz se aplica a los modos "normal", "visual + select" y "pendiente de operador". (Estoy usando el término "raíz" como en lingüística ).

noremapes 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 noreprefijo que significa "no recursivo").

(Tenga en cuenta que también existen !modos como los map!que se aplican a insertar y línea de comandos).

Vea a continuación lo que significa "recursivo" en este contexto.

Anteponiendo una letra de modo como nmodificar los modos en los que funciona la asignación. Puede elegir un subconjunto de la lista de modos aplicables (por ejemplo, solo "visual"), o elegir otros modos que mapno se apliquen (por ejemplo, "insertar").

Use help map-modesle mostrará algunas tablas que explican cómo controlar a qué modos se aplica la asignación.

Letras de modo:

  • n: normal solamente
  • v: visual y select
  • o: pendiente de operador
  • x: solo visual
  • s: seleccionar solo
  • i: insertar
  • c: línea de comando
  • l: insert, command-line, regexp-search (y otros. Colectivamente llamado pseudo-modo "Lang-Arg")

" Recursivo " significa que la asignación se expande a un resultado, luego el resultado se expande a otro resultado, y así sucesivamente.

La expansión se detiene cuando uno de estos es cierto:

  1. el resultado ya no se asigna a otra cosa.
  2. se ha aplicado un mapeo no recursivo (es decir, el "noremap" [o uno de sus tipos] es la expansión final).

En ese punto, se aplica / ejecuta el "significado" predeterminado de Vim del resultado final.

" No recursivo " significa que la asignación solo se expande una vez, y ese resultado se aplica / ejecuta.

Ejemplo:

 nmap K H
 nnoremap H G
 nnoremap G gg

Lo anterior hace Kque se expanda H, luego se Hexpanda Gy se detenga. Se detiene debido a nnoremapque se expande y se detiene inmediatamente. Se Gejecutará el significado de (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 Ga ggsolo se aplica si presiona G, pero no si presiona K. Este mapeo no afecta la presión Kindependientemente de si Gse mapeó recursivamente o no, ya que es la línea 2 la que Kdetiene la expansión , por lo que la línea 3 no se usaría.

Kelvin
fuente
44
Una cosa: mapsolo se aplica a los modos normales, visuales, selectivos y pendientes del operador, no a todos los modos.
Brian McCutchon
1
Se debe aceptar la respuesta.
Tycholiz
Esta es una respuesta mucho mejor que la aceptada.
MilMike
19

Una diferencia es que:

  • :map does nvo== normal + (visual + select) + operador pendiente
  • :map!does ic == insert + modo de línea de comando

como se indica en las help map-modestablas.

Entonces: mapno se asigna a todos los modos .

Para asignar a todos los modos necesitas ambos :mapy :map!.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
55
Cuidado !! command modees otro nombre histórico para normal modeviz. Capítulo 5 vimdoc.sourceforge.net/htmldoc/intro.html#vim-modes-intro ). La abreviatura 'c' es para 'línea de comandos'. En otras palabras, por defecto: asigna map! lhs rhs recursivamente lhs a rhs para insertar + modos de LÍNEA de comandos . Eso es a menos que la remapopción predeterminada esté explícitamente deshabilitada con set noremap[!]~ / .vimrc. En ese caso, el mapeo no sería recursivo (no recomendable).
Cbhihe