neovim/neovim
How to contribute
The canonical contributor docs live in CONTRIBUTING.md at the repo root and runtime/doc/dev*.txt. This page is the orientation that points you at them in the right order.
Where to start
If you have not built Neovim yet, do that first: Getting started.
For a first patch, the official suggestions are:
- The
complexity:lowissue label on GitHub. - Bugs found by Coverity (you can request access; the report is not public).
- A Vim patch — porting a small change from upstream Vim. This requires familiarity with both editors but the workflow is well-documented in
runtime/doc/dev_vimpatch.txt.
If you don't know where the code you want to change lives, Architecture and Systems are the maps.
Pull request checklist
The maintainers care about each of these:
- Conventional commit subject.
type(scope): subject. Types:build,ci,docs,feat,fix,perf,refactor,revert,test,vim-patch. Append!for a breaking change. - Problem / Solution body. Describe the problem first, then the solution. The PR description should be substantively the same as the commit body.
- Tests. Almost every change needs a functional or unit test. See Testing.
- No unrelated cosmetic edits. Drive-by formatting in unrelated files makes review hard.
- Rebased on
master, not merged. Force-push after addressing review comments is normal. - CI green. The full matrix runs
lint,unittest,functionaltest,oldtest, ASAN/UBSAN, valgrind, and the docs lint.
AI-assisted work
CONTRIBUTING.md and AGENTS.md are explicit:
- YOU review any AI-generated diff before marking the PR ready.
- No verbosity. Strip the model's editorial flourishes from doc, comments, commit messages, and PR descriptions.
- No redundant code or tests. Deduplicate before submitting.
- AI disclosure. Add an
AI-assisted: <tool name>trailer to every commit that used AI in any capacity.
A PR that arrives with hedged, verbose, or duplicative AI-style content gets bounced back for cleanup before it is reviewed for correctness.
What goes into C versus Lua
Verbatim from CONTRIBUTING.md: "New functionality should generally be implemented in Lua, not C." The reference PRs #37757 and #37831 are cited as good examples.
The decision tree in runtime/doc/dev_arch.txt for adding a new Vimscript function or Ex command:
- Full Lua — implementation entirely in Lua under
runtime/lua/vim/_core/vimfn.lua. Vimscript callers go through a tiny C wrapper. Preferred. - Partial Lua — a thin C function calls into Lua via
nlua_call_vimfn/nlua_call_excmd. Useful when the C side already has the data. - Legacy C — only when there is a concrete reason not to use Lua.
Same hierarchy applies to autocmds, options, UI events, and most "new feature" patches.
Style and structure
- C style is
src/uncrustify.cfg(with.clang-formatas a softer fallback).make formatcformats changed C in place. - Lua style is
styluaagainst.stylua.toml.make formatluaformats it. - Tree-sitter queries are formatted with
make formatquery. - Lint with
make lint. CI builds with-Werror, so a warning is a failure. - Header hygiene uses include-what-you-use.
make iwyuapplies the suggestions.
The full style guide is at runtime/doc/dev_style.txt.
Reviewing
Reviewers pull PRs locally with gh pr checkout <url>. To get a useful diff for the conversation:
git log -p -W master..FETCH_HEADShow the full surrounding function for each change with -W; show a per-commit diff with -p.
Where the deep dives live
- Development workflow — branch, code, test, PR, merge.
- Testing — how the test suites are organized and how to run them.
- Debugging — backtraces, ASAN, valgrind, the
$NVIM_LOG_FILE. - Patterns and conventions — error handling, allocation, typval, the API contract.
- Tooling — the make targets, the cmake presets, the generators.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.