Problem: Cannot detach the current UI. Solution: - Introduce `:detach`. - Introduce `Channel.detach`. Co-authored-by: bfredl <bjorn.linse@gmail.com>
15 KiB
Contributing to Neovim
Getting started
If you want to help but don't know where to start, here are some low-risk/isolated tasks:
- Try a complexity:low issue.
- Fix bugs found by Coverity.
- Merge a Vim patch (requires strong familiarity with Vim)
- NOTE: read the above link before sending improvements to "runtime files" (anything in
runtime/).- Vimscript and documentation files are (mostly) maintained by Vim, not Nvim.
- Nvim's filetype detection behavior matches Vim, so changes to filetype detection should be submitted to Vim first.
- Lua files are maintained by Nvim.
- NOTE: read the above link before sending improvements to "runtime files" (anything in
Reporting problems
- Check the FAQ.
- Search existing issues (including closed!)
- Update Neovim to the latest version to see if your problem persists.
- Try to reproduce with
nvim --clean("factory defaults"). - If a specific configuration or plugin is necessary to recreate the problem, use the minimal template in
contrib/minimal.luawithnvim --clean -u contrib/minimal.luaafter making the necessary changes. - Bisect your config: disable plugins incrementally, to narrow down the cause of the issue.
- Bisect Neovim's source code to find the cause of a regression, if you can. This is extremely helpful.
- When reporting a crash, include a stacktrace.
- Use ASAN/UBSAN to get detailed errors for segfaults and undefined behavior.
- Check the logs.
:edit $NVIM_LOG_FILE - Include
cmake --system-informationfor build-related issues.
Developer guidelines
- Read :help dev and :help dev-doc if you are working on Nvim core.
- Read :help dev-ui if you are developing a UI.
- Read :help dev-api-client if you are developing an API client.
- Install
ninjafor faster builds of Nvim.sudo apt-get install ninja-build make distclean make # Nvim build system uses ninja automatically, if available. - Install
ccacheorsccachefor faster rebuilds of Nvim. Nvim will use one of these automatically if it's found. To disable caching use:cmake -B build -D CACHE_PRG=OFF
Pull requests (PRs)
- To avoid duplicate work, create a draft pull request.
- Your PR must include test coverage.
- Avoid cosmetic changes to unrelated files in the same commit.
- Use a feature branch instead of the master branch.
- Use a rebase workflow for all PRs.
- After addressing review comments, it's fine to force-push.
Merging to master
For maintainers: when a PR is ready to merge to master,
- prefer Squash Merge for "single-commit PRs" (when the PR has only one meaningful commit).
- prefer Merge for "multi-commit PRs" (when the PR has multiple meaningful commits).
Stages: Draft and Ready for review
Pull requests have two stages: Draft and Ready for review.
- Create a Draft PR while you are not requesting feedback as
you are still working on the PR.
- You can skip this if your PR is ready for review.
- Change your PR to ready when the PR is ready for review.
- You can convert back to Draft at any time.
Do not add labels like [RFC] or [WIP] in the title to indicate the
state of your PR: this just adds noise. Non-Draft PRs are assumed to be open
for comments; if you want feedback from specific people, @-mention them in
a comment.
Commit messages
Follow the conventional commits guidelines to make reviews easier and to make
the VCS/git logs more valuable (try make lintcommit). The structure of a commit message is:
type(scope): subject
Problem:
...
Solution:
...
- Commit message subject (you can ignore this for "fixup" commits or any commits you expect to be squashed):
- Prefix with a type:
build ci docs feat fix perf refactor revert test vim-patch
- Append an optional
(scope)such as(lsp),(treesitter),(float), … - Use the imperative voice: "Fix bug" rather than "Fixed bug" or "Fixes bug."
- Keep it short (under 72 characters).
- Prefix with a type:
- Commit message body (detail):
- Concisely describe the Problem/Solution in the commit body. Describing the problem
independently of the solution often leads to a better understanding for you, reviewers, and future readers.
Problem: Solution:
- Concisely describe the Problem/Solution in the commit body. Describing the problem
independently of the solution often leads to a better understanding for you, reviewers, and future readers.
- Indicate breaking API changes with "!" after the type, and a "BREAKING CHANGE" footer. Example:
refactor(provider)!: drop support for Python 2 BREAKING CHANGE: refactor to use Python 3 features since Python 2 is no longer supported.
Automated builds (CI)
Each pull request must pass the automated builds on Cirrus CI and GitHub Actions.
- CI builds are compiled with
-Werror, so compiler warnings will fail the build. - If any tests fail, the build will fail. See test/README.md#running-tests to run tests locally.
- CI runs ASan and other analyzers.
- To run valgrind locally:
VALGRIND=1 make test - To run ASan/UBSan locally:
CC=clang make CMAKE_FLAGS="-DENABLE_ASAN_UBSAN=ON". Note that MSVC requires Release or RelWithDebInfo build type to work properly.
- To run valgrind locally:
- The lint build checks that the code is formatted correctly and passes various linter checks.
- CI for FreeBSD runs on Cirrus CI.
- To see CI results faster in your PR, you can temporarily set
TEST_FILEin test.yml.
Coverity
Coverity runs against the master build. To view the defects you must request access (Coverity does not have a "public" view), then you will be approved as soon as a maintainer sees the email.
- Use this format for commit messages (where
{id}is the CID (Coverity ID); (example)):fix(coverity/{id}): {description} - Search the Neovim commit history to find examples:
git log --oneline --no-merges --grep coverity
Sanitizers (ASAN and UBSAN)
ASAN/UBSAN can be used to detect memory errors and other common forms of undefined behavior at runtime in debug builds.
- To build Neovim with sanitizers enabled, use
rm -rf build && CMAKE_EXTRA_FLAGS="-DCMAKE_C_COMPILER=clang -DENABLE_ASAN_UBSAN=1" make - When running Neovim, use
ASAN_OPTIONS=log_path=/tmp/nvim_asan nvim args... - If Neovim exits unexpectedly, check
/tmp/nvim_asan.{PID}(or your preferredlog_path) for log files with error messages.
Coding
Lint
You can run the linter locally by:
make lint
Style
- You can format files by using:
This will format changed Lua and C files with all appropriate flags set.
make format # or formatc, formatlua - Style rules are (mostly) defined by
src/uncrustify.cfgwhich tries to match the style-guide. To use the Nvimgqcommand withuncrustify:if !empty(findfile('src/uncrustify.cfg', ';')) setlocal formatprg=uncrustify\ -q\ -l\ C\ -c\ src/uncrustify.cfg\ --no-backup endif - There is also
.clang-formatwhich has drifted from the style-guide, but is available for reference. To use the Nvimgqcommand withclang-format:if !empty(findfile('.clang-format', ';')) setlocal formatprg=clang-format\ -style=file endif
Navigate
-
Set
blame.ignoreRevsFileto ignore noisy commits in git blame:git config blame.ignoreRevsFile .git-blame-ignore-revs -
Recommendation is to use clangd. Can use the maintained config in nvim-lspconfig/clangd.
-
Explore the source code on the web.
Includes
For managing includes in C files, use include-what-you-use.
- Install include-what-you-use
- To see which includes needs fixing use the cmake preset
iwyu:cmake --preset iwyu cmake --build build - There's also a make target that automatically fixes the suggestions from
IWYU:
make iwyu
See #549 for more details.
Lua runtime files
Most of the Lua core runtime/ modules are precompiled to
bytecode, so changes to those files won't get used unless you rebuild Nvim or
by passing --luamod-dev and $VIMRUNTIME. For example, try adding a function
to runtime/lua/vim/_editor.lua then:
VIMRUNTIME=./runtime ./build/bin/nvim --luamod-dev
Documentation
Read :help dev-doc to understand the expected documentation style and conventions.
Generating :help
Many :help docs are autogenerated from (C or Lua) docstrings. To generate the documentation run:
make doc
To validate the documentation files, run:
make lintdoc
If you need to modify or debug the documentation flow, these are the main files:
-
./scripts/gen_vimdoc.lua: Main doc generator. Parses C and Lua files to render vimdoc files. -
./scripts/luacats_parser.lua: Documentation parser for Lua files. -
./scripts/cdoc_parser.lua: Documentation parser for C files. -
./scripts/luacats_grammar.lua: Lpeg grammar for LuaCATS -
./scripts/cdoc_grammar.lua: Lpeg grammar for C doc comments -
./scripts/gen_eval_files.lua: Generates documentation and Lua type files from metadata files:runtime/lua/vim/* => runtime/doc/lua.txt runtime/lua/vim/* => runtime/doc/lua.txt runtime/lua/vim/lsp/ => runtime/doc/lsp.txt src/nvim/api/* => runtime/doc/api.txt src/nvim/eval.lua => runtime/doc/builtin.txt src/nvim/options.lua => runtime/doc/options.txt -
./scripts/lintdoc.lua: Validation and linting of documentation files.
Lua docstrings
Use LuaLS annotations in Lua docstrings to annotate parameter types, return types, etc. See :help dev-lua-doc.
- The template for function documentation is:
--- {Brief} --- --- {Long explanation} --- --- @param arg1 type {description} --- @param arg2 type {description} --- ... --- --- @return type {description} - If possible, add type information (
table,string,number, ...). Multiple valid types are separated by a bar (string|table). Indicate optional parameters viatype|nil. - If a function in your Lua module should not be documented, add
@nodoc. - If the function is internal or otherwise non-public add
@private. - Private functions usually should be underscore-prefixed (named "_foo", not "foo"). - Mark deprecated functions with
@deprecated.
Third-party dependencies
To build Nvim using a different commit of a dependency change the appropriate
URL in cmake.deps/deps.txt. For example, to use a different version of luajit
replace the value in LUAJIT_URL with the wanted commit hash:
LUAJIT_URL https://github.com/LuaJIT/LuaJIT/archive/<sha>.tar.gz
Set DEPS_IGNORE_SHA to TRUE in cmake.deps/CMakeLists.txt to skip hash
check from cmake.
Alternatively, you may point the URL as a local path where the repository is.
This is convenient when bisecting a problem in a dependency with git bisect.
This may require running make distclean between each build. Hash checking is
always skipped in this case regardless of DEPS_IGNORE_SHA.
LUAJIT_URL /home/user/luajit
Reviewing
Reviewing can be done on GitHub, but you may find it easier to do locally. Using GitHub CLI, you can create a new branch with the contents of a pull request, e.g. #1820:
gh pr checkout https://github.com/neovim/neovim/pull/1820
Use git log -p master..FETCH_HEAD to list all
commits in the feature branch which aren't in the master branch; -p
shows each commit's diff. To show the whole surrounding function of a change
as context, use the -W argument as well.