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