Skip to main content
AI generated
Compilation mode runs a shell command, captures the output, and parses error messages so you can jump directly to the source location. It works for compilers, linters, test runners, and anything else that outputs file/line references.

Configuration

The compile package is configured in lisp/init-prog.el:
  • compilation-scroll-output is set to 'first-error — the compilation buffer scrolls to follow output and stops scrolling when the first error appears.
  • compilation-ask-about-save is disabled — Emacs saves modified buffers before compiling without prompting.
  • compilation-always-kill is enabled — starting a new compilation kills any running one without asking.

Running a compilation

M-x compile prompts for a shell command and runs it. M-x recompile (or g in the compilation buffer) re-runs the last command. For per-language compile commands, compile-multi is configured in lisp/init-project.el with presets for Go, Python, Haskell, Nix, and Rust:
Run M-x compile-multi to pick from these. The consult-compile-multi integration provides a narrowing UI.

In the compilation buffer

From any buffer

The standard M-g n (next-error) and M-g p (previous-error) work from any buffer — Emacs tracks the last buffer that produced errors and jumps you there. This works across compile, grep, occur, and any other mode that produces error-like output. M-g M-n and M-g M-p do the same thing but are easier to type since you can hold Meta throughout. This config also binds M-g e to consult-compile-error (in lisp/init-completion.el), which provides a searchable, narrowable list of all compilation errors via consult.

Flymake integration

For in-buffer diagnostics, M-n and M-p are bound to flymake-goto-next-error and flymake-goto-prev-error in flymake-mode-map (in lisp/init-prog.el). These navigate flymake diagnostics inline without needing a compilation buffer.

Editing grep results

The wgrep package (configured in lisp/init-prog.el) enables editing grep result buffers in place. The workflow is:
  1. consult-ripgrep — search across the project
  2. C-c C-o (embark-export) — export results to a grep buffer
  3. C-x C-q — enter wgrep edit mode
  4. Edit the results as you would any buffer
  5. C-c C-c — apply changes to all matched files
Starting with Emacs 31, a built-in grep-edit-mode will also be available.

How error parsing works

Compilation mode uses compilation-error-regexp-alist and compilation-error-regexp-alist-alist to parse error output. Emacs ships with dozens of entries for GCC, Java, Ruby, Python, Perl, and many more — no configuration needed for common tools. Each entry has the shape:
Where TYPE controls severity: 2 = error, 1 = warning, 0 = info. The TYPE field can also be a cons cell for conditional severity based on match groups.

Adding a custom error regexp

If you use a tool whose output format is not recognized, you can teach compilation mode about it:

Useful variables

Beyond what this config sets, a few more compilation variables are worth knowing:

The compilation mode family

Compilation mode is not just for compilers — it is the infrastructure for any structured output with source locations:
  • grep-modeM-x grep, M-x rgrep, M-x lgrep all produce compilation-derived buffers with the same navigation.
  • occur-modeM-x occur participates in the same next-error infrastructure.
  • flymake — uses compilation-style error navigation under the hood.
Any tool that outputs file/line references can plug into this system. Whether you are navigating compiler errors, grep results, test failures, or linter output, the workflow is the same: M-g n to jump to the next problem.
Last modified on August 23, 2026