Quais são as diferenças entre os comandos map, noremap, abbrev e noreabbrev?

19

Esses comandos transformam um conjunto de pressionamentos de tecla em outro de alguma forma, mas estou um pouco confuso sobre qual é o mais apropriado para alguma situação. Além disso, existem as !variantes deles também. No momento, meu uso deles é bastante casual, então eu poderia saber quais são as armadilhas associadas a cada um? Em particular, notas sobre as várias versões de modo podem ser úteis, pois aprendi com Peter Rincker em um comentário que cmappode se expandir praticamente em qualquer lugar da linha e não apenas quando estou usando :comandos. Que precauções posso tomar contra possíveis armadilhas?

muru
fonte
A próxima parte é um pouco meta: que formulário devemos usar ao responder neste site? - devo perguntar isso no Meta ou adicioná-lo à pergunta?
muru
Eu diria que depende. Eu sempre usaria a versão noremap se demonstrasse um mapeamento. Dessa forma, as pessoas adquirem o hábito de usar os mapeamentos não recursivos sobre as versões recursivas. A menos, é claro, que haja um motivo para usar o mapa especificamente, por exemplo, em um mapeamento <Plug>.
akshay

Respostas:

21

Primeiro, mape noremapsão semelhantes, pois cada um cria mapeamentos para os modos normal, visual, de seleção e de operador pendente simultaneamente . O Vim detalha isso em :help map-overview:

Overview of which map command works in which mode.  More details below.
     COMMANDS                    MODES ~
:map   :noremap  :unmap     Normal, Visual, Select, Operator-pending
:nmap  :nnoremap :nunmap    Normal
:vmap  :vnoremap :vunmap    Visual and Select
:smap  :snoremap :sunmap    Select
:xmap  :xnoremap :xunmap    Visual
:omap  :onoremap :ounmap    Operator-pending
:map!  :noremap! :unmap!    Insert and Command-line
:imap  :inoremap :iunmap    Insert
:lmap  :lnoremap :lunmap    Insert, Command-line, Lang-Arg
:cmap  :cnoremap :cunmap    Command-line

De acordo com a ajuda acima, se você deseja restringir o mapeamento a um modo específico, você deve acrescentar:

'n' (para normal), 'v' (para visual e select), 'c' (para comando), 'x' (para modo visual), 's' (para select), 'o' (para operador pendente )

Por exemplo,

nmap n nzz

criará um modo normal, mapeamento recursivo de n.

Agora, noremapé apenas uma versão não recursiva do map.

Então, o que é mapeamento não recursivo? O Vim também tem a resposta, com :help map-recursive:

If you include the {lhs} in the {rhs} you have a recursive mapping.  When
{lhs} is typed, it will be replaced with {rhs}.  When the {lhs} which is
included in {rhs} is encountered it will be replaced with {rhs}, and so on.
This makes it possible to repeat a command an infinite number of times.  The
only problem is that the only way to stop this is by causing an error.  The
macros to solve a maze uses this, look there for an example.  There is one
exception: If the {rhs} starts with {lhs}, the first character is not mapped
again (this is Vi compatible).
For example: >
   :map ab abcd
will execute the "a" command and insert "bcd" in the text.  The "ab" in the
{rhs} will not be mapped again.

Um exemplo disso é o mapeamento do seguinte:

:imap j k

:imap k j

Agora, o vim substituirá j por k ek por j número infinito de vezes e, portanto, mostrará um erro de que você criou um mapeamento recursivo.

É por isso que geralmente é recomendável que você quase sempre (exceto quando tiver <Plug>mapeamentos ou similares) use mapeamentos não recursivos. Isso evita que o Vim seja interrompido quando você cria inadvertidamente mapeamentos recursivos. O mapeamento não recursivo é, portanto, uma maneira mais segura de mapear comandos no Vim.

Com as informações acima em mãos, podemos ver que :noreabbrevé apenas uma versão não recursiva do :abbrevcomando.

Você pode usar :abbrevapenas nos modos de inserção, substituição e comando. :abbrevé usado para criar abreviações (também conhecidas como atalhos que o Vim pode expandir). A pequena expansão é usar :map/ :noremappara criar mapeamentos, :abbrev/ :noreabbrevpara criar abreviações, ou sempre que você desejar que o Vim expanda sua digitação.

akshay
fonte
1
Evitar travamentos não é o único motivo para usar os noreformulários do comando map. Outra (e na minha opinião, mais importante) razão para usá-los é que eles tornam seus mapeamentos confiáveis ​​/ previsíveis. Se você usar o formulário simples e o rhscontiver uma chave que por acaso seja mapeada para outra coisa, seu mapeamento poderá ter um comportamento totalmente diferente do pretendido.
Rich