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 mainnvimexecutable.cmake.config/— defines (HAVE_*, feature flags).cmake.deps/— downloads and builds third-party deps. Sources are pinned by URL+sha incmake.deps/deps.txt.cmake.packaging/— AppImage, Debian, RPM, MSI scaffolding used byrelease.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 targetMake 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-sitterplus 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:helpto HTML for the website.scripts/gen_filetype.lua— regenerateruntime/lua/vim/filetype.lua.
Editor integration
For working on Neovim in Neovim:
- The repo's
.clangdpoints atbuild/compile_commands.json. After a build, clangd gives you cross-file navigation in any LSP-aware editor. - The repo's
.emmyrc.jsonand.luarc.jsonconfigure LuaLS for Lua support. .editorconfigkeeps whitespace consistent across editors..git-blame-ignore-revslists commits to skip ingit blame. Rungit config blame.ignoreRevsFile .git-blame-ignore-revsonce after cloning.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.