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
jflag (:vimgrep /pattern/j **/*) to populate the quickfix list without jumping to the first match - Restrict file types with globs:
**/*.jsfor JavaScript,**/*.{c,h}for C files - For large projects,
:grepwith an external tool (:set grepprg=rg\ --vimgrep) is significantly faster - Use
:lvimgrepto populate the location list instead, keeping results per-window