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

How do I search for a pattern across all files in a project using Vim's built-in grep?

Answer

:vimgrep /pattern/ **/*

Explanation

While external tools like grep or ripgrep are fast, Vim's built-in :vimgrep has a key advantage: it populates the quickfix list directly, so you can jump between matches using Vim's native navigation without leaving the editor. The **/* glob pattern recurses into all subdirectories, giving you a project-wide search.

How it works

  • :vimgrep — Vim's internal grep command that uses Vim regex syntax
  • /pattern/ — the search pattern, using Vim's regular expression engine
  • **/* — recursive glob matching all files in all subdirectories
  • Results populate the quickfix list, navigable with :cnext, :cprev, and :copen

Example

Search for all TODO comments across a project:

:vimgrep /TODO\|FIXME/ **/*.py

This searches all Python files recursively. Then navigate results:

:copen       " open the quickfix window to see all matches
:cnext       " jump to the next match
:cprev       " jump to the previous match
:cfirst      " jump to the first match
:clast       " jump to the last match
quickfix window:
  src/app.py|12| # TODO: refactor this function
  src/utils.py|45| # FIXME: handle edge case
  tests/test_app.py|8| # TODO: add more test cases

Tips

  • Add j flag (:vimgrep /pattern/j **/*) to populate the quickfix list without jumping to the first match
  • Restrict file types with globs: **/*.js for JavaScript, **/*.{c,h} for C files
  • For large projects, :grep with an external tool (:set grepprg=rg\ --vimgrep) is significantly faster
  • Use :lvimgrep to populate the location list instead, keeping results per-window

Next

How do I use PCRE-style regex in Vim without escaping every special character?