1

I'm trying to write a vim-script function, which allows me to grep the word under cursor easily in my project.

function! CustomGrep()
    vimgrep expand("<cword>") **/*.h **/*.hpp **/*.c **/*.cpp
endfunction

However, when I executed :call CustomGrep() in my vim, I got an error:

E480: No match: expand("<cword>")

Did I do something wrong here?

2

You can just use <cword> directly here:

function! CustomGrep()
    vimgrep <cword> **/*.h **/*.hpp **/*.c **/*.cpp
endfunction

If you look up :help <cword> you'll see it's on a section about "Ex special characters", which also cover special characters you might be familiar with, such as % and # (as in, :e #, to edit the alternate buffer.)

That section also mentions (a little above <cword>) that:

These can also be used in the expression function expand().

In other words, they're primarily meant to be used directly in Ex commands, and only available through expand() for the cases where you actually need them as a string.

| improve this answer | |
  • 2
    It's hard to predict how a :vim command including special characters in its pattern will be parsed without delimiters. While your cursor is on the x in the text foo !x!bar, run :vim <cWORD> %. Instead of looking for !x!bar in the current file, Vim looks for x in the file bar and in the current file. More generally, the expansion may be parsed as anything: a delimiter, a flag, or a filename. The same issue can affect <cword>. That's why I always use delimiters. But inside delimiters, Vim stops expanding special characters, so you need expand() and :exe. – user938271 Apr 2 at 22:06
  • 2
    Small other nitpick: expand() is not only useful to get a string, but also to force Vim to expand special characters earlier. Run this command while your cursor is on a'b: :setl gp&vim | 4verb exe 'grep '..shellescape('<cWORD>'); it fails, because the shell runs grep -n 'a'b' .... And yet you've used shellescape(). – user938271 Apr 2 at 22:07
  • 2
    The issue is not that shellescape() did not receive a valid string; if that was the case, then it would have raised E116 (try :echo shellescape('a'b')). The issue is that shellescape() was evaluated before <cWORD> was expanded. So, it didn't have any effect. expand() fixes the issue by forcing Vim to expand the special characters during the expressions evaluation step (and not after): :setl gp&vim | 4verb exe 'grep '..shellescape(expand('<cWORD>')). – user938271 Apr 2 at 22:07
2

Did I do something wrong here?

:vimgrep is a command which takes a string. expand() is a function call. You must use execute then:

execute 'vimgrep' expand('<cword>') '**/*.h ...'
| improve this answer | |

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.