The reason your example attempts don't work is that in many locations text is simply seen as a literal string, rather than VimScript. So functions, variables, and the like don't work.
For example, if you do:
:let var='value'
:set option=var
Then Vim will simply set the value of option
to the literal value var
, since it doesn't recognize VimScript in :set
. The same applies to :map
and many other locations.
In general, most colon/Ex/:
commands do not evaluate VimScript.
:execute
Not all is lost, since you can still build a string with :execute
:
:let var='value'
:execute ':set option=' . var
The :execute
command executes the given VimScript expression. In this case, we build a string using the variable, and what :execute
sees is :set option=value
.
You can use any Vim expression; some more examples:
" Function return value
:execute 'set option=' . Fun()
" You don't need to use string concatenation; all arguments are
" concatenated automatically. A space is added.
:execute 'edit' var
:execute 'edit' Fun()
map
expands special key sequences like <CR>
. To get them in an execute, you need to prepend the <
with a \
: "\<CR>"
. You need to use double quotes, single quotes won't work:
:let key = 'h'
:execute 'nnoremap ' . key . " :echo 'hello'\<CR>"
Because you're building VimScript code in a VimScript string things tend to look rather ugly. C'est la vie. Depending on your personal tastes, printf()
can make things a bit easier on the eyes:
:execute printf("nnoremap %s :echo 'hello'\<CR>", key)
Note: it's very common to abbreviate :execute
to :exe
.
See :help :execute
for more information.
Expression mappings
Finally, you can use expression mappings to use a Vim expression for the entire right-hand side.
" Execute the contents of the current line as a Vim command.
:nnoremap <expr> f getline('.')
The biggest difference with :execute
is that the expression is run when the key is pressed, and not when the command is defined. So every time you press f
in the above example getline()
gets the value of the current line. If we had used:
:execute ':nnoremap f' getline('.')
Then it would get the value of the line once. So if you had been on the line gg
it would be the same as typing:
:nnoremap f gg
See :help :map-<expr>
for more information.
Interactively and in mappings, the expression register "=
can be used to achieve similar effects. Its usage stands out as
:nnoremap keys :put =Fun()<CR>
or
:inoremap keys <C-r>=Fun()<CR>
:let-&
As a special case with options, you can use
:let &option = 'value'
syntax to have a similar effect as
:execute 'set option='.value