2

Suppose I have a variable

let g:f_themes="./themes/**"

Suppose I want to map this command to a key:

:execute "vimgrep /".expand("<cword>")."/g ".g:f_themes." | copen"

That works, even though it may complain about not finding <cword>. I can deal with that.

But what if I want to instead place that string onto the command line and NOT execute it, which allows me to inspect and edit the command before hitting <cr>. I can't use :execute because it will go ahead and execute. And I can't get the value of g:f_themes to expand to ./themes/** if I just type the command without the :execute.

Is there a way to place a string onto the command line so that a simple <cr> would go ahead and execute the line?

1

You can insert the evaluations of expressions into the command-line (or a buffer) with the expression register, by pressing Ctrl-R=. You can also use this in a mapping:

nnoremap <leader>gt :vimgrep /<C-R>=expand("<cword>")<CR>/g <C-R>=g:f_themes<CR> <bar> copen

See :help quote_= for more details on the expression register and :help c_CTRL-R for specific notes on using it in command-line mode.

EDIT: You mention in a comment that you'd like to be able to do this without any mapping being involved. You can use feedkeys() for this:

:call feedkeys(':vimgrep /' . expand("<cword>") . '/g ' . g:f_themes . ' | copen')

This can be run from the command-line, or directly within a function (that has not been invoked by a mapping).

  • This is good stuff. I didn't know about feedkeys(). By the way, this technique seems to be a good way to do specific greps. – BSM Aug 2 '18 at 22:25
0

I think I got part of the answer: how to map a key to do this.

First, declare this one-line function (1):

exe "function! Temp(cword) \n return ':vimgrep /'.a:cword.'/ '.g:f_themes.' | copen' \n endfunction"

Then do this key mapping (2):

:nnoremap <expr> <Leader>gt ':'.Temp(expand("<cword>"))

It puts this on the command line:

:vimgrep /mycword/ ./themes/** | copen

Just what I wanted.

A couple of points: (1): You can't use bars (|) to separate lines in a compressed function. (2): You need <expr>. Learn something new every day. You need to quote the :. You need to use expand(). Or it won't work. I don't know if Temp() could directly refer to <cword>.

But now there is another question. What if one wanted to pump the command line directly from a function. Is it possible to do that?

  • 1: I just used :execute to make the function a one-liner. 2: Note that I was using a key map that took the return value of a function and pumped the command line with that. What I was wondering about was the ability to pump the command line directly from within a function, without having any key mapping involved. – BSM Aug 2 '18 at 21:12
  • Just out of curiosity, I wondering how a :call Whatever() type command could pump the command line, or if it could. – BSM Aug 2 '18 at 22:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.