Troskyvs
Troskyvs

Reputation: 8047

How to use vimgrep to grep the word that's highlighted by Vim?

Using :vimgrep, inside Vim, in normal mode I can type:

:vimgrep mywords %

to search for "mywords" in the documents below the current directory.

But I wish that in normal mode, when I highlight a word using gd, or in visual mode use viw to select a word, I use a hot key F8 to vimgrep. So I add in my vimrc and restart Vim:

vnoremap <F8> :vimgrep expand('<cword>') %<CR>

This doesn't work for me. I put focus on one word and select it, I press F8, no response in Vim. How can I make it work?

Thanks!

Upvotes: 3

Views: 2369

Answers (2)

Ingo Karkat
Ingo Karkat

Reputation: 172510

Vimscript is evaluated exactly like the Ex commands typed in the : command-line. There were no variables in ex, so there's no way to specify them. When typing a command interactively, you'd probably use <C-R>= to insert variable contents:

:vimgrep <C-R>=expand('<cword>')<CR> '%'<CR>

... but in a script, :execute must be used. All the literal parts of the Ex command must be quoted (single or double quotes), and then concatenated with the variables:

execute 'vimgrep' expand('<cword>') '%'

Actually, there's a built-in command for inserting the current word into the command-line: :help c_CTRL-R_CTRL-W:

:vimgrep <C-R><C-W>

Your mapping

You could use all three approaches; let's use the last:

vnoremap <F8> :<C-u>vimgrep <C-r><C-w> %<CR>

The <C-u> clears the '<,'> range that is automatically inserted.

What you probably wanted

Using the current word from visual mode is strange. You probably wanted to search for the current selection. There's no expand() for that. Easiest is to yank, as outlined by @ryuichiro's answer:

vnoremap <F8> y:vimgrep /<C-r>"/ %<CR>

Still missing is escaping of the literal text (:vimgrep searches for a regular expression pattern), and of the / delimiter:

vnoremap <F8> y:execute 'vimgrep /\V' . escape(@@, '/\') . '/ %'<CR>

Robust plugin solution

Now, if you also want to avoid the clobbering of the default register, it gets really complicated. Have a look at my GrepHere plugin; it provides a {Visual}<A-M> mapping for exactly that.

Upvotes: 6

ryuichiro
ryuichiro

Reputation: 3865

Try

vnoremap <F8> y:vimgrep "<c-r>"" %<CR> 

Recommended reading: Mapping keys in Vim - Tutorial (Part 1)

Upvotes: 1

Related Questions