On , I learnt ...

You can run :grep without using parent shell process

Using ripgrep as a :grep command can be configured with:

set grepprg=rg\ --vimgrep

This is a big upgrade in performance and functionality but it has a couple of downsides:

These problems can be avoided by using :cgetexpr to populate the quickfix list via a command executed with system. Here’s a custom :Grep command that does exactly that.

function! Grep(...)
    return system(join([&grepprg] + [join(a:000, ' ')], ' '))
endfunction

" Define custom commands for quickfix/location lists.
command! -nargs=+ -complete=file_in_path Grep  cgetexpr Grep(<f-args>)
command! -nargs=+ -complete=file_in_path LGrep lgetexpr Grep(<f-args>)

" Use an autocommand to automatically open the quickfix/location list if there
" are errors.
augroup quickfix
    autocmd!
    autocmd QuickFixCmdPost cgetexpr cwindow
    autocmd QuickFixCmdPost lgetexpr lwindow
augroup END

Credit to Romain Lafourcade, who wrote this up in “Instant grep + quickfix”. The command I use is slightly different to his as: