Given this small vimgrep wrapper, how would I forward multiple arguments to vimgrep, so they are interpreted as a single argument to vimgrep?

command! -nargs=1 FIND call SimpleGrep(<f-args>)
nnoremap <M-f> :FIND<SPACE>

function! SimpleGrep(exp)
    " Depends on: https://github.com/dbakker/vim-projectroot
    let l:base = ProjectRootGuess()
    " Find files with the current extension in project path.
    let l:root = l:base . "/**/*." . expand('%:e')
    execute 'vimgrep' a:exp l:root

Currently FIND text works, but FIND "some text" only works when quoted.


The simple case

Projectroot provides the :ProjectRootExe command which can simplify this task greatly.

command! -nargs=+ FIND ProjectRootExe execute "vimgrep /<args>/ **/*." . expand('%:e')
nnoremap <M-f> :FIND<SPACE>

The <args> expands to the arguments supplied to your :FIND command. While -nargs=+ means this command can take at least 1 argument. Since you do not want to quote the search pattern we will add /'s as suggested by :h :vimgrep.

Using <q-args>

Since you wanted to use a function to do some extra logic, you can use <q-args> to slurp up all the arguments into a "quoted string". e.g.

function s:simple_grep(pattern)
  let filetypes = {}
  let filetypes['c'] = '{c,cpp,h}'
  execute "ProjectRootExe vimgrep /" . a:pattern . "/ *." . get(filetypes, &filetype, expand('%:e'))

command! -nargs=+ Find call <SID>simple_grep(<q-args>)
nnoremap <M-f> :FIND<SPACE>

I have added some logic to search multiple extensions when using the 'filetype' is set to c.


If you use git and fugitive.vim you may want to look into using :Ggrep as it much faster than :vimgrep and automatically searching from the root of a git project by default.

You may also want to look into using a tool like Ag the silver searcher which searches recursively by default an can be supplied a file type, e.g. ag --js 'pattern'. Note: ag does not search from project root. Settings from man ag:

set grepprg=ag\ --vimgrep\ $*
set grepformat=%f:%l:%c:%m

Now you can use ag powered grep: :grep 'pattern'.

For more help see

:h :command-nargs
:h <args>
:h :vimgrep
:h :execute
:h expand()
:h <q-args>
:h get()
:h projectroot-:ProjectRootExe

Note: I do not use projectroot nor have I tested any of the code above. Use as is.

| improve this answer | |
  • Thanks for the answer. while this is helpful, I wanted to keep using the function (instead of bypassing it), to be able to choose useful extension(s) based on the filetype. – ideasman42 Sep 26 '16 at 21:59
  • I have updated my answer to show how you can leverage <q-args> to pass arguments to a function call. – Peter Rincker Sep 26 '16 at 22:27

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.