how do I use a variable content as an argument for vim command?
for example suppose I did
:let foo=pattern
and now I want to perform Ggrep patter
but use variable foo
instead of the literal patter
string.
:echo foo
outputs pattern
, but
:Ggrep foo
just looks for foo
UPDATE:
building a string of command and then running :execute on it is not a solution, its a hack. And it breaks with any non-trivial variable values.
It's not about variable but maybe vim abbreviate command can helps. Try from command line:
:abbreviate foo pattern
Then
:Ggrep foo<space>
It will complete 'foo' to your 'pattern'.
what about:
:execute ':grep ' . foo
If you don't like the :exe
solution, you can "read" the contents of a variable into to the command line by using the =
expression register. For example, type :Ggrep
then press Ctrl-r and then type =foo
and press Enter. Assuming the variable foo
contained "pattern", your command line should now look like:
:Ggrep pattern
This has the advantage that you can see the actual command that will be run, and even modify it before pressing Enter a second time.
See:
:help "=
As far as I'm aware, there is no option other than :execute
echo "hello"
" same as
let greeting = "hello"
execute "echo '" . greeting . "'"
However, as you've noticed, if the variable contains certain bad characters, that causes an issue:
let greeting = "hel'lo"
execute "echo '" . greeting . "'"
" hel
" E121: Undefined variable: lo
To avoid this, the string variable needs to be escaped properly. This is actually easier than it sounds, using single-quoted strings. Double-quoted strings would be a nightmare, but if you look at :help literal-string
it says:
Note that single quotes are used. This string is taken as it is. No backslashes are removed or have a special meaning. The only exception is that two quotes stand for one quote.
So the only special character is '
, which can be escaped by replacing it with ''
. That can be done with substitute
.
let greeting = "hel'lo"
execute "echo '" . substitute(greeting, "'", "''", 'g') . "'"
" echoes: hel'lo
That's a bit gross looking, so you could move that into a function:
function! EscapeVimStr(str)
return "'" . substitute(a:str, "'", "''", 'g') . "'"
endfunction
let greeting = "hel'lo"
execute 'echo' EscapeVimStr(greeting)
" echoes: hel'lo