Qual é a diferença entre os comandos de mapeamento remapear, noremap, nnoremap e vnoremap no Vim?

1114

Qual é a diferença entre as remap, noremap, nnoremape vnoremapcomandos de mapeamento no vim?

Chetan
fonte
1
Cuidado vnoremape vmaptrabalhe no modo Visual AND Select. Para ter um mapeamento apenas no modo Visual, use xmape xnoremap.
Benoit

Respostas:

1628

remapé uma opção que faz com que os mapeamentos funcionem recursivamente. Por padrão, está ativado e eu recomendo que você deixe assim. O restante são comandos de mapeamento , descritos abaixo:

:mape :noremapsão versões recursivas e não recursivas dos vários comandos de mapeamento. O que isso significa é que, se você fizer:

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

jserá mapeado para gg. Qirá também ser mapeados para gg, porque jvai ser expandido para o mapeamento recursiva. Wserá mapeado para j(e não para gg) porque jnão será expandido para o mapeamento não recursivo.

Agora lembre-se de que o Vim é um editor modal . Tem um modo normal , modo visual e outros modos.

Para cada um desses conjuntos de mapeamentos, existe um mapeamento que funciona nos modos normal, visual, de seleção e operador ( :mape :noremap), um que funciona no modo normal ( :nmape :nnoremap), outro no modo visual ( :vmape :vnoremap) e assim por diante.

Para mais orientação sobre isso, consulte:

:help :map
:help :noremap
:help recursive_mapping
:help :map-modes
DrAl
fonte
8
Obrigado pela sua resposta! Além disso, quando é usado recursivo e quando não-recursivo?
Chetan
14
@Chetan: Depende do que você deseja alcançar. Eu costumo usar não recursivo com mais frequência, mas se você definiu um mapeamento relativamente complicado usando não recursivo e que outro mapeamento faz tudo o que o primeiro mapeamento faz e mais, pode ser mais fácil usar um mapeamento recursivo que inclua o original em vez de redigitar todo o não recursivo novamente (principalmente se você precisar ajustar o original).
DrAl
10
Eu tinha assumido noremapser um oposto de map. Quero dizer algo que remove um mapeamento. Obrigado pela resposta. Ele me esclareceu
Pavan Manjunath
4
Não é tão importante para a maioria dos casos de uso, mas deve-se observar que :mapetc. não funcionam em todos os modos, exatamente, apenas nos comuns (especificamente, modo normal, modo visual, modo de seleção e pendente do operador). Se você deseja que um mapeamento funcione nos modos de inserção, linha de comando ou lang-arg, é necessário usá-lo :map!etc. (Fonte: vimdoc.sourceforge.net/htmldoc/map.html#map-overview )
Ken Bellows
3
@whytheq noremap = mapeamento não-recursiva
Dan Bechard
281

Eu acho que a documentação do Vim deveria ter explicado o significado por trás da nomeação desses comandos. Apenas dizer o que eles fazem não ajuda a lembrar os nomes.

mapé a "raiz" de todos os comandos de mapeamento recursivo. O formato raiz se aplica aos modos "normal", "visual + selecionar" e "pendente de operador". (Estou usando o termo "raiz" como na linguística .)

noremapé a "raiz" de todos os comandos de mapeamento não recursivos. O formulário raiz se aplica aos mesmos modos que map. (Pense no noreprefixo como "não recursivo".)

(Observe que também existem os !modos map!aplicáveis ​​à inserção e linha de comando.)

Veja abaixo o que "recursivo" significa neste contexto.

Anexar uma letra de modo como nmodificar os modos nos quais o mapeamento funciona. Ele pode escolher um subconjunto da lista de modos aplicáveis ​​(por exemplo, apenas "visual") ou escolher outros modos que mapnão se aplicariam (por exemplo, "inserir").

O uso help map-modesmostrará algumas tabelas que explicam como controlar a quais modos o mapeamento se aplica.

Letras de modo:

  • n: apenas normal
  • v: visual e selecione
  • o: operador pendente
  • x: apenas visual
  • s: selecione apenas
  • i: inserir
  • c: linha de comando
  • l: inserção, linha de comando, pesquisa de expressão regular (e outros. Coletivamente chamados pseudo-modo "Lang-Arg")

" Recursivo " significa que o mapeamento é expandido para um resultado, depois o resultado é expandido para outro resultado e assim por diante.

A expansão é interrompida quando uma delas é verdadeira:

  1. o resultado não é mais mapeado para mais nada.
  2. um mapeamento não recursivo foi aplicado (ou seja, o "noremap" [ou um de seus tipos] é a expansão final).

Nesse ponto, o "significado" padrão do Vim do resultado final é aplicado / executado.

" Não recursivo " significa que o mapeamento é expandido apenas uma vez e esse resultado é aplicado / executado.

Exemplo:

 nmap K H
 nnoremap H G
 nnoremap G gg

As causas acima Kse expandem para H, depois Hse expandem para Ge param. Para por causa de nnoremap, que expande e para imediatamente. O significado de Gserá executado (ou seja, "pule para a última linha"). No máximo, um mapeamento não recursivo será aplicado em uma cadeia de expansão (seria a última expansão a ocorrer).

O mapeamento de Gpara ggsomente se aplica se você pressionar G, mas não se pressionar K. Esse mapeamento não afeta a pressão, Kindependentemente de ter Gsido mapeado recursivamente ou não, pois é a linha 2 que faz com que a expansão Kpare, portanto, a linha 3 não seria usada.

Kelvin
fonte
4
Uma coisa: mapaplica-se apenas aos modos normal, visual, de seleção e pendente do operador, e não a todos os modos.
precisa saber é o seguinte
1
deve ser aceita resposta.
Tycholiz 17/03
esta é uma resposta muito melhor do que a aceita.
MilMike
19

Uma diferença é que:

  • :map faz nvo== normal + (visual + selecionar) + operador pendente
  • :map!faz ic == inserir + modo de linha de comando

como indicado nas help map-modestabelas.

Então: mapnão mapeia para todos os modos .

Para mapear para todos os modos, você precisa de ambos :mape :map!.

Ciro Santilli adicionou uma nova foto
fonte
5
Cuidado !! command modeé outro nome histórico para normal modeviz. capítulo 5 vimdoc.sourceforge.net/htmldoc/intro.html#vim-modes-intro ). A abreviação 'c' é para 'linha de comando'. Em outras palavras, por padrão: mapeia map! lhs rhs recursivamente lhs para rhs para os modos insert + command-LINE . Isto é, a menos que a remapopção padrão seja explicitamente desabilitada com set noremap[!]~ / .vimrc. Nesse caso, o mapeamento não seria recursivo (não recomendável).
Cbhihe 15/08/15