What is the difference between the remap
, noremap
, nnoremap
and vnoremap
mapping commands in Vim?
vnoremap
and vmap
work in Visual AND Select mode. To have a mapping only in Visual mode, use xmap
and xnoremap
.
remap
is an option that makes mappings work recursively. By default it is on and I'd recommend you leave it that way. The rest are mapping commands, described below:
:map
and :noremap
are recursive and non-recursive versions of the various mapping commands. For example, if we run:
:map j gg (moves cursor to first line)
:map Q j (moves cursor to first line)
:noremap W j (moves cursor down one line)
Then:
j will be mapped to gg.
Q will also be mapped to gg, because j will be expanded for the recursive mapping.
W will be mapped to j (and not to gg) because j will not be expanded for the non-recursive mapping.
Now remember that Vim is a modal editor. It has a normal mode, visual mode and other modes.
For each of these sets of mappings, there is a mapping that works in normal, visual, select and operator modes (:map
and :noremap
), one that works in normal mode (:nmap
and :nnoremap
), one in visual mode (:vmap
and :vnoremap
) and so on.
For more guidance on this, see:
:help :map
:help :noremap
:help recursive_mapping
:help :map-modes
I think the Vim documentation should've explained the meaning behind the naming of these commands. Just telling you what they do doesn't help you remember the names.
map
is the "root" of all recursive mapping commands. The root form applies to "normal", "visual+select", and "operator-pending" modes. (I'm using the term "root" as in linguistics.)
noremap
is the "root" of all non-recursive mapping commands. The root form applies to the same modes as map
. (Think of the nore
prefix to mean "non-recursive".)
(Note that there are also the !
modes like map!
that apply to insert & command-line.)
See below for what "recursive" means in this context.
Prepending a mode letter like n
modify the modes the mapping works in. It can choose a subset of the list of applicable modes (e.g. only "visual"), or choose other modes that map
wouldn't apply to (e.g. "insert").
Use help map-modes
will show you a few tables that explain how to control which modes the mapping applies to.
Mode letters:
n: normal only
v: visual and select
o: operator-pending
x: visual only
s: select only
i: insert
c: command-line
l: insert, command-line, regexp-search (and others. Collectively called "Lang-Arg" pseudo-mode)
"Recursive" means that the mapping is expanded to a result, then the result is expanded to another result, and so on.
The expansion stops when one of these is true:
the result is no longer mapped to anything else. a non-recursive mapping has been applied (i.e. the "noremap" [or one of its ilk] is the final expansion).
At that point, Vim's default "meaning" of the final result is applied/executed.
"Non-recursive" means the mapping is only expanded once, and that result is applied/executed.
Example:
nmap K H
nnoremap H G
nnoremap G gg
The above causes K
to expand to H
, then H
to expand to G
and stop. It stops because of the nnoremap
, which expands and stops immediately. The meaning of G
will be executed (i.e. "jump to last line"). At most one non-recursive mapping will ever be applied in an expansion chain (it would be the last expansion to happen).
The mapping of G
to gg
only applies if you press G
, but not if you press K
. This mapping doesn't affect pressing K
regardless of whether G
was mapped recursively or not, since it's line 2 that causes the expansion of K
to stop, so line 3 wouldn't be used.
map
only applies to normal, visual, select, and operator-pending modes, not to all modes.
One difference is that:
:map does nvo == normal + (visual + select) + operator pending
:map! does ic == insert + command-line mode
as stated on help map-modes
tables.
So: map
does not map to all modes.
To map to all modes you need both :map
and :map!
.
command mode
is another historical name for normal mode
viz. chapt 5 vimdoc.sourceforge.net/htmldoc/intro.html#vim-modes-intro). The abbreviation 'c' is for 'command-line'. In other words, by default: map! lhs rhs
recursively maps lhs to rhs for insert + command-LINE modes. That is unless the remap
default option is explicitely disabled with set noremap[!]
in ~/.vimrc. In that case mapping would not be recursive (not advisable).
I will explain mapping commands simply.
First, we have two general mapping commands:
map - works recursively in normal, visual, select and operator pending modes.
map! - works recursively in insert and command-line modes.
The non-recursive variations of these commands are:
noremap - works non-recursively in normal, visual, select and operator pending modes.
noremap! - works non-recursively in insert and command-line modes.
Then, we have mode-specific commands:
nmap - works recursively in normal mode.
imap - works recursively in insert mode.
vmap - works recursively in visual and select modes.
xmap - works recursively in visual mode.
smap - works recursively in select mode.
cmap - works recursively in command-line mode.
omap - works recursively in operator pending mode.
And their non-recursive variations:
nnoremap - works non-recursively in normal mode.
inoremap - works non-recursively in insert mode.
vnoremap - works non-recursively in visual and select modes.
xnoremap - works non-recursively in visual mode.
snoremap - works non-recursively in select mode.
cnoremap - works non-recursively in command-line mode.
onoremap - works non-recursively in operator pending mode.
Finally, remap
is a boolean option that allows for mappings to work recursively. It is worth mentioning that you should always keep this option at the default on
.
no[remap] {lhs} {rhs}
which means to map the key sequence {lhs}
to {rhs}
, but do not re-map any commands in {rhs}
to avoid nested and recursive mappings.
noremap
and noremap!
. I was wondering exactly the same thing as Janac Meena. (I think I might have the ability to make the edit, but I don't want to add something new to someone else's answer.)
Success story sharing
noremap
to be some opposite ofmap
. I mean something which removes a mapping. Thanks for the answer. It clarified me:map
, etc. don't work in all modes, exactly, just all the common ones (specifically, normal mode, visual mode, select mode, and operator-pending mode). If you want a mapping to work in insert, command-line, or lang-arg mode, you need to use:map!
, etc. (Source: vimdoc.sourceforge.net/htmldoc/map.html#map-overview)