Open-Source Wikis

/

Neovim

/

How to contribute

/

Tooling

neovim/neovim

Tooling

The build system, linters, generators, and CI tools that wrap the source.

CMake

The canonical build is CMake-driven. The top-level Makefile and BSDmakefile are convenience wrappers that translate human-friendly targets into CMake invocations. The presets in CMakePresets.json give you iwyu, release, debug, etc.

Key CMake files:

  • CMakeLists.txt — root build, sets up the bundled-deps fetch and the main nvim executable.
  • cmake.config/ — defines (HAVE_*, feature flags).
  • cmake.deps/ — downloads and builds third-party deps. Sources are pinned by URL+sha in cmake.deps/deps.txt.
  • cmake.packaging/ — AppImage, Debian, RPM, MSI scaffolding used by release.yml.
  • src/nvim/CMakeLists.txt — defines the actual build targets, the generated-headers pipeline, and the test runners.

Useful invocations:

cmake --build build --target help     # list every target
cmake -B build -LH                    # show all options with help
cmake --preset iwyu                   # set up the include-what-you-use build
cmake --build build --target lintc    # run a single lint target

Make targets

The Makefile aliases that you'll use day-to-day:

Target What it does
make Default RelWithDebInfo build
make CMAKE_BUILD_TYPE=Debug Debug build
make distclean rm -rf build .deps
make deps Build only third-party deps
make install Install to CMAKE_INSTALL_PREFIX
make doc Regenerate :help files
make test Run all suites
make functionaltest / unittest / oldtest / benchmark Individual suites
make lint / lintc / lintlua / lintdoc / lintquery / lintcommit Lint targets
make format / formatc / formatlua / formatquery Auto-format
make iwyu Apply include-what-you-use suggestions

TEST_FILE, TEST_FILTER, VALGRIND, CMAKE_EXTRA_FLAGS, CMAKE_INSTALL_PREFIX are the most common environment overrides.

Code generators

A non-trivial fraction of the C code is generated. The generators all live in src/gen/ and are pure Lua (run via nlua0, the small embedded Lua used at build time):

Input Generator Output
src/nvim/api/*.c src/gen/gen_api_dispatch.lua API dispatch wrappers and metadata
src/nvim/api/ui_events.in.h src/gen/gen_api_ui_events.lua UI event wrappers
src/nvim/eval.lua src/gen/gen_eval.lua Vimscript fn dispatch
src/nvim/options.lua src/gen/gen_options.lua Option tables and enum
src/nvim/ex_cmds.lua src/gen/gen_ex_cmds.lua Excmd dispatch
src/nvim/auevents.lua src/gen/gen_events.lua Autocmd event tables
src/nvim/keycodes.lua src/gen/gen_keycodes.lua Keycode tables
src/nvim/vvars.lua src/gen/gen_vimvim.lua v: variable definitions
runtime/doc/*.txt src/gen/gen_vimdoc.lua API/options/lua docs
Translations src/gen/preload.lua Build-time loader

Edit the input file, run make, and the generated header lands under build/src/nvim/auto/. Don't edit the generated headers directly — they get clobbered.

The generator drivers and parsers used by the doc generator (luacats_parser.lua, cdoc_parser.lua, luacats_grammar.lua, cdoc_grammar.lua) also live in src/gen/.

Linters

Linter Targets
clang-tidy C lint. Config in .clang-tidy.
uncrustify C formatting. Config in src/uncrustify.cfg.
clang-format Backup C formatter. Config in .clang-format.
luacheck Lua lint. Config in .luacheckrc.
selene Lua lint.
stylua Lua format. Config in .stylua.toml, .stylua2.toml.
clint.lua In-tree custom C lint. Lives at src/clint.lua.
lintdoc Vim help validator. Driver in scripts/lintdoc.lua.
lintcommit Conventional-commit validator. Driver in scripts/lintcommit.lua.
zizmor Workflow security scanner. Config in .github/zizmor.yml.

make lint runs all of these. CI also runs include-what-you-use (the iwyu preset) against headers.

Bundled third-party deps

cmake.deps/deps.txt pins every external library. The fetch is done at CMake-time via ExternalProject_Add calls in cmake.deps/cmake/. Currently bundled (versions accurate as of 2026-04):

  • libuv — async I/O.
  • LuaJIT — Lua interpreter.
  • lua (5.1) — fallback PUC Lua.
  • luv — Lua bindings to libuv.
  • lpeg — PEG library.
  • lua-compat-5.3 — Lua 5.1 ↔ 5.3 compatibility.
  • unibilium — terminfo parser.
  • tree-sitter plus per-language parsers (tree-sitter-c, -lua, -vimdoc, -vim, -markdown, -bash, -query).
  • gettext, libiconv — i18n on platforms that don't ship them.
  • win32yank — Windows clipboard helper.

To bump a dependency, update its URL+sha256 in deps.txt, run make distclean, and rebuild. Setting DEPS_IGNORE_SHA=TRUE in cmake.deps/CMakeLists.txt skips the hash check, which is useful for git bisect over a vendored library.

CI

Workflows live in .github/workflows/:

Workflow Purpose
build.yml Build matrix (Linux, macOS, Windows; debug/release).
test.yml Unit + functional + oldtest.
test_windows.yml Windows-specific tests.
release.yml Tag → asset uploads.
news.yml Release notes generation.
lintcommit.yml Validate conventional-commit message format.
lintdocurls.yml Validate links inside runtime/doc/*.txt.
vim_patches.yml Track and report vim-patch porting status.
coverity.yml Submit to Coverity Scan.
codeql.yml GitHub CodeQL static analysis.
backport.yml Auto-backport flagged PRs to release branches.
labeler_*.yml, reviewers_*.yml, response.yml Issue/PR triage automation.
zizmor.yml Workflow security scanning.
optional.yml Manually triggered jobs (sanitizer-only, etc.).
docs.yml Build and publish API docs.

The matrix is extensive — a typical PR triggers ~30 jobs. CI is the source of truth for "is this commit good"; locally you run only what you suspect changed.

In-tree dev tools

Helper scripts for maintainers:

  • scripts/vim-patch.sh — fetch and apply a Vim patch.
  • scripts/git-log-pretty-since.sh — printable changelogs for releases.
  • scripts/release.sh, scripts/genappimage.sh — release plumbing.
  • scripts/gen_help_html.lua — render :help to HTML for the website.
  • scripts/gen_filetype.lua — regenerate runtime/lua/vim/filetype.lua.

Editor integration

For working on Neovim in Neovim:

  • The repo's .clangd points at build/compile_commands.json. After a build, clangd gives you cross-file navigation in any LSP-aware editor.
  • The repo's .emmyrc.json and .luarc.json configure LuaLS for Lua support.
  • .editorconfig keeps whitespace consistent across editors.
  • .git-blame-ignore-revs lists commits to skip in git blame. Run git config blame.ignoreRevsFile .git-blame-ignore-revs once after cloning.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Tooling – Neovim wiki | Factory