3 kinds of <xxxx>
"\<xxxx>"
'<xxxx>'
<xxxx>
Let's see "\<xxxx>"
first, :h string says:
`\<xxx> Special key named "xxx". e.g. "\<C-W>" for CTRL-W.`
...
It's an expression, it's a string, a literal string for keycode, let's see it's relation ship with literal terminal keycode on my xterm-256color
:
echo "\a"
output a
, it's the same as terminal literal keycode
echo "\b"
output b
, it's the same as terminal literal keycode
...
echo "\<space>"
output
, it's the same as terminal literal keycode
echo "\<c-a>"
output ^a
, it's the same as terminal literal keycode
echo "\<c-b>"
output ^b
, it's the same as terminal literal keycode
...
echo "\<c-right>"
output <80><fd>V
, it's not the same as terminal literal keycode
echo "\<c-left>"
output <80><fd>U
, it's not the same as terminal literal keycode
echo "\<f5>"
output <80>k5
, it's not the same as terminal literal keycode
echo "\<f6>"
output <80>k6
, it's not the same as terminal literal keycode
...
So i believe "\<xxxx>"
is vim's internal keycode for keys, it's the same as terminal literal keycode if it doesn't starts with 0x80
.
Now let's see '<xxxx>'
, it's the same as "<xxxx>"
, it's an expression, it's a string, and that's it, there is nothing special about this string.
Now let's see <xxxx>
, it's not an expression, it's also not a string, it's nothing by itself, it has to be used with command like map
.
Map and all kinds of <xxxx>
Definition of map
without <expr>
is:
Map the key sequence {lhs} to {rhs} for the modes where the map command applies.
It's key sequence, it works like you are typing it, remember that, it's very important.
:h keycodes says <xxxx>
can be used with :h :map command, e.g.
inoremap <down> <esc>
Above command map <down>
to <esc>
in insert mode, map
family command is smart, they interpret <xxxx>
style keycode as vim's internal keycode for special keys. Now turn on :h 'showcmd' , let's see another example:
inoremap '<down>' '<esc>'
Type 'down arrow' quickly in insert mode, you should see a single '
, and you are back to normal mode
, there should be a '
in right bottom of of your screen. Let's break it down: after you hit 'down arrow' in insert mode, the map triggered, it's result is '<esc>'
, remember that map without <expr>
works like you are typing it, so you type ' esc, vim return to normal mode, the last ' won't be discarded, it waits for you to enter a mark lonely in the right bottom.
Another purpose of this example is to show you that map
without <expr>
knows nothing about expression
, when it saw <xxxx>
, it knows it should be interpreted as special key code, it doesn't care if it's surrounded by '
or "
.
The <c-r>=
Let's see some wrong examples first, assume you want to map <c-x>
to <esc>
in insert mode:
inoremap <c-x> <c-r>='<esc>'<cr>
It won't work, because map
without <expr>
works like you are typing it, nothing good will happen if you type <esc>
in the middle of a string. Continue:
inoremap <c-x> <c-r>="\<esc>"<cr>
This won't work too, "<xxxx>" doesn't have chance to do their job, for the same reason as above. In this case you must prevent vim from interpreting <esc>
as key code:
inoremap <c-x> <c-r>="\<lt>esc>"<cr>
<lt>
is special keycode for <
, so after map
special keycode interpretation, "\<lt>esc>"
becomes "\<esc>"
, which is literal keycode for esc.
The <expr>
"\<lt>esc>"
is super ugly, :h :map-expression is much easier to work with, you provide an expression to map <expr>
, it's evaluated result will be used as {rhs}
for map
, the result is key sequence, the expression is not:
inoremap <expr> <c-x> '<esc>'
It's simple and beautiful. Don't miss the quote, both '<xxxx>'
and "<xxxx>"
work here. Note that map
still interpret <xxxx>
as special keycode, this rule won't change, never change, but only for <xxxx>
on the command, not for the result of the expression.
Let's use another example to explain that. Sometimes you want to use function as an expression:
inoremap <c-x> GetEsc()
function! GetEsc()
return "<esc>"
endfunction
Result of GetEsc()
is "<esc>"
, you hope that map
knows it's a special keycode. it won't work, map
recognize <xxxx>
as special keycode only if it's typed in the command directly, not for the expression result. The right form is:
inoremap <c-x> GetEsc()
function! GetEsc()
return "\<esc>"
endfunction
map
commands parse/guess the keynames specifically, therefore, they translate literal<keys>
to the right form and you do not need the special form"\<key>"