What is the Quickfix List?#
The quickfix list is a navigable list of locations in your project. Each entry has a file, line number, and message. Vim lets you jump between these entries with simple commands.
Common sources that populate the quickfix list:
- Compiler errors (
:make) - Grep results (
:grep,:vimgrep) - Lint output
- Test failures
- Any tool that outputs
file:line:messageformat
Instead of manually opening files and jumping to line numbers, you let the quickfix list drive your navigation.
Basic Quickfix Commands#
| Command | Action |
|---|---|
:copen | Open the quickfix window |
:cclose | Close the quickfix window |
:cnext or :cn | Jump to next entry |
:cprev or :cp | Jump to previous entry |
:cfirst | Jump to first entry |
:clast | Jump to last entry |
:cc 5 | Jump to entry 5 |
:clist | List all entries |
The typical workflow:
1. Run a command that populates the quickfix list
2. :copen to see the results
3. :cnext / :cprev to jump between them
4. Fix each issue
5. :cclose when donePopulating the Quickfix List#
:make — Run your build tool#
This is where quickfix originated — navigating C compiler errors:
" Run make (default)
:makeIf your project uses a Makefile, Vim runs make, parses the output using errorformat, and populates the quickfix list with every error and warning. You jump directly to each one.
C example — compiling with gcc errors:
// main.c
#include <stdio.h>
int main() {
int x = 10
printf("Value: %d\n", y);
return 0;
}:make
" Quickfix list now contains:
" main.c|5| error: expected ';' before 'printf'
" main.c|6| error: 'y' undeclared
:cnext " Jump to line 5 — add the semicolon
:cnext " Jump to line 6 — fix the variable nameConfigure :make for different build systems:
" Default (uses make)
set makeprg=make
" Build a single C file
set makeprg=gcc\ -Wall\ -Wextra\ -o\ %<\ %
" CMake project
set makeprg=cmake\ --build\ build
" Run with specific target
:make clean
:make all:grep — Search across files#
" Search for a pattern across all C source files
:grep "malloc" **/*.c
" Search headers too
:grep "struct node" **/*.{c,h}
" Search in a specific directory
:grep "error" src/
" Case-insensitive
:grep -i "warning" **/*.pyAfter running :grep, the quickfix list is populated with matches. Press Enter on the first result, then use :cnext to step through them.
:vimgrep — Vim’s built-in grep#
" Search with a Vim regex
:vimgrep /function\s\+\w\+/ **/*.js
" Find all struct definitions in C headers
:vimgrep /^struct\s\+\w\+\s*{/ **/*.h
" Add to existing list instead of replacing
:vimgrepadd /TODO/ **/*.md:vimgrep uses Vim’s regex engine and doesn’t depend on external tools. Slower on large projects, but consistent across systems.
:cexpr — Custom command output#
Populate the quickfix list from any command:
" Run cppcheck static analysis
:cexpr system('cppcheck --template=gcc src/')
" Run Python linter
:cexpr system('pylint --output-format=parseable src/*.py')
" Run tests and capture failures
:cexpr system('pytest --tb=line 2>&1')Navigating Efficiently#
Open the quickfix window#
:copenThis splits the screen with a list of all entries. You can:
- Press
Enteron any line to jump to that location - Use
j/kto browse the list :cnext/:cprevto step through without the window focused
Jump without opening the window#
If you prefer not to have the window open:
:cnext " Next error
:cprev " Previous errorMap keys for faster navigation#
" In your .vimrc
nnoremap ]q :cnext<CR>
nnoremap [q :cprev<CR>
nnoremap ]Q :clast<CR>
nnoremap [Q :cfirst<CR>Now ]q and [q step through the list like stepping through search results.
C Programming Workflow#
Compile, fix, repeat#
A typical C workflow using quickfix:
" Set up for your project
set makeprg=gcc\ -Wall\ -Wextra\ -std=c99\ -o\ main\ *.c
" Build
:make
" If there are errors, quickfix is populated automatically
:copen " See all errors at once
:cnext " Jump to first error, fix it
:cnext " Next error
:make " Rebuild to check your fixesFind all uses of a function#
:grep "parse_input" **/*.c **/*.h
:copen
" Now you can see every file and line where parse_input is called or declaredFind memory management issues#
" Find all malloc calls without a corresponding free
:grep "malloc" **/*.c
:copen
" Review each allocation siteNavigate compiler warnings#
" Compile with all warnings
set makeprg=gcc\ -Wall\ -Wextra\ -Wpedantic\ -o\ %<\ %
:make
" Warnings appear in quickfix just like errors
:cnext " Step through each warningMulti-file C project with Makefile#
# Makefile
CC=gcc
CFLAGS=-Wall -Wextra -std=c99
SRC=$(wildcard src/*.c)
OBJ=$(SRC:.c=.o)
main: $(OBJ)
$(CC) $(CFLAGS) -o $@ $^
" Vim uses make by default, so just:
:make
" Errors from any source file appear in quickfix
" Vim opens the correct file and jumps to the right lineThe Location List#
The location list is identical to the quickfix list but scoped to a single window. Every window can have its own location list, while there’s only one global quickfix list.
| Quickfix | Location List Equivalent |
|---|---|
:copen | :lopen |
:cclose | :lclose |
:cnext | :lnext |
:cprev | :lprev |
:grep | :lgrep |
:vimgrep | :lvimgrep |
:make | :lmake |
:clist | :llist |
When to use which#
- Quickfix — project-wide results (build errors, project-wide search)
- Location list — per-file results (lint for current file, local search) or when you want multiple lists visible in different splits
Filtering the Quickfix List#
Keep only matching entries#
" Only show errors containing "undefined"
:cfilter /undefined/
" Invert — remove entries matching a pattern
:cfilter! /warning/Older and newer lists#
Vim keeps a stack of quickfix lists. If you run :grep twice, you can go back:
:colder " Previous quickfix list
:cnewer " Next quickfix list
:chistory " Show quickfix list historyPractical Workflows#
Fix all compiler errors systematically#
:make
:copen
:cfirst
" Fix the error
:cnext
" Fix the next one
:make
" Repeat until clean buildFind and update a function signature across a project#
:grep "int process_data" **/*.c **/*.h
:copen
" Jump to each declaration and call site, update the signatureSearch for a pattern and review all matches#
:grep "TODO\|FIXME\|HACK" **/*.c
:copen
" Browse each note and decide what to addressRun :grep with ripgrep for speed#
" In .vimrc — use ripgrep as the grep program
set grepprg=rg\ --vimgrep\ --smart-case
set grepformat=%f:%l:%c:%m
" Now :grep is fast even in huge projects
:grep "pattern" src/Quickfix and the Dot Command#
A powerful pattern: make a fix, then step and repeat.
" Find all uses of an old function name
:grep "old_func" **/*.c
:cnext
" Rename it
ciw new_func Esc
" Jump to next match and repeat
:cnext
.
:cnext
.Best Practices#
- Map
]qand[qfor quickfix navigation — you’ll use them constantly - Set
grepprgtoripgreporagfor fast project-wide searches - Use
:cfilterto narrow results rather than re-running the search - Use the location list when you need per-window results and want to keep the global quickfix for something else
- Use
:colder/:cnewerto move between search results without losing previous lists - Combine quickfix with the dot command for efficient repetitive fixes across files
- Set
makeprgto your project’s build tool so:makegives you navigable errors - Compile with
-Wall -Wextrain C — more warnings means more quickfix entries to catch issues early

