vimtricks.wiki Concise Vim tricks, one at a time.

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 j flag to avoid jumping to the first match: :vimgrep /pattern/gj **/*.py
  • The ** glob means "recursive" — **/*.go searches all Go files in all subdirectories
  • After :vimgrep, use :cdo for batch operations on all matches
  • :lvimgrep puts results in the location list instead (per-window)
  • For large projects, set grepprg to ripgrep or ag for dramatically faster searches

Next

How do I always access my last yanked text regardless of deletes?