how do I use a variable content as an argument for vim command?

11

3

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.

Vitaly Kushner

Posted 2011-08-08T10:42:30.683

Reputation: 1 360

example command is wrong. it should be let foo='pattern'. Say that :execute is a hack is totally wrong. That's the solution: You want vim to evaluate the command before execute it – albfan – 2018-03-09T19:51:25.757

what is Ggrep (capital G?)? – akira – 2011-08-08T11:30:35.387

git grep from 'fugutive' vim plugin – Vitaly Kushner – 2011-08-09T10:08:04.600

Answers

2

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'.

alexche8

Posted 2011-08-08T10:42:30.683

Reputation: 136

Now try to run echo foo. Opps echo pattern which is not a variable. this is a hack and misguiding. – albfan – 2018-03-09T19:55:32.970

7

what about:

:execute ':grep ' . foo

akira

Posted 2011-08-08T10:42:30.683

Reputation: 52 754

how do I properly escape foo's content? it might contain special characters like ", ', /, , etc – Vitaly Kushner – 2011-08-08T11:34:13.410

1@Vitaly Kushner: See ":help escape()" and ":help fnameescape()". – garyjohn – 2011-08-08T16:45:13.757

I know escape(), but not sure about what characters to escape – Vitaly Kushner – 2011-08-10T13:00:49.857

fnameescape() is not good, its not a filename argument, its an arg to plugin function. suppose I :let foo = "aaa"bbbb'cccc" – Vitaly Kushner – 2011-08-10T13:02:29.947

i think that 'how to escape a regular expression bullet-proof in vim' is another question, either here or on stackoverflow.com. – akira – 2011-08-10T17:52:23.940

not really. what you proposed is a kind of 'eval' expression, which cab work, but once your variable contains anything slightly more interesting then [a-z] it breaks. So the question is still pending: How do you call a plugin function passing variable as an argument. – Vitaly Kushner – 2011-08-13T15:39:04.787

well, read the 'fugitive.vim': call s:command("-bang -nargs=? -complete=customlist,s:EditComplete Ggrep :execute s:Grep(<bang>0,<q-args>)") call s:command("-bar -bang -nargs=* -complete=customlist,s:EditComplete Glog :execute s:Log('grep<bang>',<f-args>)")

they use 'execute' to actually call the function 'Grep' (that's visible only inside that script). otherwise you could use 'call', but since that function is not visible to the global scope: bad luck. either change the script or live with 'the hack'. – akira – 2011-08-13T18:07:57.957

yes, but they run execute with a special expansions like <bang> and <q-args>. – Vitaly Kushner – 2011-08-14T16:12:12.747

<q-args> is actually interesting here. try :h <q-args> :

"If the first two characters of an escape sequence are "q-" (for example, <q-args>) then the value is quoted in such a way as to make it a valid value for use in an expression. This uses the argument as one single value."

so there IS a way to quote stuff when defining a user command. What I'm looking for is the same for when I'm runing :exec, or similar. – Vitaly Kushner – 2011-08-14T16:13:43.760

soo .. building a string to :execute actually is the solution :) – akira – 2011-08-15T08:23:04.167

it might, if it "is quoted in such a way as to make it a valid value for use in an expression" ;). – Vitaly Kushner – 2011-08-15T08:57:04.763

1I am pulling my hair out over this too. You can't issue a command like let xyz = tabpagenr() then tabnext xyz. Vim's scripting language is as flawed as its modal environment is flawless. – puk – 2012-03-01T07:01:39.903

2

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 "=

Heptite

Posted 2011-08-08T10:42:30.683

Reputation: 16 267