How do I populate the quickfix list from the output of an external shell command?
Answer
:cexpr system('grep -rn TODO .')
Explanation
The :cexpr command evaluates an expression and parses the result as quickfix entries using the current errorformat. Combined with system(), this lets you run any shell command and jump directly to matching locations in Vim. This is a powerful alternative to :make or :vimgrep when you want to leverage fast external tools like grep, rg, or custom linters.
How it works
:cexpr— sets the quickfix list from an expressionsystem('grep -rn TODO .')— runsgreprecursively with line numbers, capturing its output as a string- Vim parses each line of output using
errorformat(the default%f:%l:%mformat works withgrep -rnoutput) - After running, use
:copento view the quickfix list and navigate results
Example
Running :cexpr system('grep -rn TODO .') in a project might produce a quickfix list like:
./src/main.c|12| // TODO: refactor this function
./src/utils.c|45| // TODO: add error handling
./README.md|8| - TODO: update installation docs
You can then press <CR> on any entry to jump to that file and line.
Tips
- Use
:caddexprinstead to append results to the existing quickfix list without replacing it - For ripgrep users:
:cexpr system('rg --vimgrep TODO')works out of the box since--vimgrepoutputs in a format Vim understands - Set a custom
errorformatbefore:cexprif your tool's output format differs from the default - Combine with
:cdoto perform batch operations on all matches::cdo s/TODO/DONE/g | update