Let's say I've got the word foo
in a file, I copy it in register a
("ayiw
) and I define the following mapping:
inoremap <expr> <F3> "<C-r>a"
If I hit F3
while in insert mode it will paste the content of register a
(foo
).
Now, let's say I define the following function, and the following mapping:
function! SomeFunction()
return "<C-R>a"
endfunction
inoremap <expr> <F3> SomeFunction()
When I hit F3
, instead of inserting the a
register (foo
), it inserts literally <C-R>a
.
I found a solution, which involves changing the function and using the unicode for <C-R>
.
I think u12
is the unicode for the control character <C-R>
, because when you insert it literally (<C-V><C-R>
) and you hit ga
on it, the output is <^R> 18, Hex 12, Octal 022
.
So the following function and mapping works:
function! SomeFunction()
return "\u12" . 'a'
endfunction
inoremap <expr> <F3> SomeFunction()
When I hit F3
it inserts the content of the a
register as expected.
But why do I have to use unicode when the control character is returned by a function instead of being directly passed as an argument to :inoremap
?
Edit: After reading Christian Brabandt's answer, I've realised that my solution was too complex.
As he has well explained, no need of unicode, a control character must simply be escaped in a string, so the proper way to write the function would be:
function! SomeFunction()
return "\<C-R>a"
endfunction
And yet I'm still confused, if I type:
inoremap <expr> <F3> "<C-r>a"
It works as expected. So why do I need to escape <C-r>
inside the function but not when it's directly passed as an argument to :inoremap
?
For that, I think I have an explanation. The Ex commands which define a mapping like :inoremap
, :nnoremap
... don't need the control characters to be escaped. For example, you don't write:
nnoremap \<F3> :call SomeFunction\<cr>
but
nnoremap <F3> :call SomeFunction<cr>
Why? Probably because these commands are special, they already interpret correctly <cr>
as a carriage return and not as 4 literal characters (same thing for <F3>
).
So, going back to my previous function, why do I need to escape <C-r>
?
Because, when I hit <F3>
, :inoremap
evaluates the right-hand-side of the mapping as a call to the function SomeFunction()
... and that's it. It doesn't interpret anything after that, it just types the output literally.
The output of SomeFunction()
is not interpreted by :inoremap
, so this time you have to escape the control character so that Vim (not :inoremap
) interprets \<C-r>
as Ctrl + r.