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'))
endfunction
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
.
Alternatives
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.