:grep/:vimgrep both use the quickfix list to store locations. As you have noticed vim will automatically jump to the first occurrence (use ! to avoid this behavior). Simply use :cnext to go to the next location in the quickfix list.
Quickfix commands
:cnext/:cprevious to navigate the quickfix forwards and backwards in the quickfix list
:cfirst/:clast to jump to the start and end of the quickfix list
- Use
:copen to open the quickfix window. Use <cr> to jump to an entry
- Use
:cclose to close the quickfix window
- Use
:cc to display the current error.
:colder/:cnewer to jump older/newer quickfix lists
I would recommend you create mappings for :cnext and :cprevious. I personally use unimpaired.vim which provides ]q & [q mappings for :cnext and :cprevious.
If you want the quickfix window to open automatically put the following in your vimrc:
augroup autoquickfix
autocmd!
autocmd QuickFixCmdPost [^l]* cwindow
autocmd QuickFixCmdPost l* lwindow
augroup END
There is a Vimcasts episode about this topic: Search multiple files with :vimgrep.
Project-wide Search and Replace
If you are using :grep/:vimgrep as way to do a project-wide search and replace then I suggest you use :cdo/:cfdo (in Vim 7.4.980+).
:grep 'foo'
:cfdo %s/foo/bar/g|w
If your version of Vim does not have :cdo/:cfdo put the following commands in your vimrc file to provide :Cdo/:Cfdo alternative commands.
if !exists(':cdo')
command! -nargs=1 -complete=command Cdo try | sil cfirst |
\ while 1 | exec <q-args> | sil cn | endwhile |
\ catch /^Vim\%((\a\+)\)\=:E\%(553\|42\):/ |
\ endtry
command! -nargs=1 -complete=command Cfdo try | sil cfirst |
\ while 1 | exec <q-args> | sil cnf | endwhile |
\ catch /^Vim\%((\a\+)\)\=:E\%(553\|42\):/ |
\ endtry
endif
Using an alternative program for :grep
Sometimes grep isn't quite good enough for your search needs. You can change your :grep program via the 'grepprg' setting (may also need to change 'grepformat' as well). Personally I use ripgrep by adding the following to my vimrc file as instructed in rg's man page:
set grepprg=rg\ --vimgrep
set grepformat^=%f:%l:%c:%m
Note: May want to use -S flag, e.g. set grepprg=rg\ -S\ --vimgrep, to use "smart case" searching (case insensitive searching when all lowercase letters).
Now :grep will use rg to search. e.g. :grep foo -t js.
Her are a few alternative grep programs to look into: ack, ag, ripgrep, and git grep (Fugitive.vim provides :Ggrep wrapper)
For more help see:
:h :grep
:h 'grepprg'
:h quickfix
:h :cnext
:h :copen
:h :ccl
:h :cc
:h :colder
:h :cdo
:h :cfdo