How do I search across multiple files and navigate results without leaving Vim?
Answer
:vimgrep /pattern/g **/*.ext
Explanation
The :vimgrep command searches for a pattern across multiple files and loads the results into the quickfix list. Unlike external grep, it uses Vim's own regex engine and integrates natively with Vim's navigation.
How it works
" Search for 'TODO' in all Python files recursively
:vimgrep /TODO/g **/*.py
" Search in all files
:vimgrep /pattern/g **/*
" Case-insensitive search
:vimgrep /pattern/gi **/*.js
Navigating results
:copen " Open quickfix window to see all results
:cnext " Jump to next match
:cprev " Jump to previous match
:cfirst " Jump to first match
:clast " Jump to last match
vimgrep vs grep
| Feature | :vimgrep |
:grep |
|---|---|---|
| Engine | Vim regex | External tool (grep/rg) |
| Speed | Slower (reads all files into Vim) | Faster (external process) |
| Regex | Full Vim regex syntax | Tool-specific syntax |
| Integration | Native quickfix | Requires errorformat |
Using external grep for speed
" Use ripgrep as :grep backend
:set grepprg=rg\ --vimgrep
:set grepformat=%f:%l:%c:%m
" Now :grep uses ripgrep
:grep 'pattern' **/*.py
Tips
- Use
jflag to avoid jumping to the first match::vimgrep /pattern/gj **/*.py - The
**glob means "recursive" —**/*.gosearches all Go files in all subdirectories - After
:vimgrep, use:cdofor batch operations on all matches :lvimgrepputs results in the location list instead (per-window)- For large projects, set
grepprgtoripgreporagfor dramatically faster searches