2019-07-19 12:32:04 -07:00
Contributing to Neovim
======================
2014-02-24 16:32:15 -07:00
2016-08-09 21:47:04 -07:00
Getting started
---------------
2014-02-24 16:32:15 -07:00
2016-08-09 21:47:04 -07:00
If you want to help but don't know where to start, here are some
low-risk/isolated tasks:
2015-03-09 16:20:15 -07:00
2021-12-19 14:15:42 -07:00
- Try a [complexity:low] issue.
2023-10-24 08:44:02 -07:00
- Fix bugs found by [Coverity ](#coverity ).
2022-10-14 08:01:13 -07:00
- [Merge a Vim patch] (requires strong familiarity with Vim)
2022-10-18 07:18:44 -07:00
- NOTE: read the above link before sending improvements to "runtime files" (anything in `runtime/` ).
- Vimscript and documentation files are (mostly) maintained by [Vim ](https://github.com/vim/vim ), not Nvim.
- Lua files are maintained by Nvim.
2017-04-17 14:52:38 -07:00
2019-07-19 12:32:04 -07:00
Reporting problems
------------------
- [Check the FAQ][wiki-faq].
- [Search existing issues][github-issues] (including closed!)
- Update Neovim to the latest version to see if your problem persists.
2021-10-05 08:01:09 -07:00
- Try to reproduce with `nvim --clean` ("factory defaults").
2023-12-12 09:10:22 -07:00
- If a specific configuration or plugin is necessary to recreate the problem, use the minimal template in `contrib/minimal.lua` with `nvim --clean -u contrib/minimal.lua` after making the necessary changes.
2021-08-21 18:26:33 -07:00
- [Bisect ](https://neovim.io/doc/user/starting.html#bisect ) your config: disable plugins incrementally, to narrow down the cause of the issue.
- [Bisect][git-bisect] Neovim's source code to find the cause of a regression, if you can. This is _extremely_ helpful.
2024-01-28 15:26:13 -07:00
- When reporting a crash, [include a stacktrace ](https://neovim.io/doc/user/dev_tools.html#dev-tools-backtrace ).
- Use [ASAN/UBSAN ](#sanitizers-asan-and-ubsan ) to get detailed errors for segfaults and undefined behavior.
2021-08-21 18:26:33 -07:00
- Check the logs. `:edit $NVIM_LOG_FILE`
2019-07-19 12:32:04 -07:00
- Include `cmake --system-information` for build-related issues.
2017-04-17 14:52:38 -07:00
Developer guidelines
--------------------
2023-06-19 02:24:44 -07:00
- Read [:help dev ](https://neovim.io/doc/user/develop.html#dev ) and [:help dev-doc][dev-doc-guide] if you are working on Nvim core.
2022-10-09 05:21:52 -07:00
- Read [:help dev-ui ](https://neovim.io/doc/user/develop.html#dev-ui ) if you are developing a UI.
- Read [:help dev-api-client ](https://neovim.io/doc/user/develop.html#dev-api-client ) if you are developing an API client.
2021-08-27 03:59:13 -07:00
- Install `ninja` for faster builds of Nvim.
2023-07-07 05:52:30 -07:00
```bash
2017-12-27 11:30:23 -07:00
sudo apt-get install ninja-build
make distclean
make # Nvim build system uses ninja automatically, if available.
```
2023-01-27 16:42:13 -07:00
- Install `ccache` for faster rebuilds of Nvim. Nvim will use it automatically
if it's found. To disable caching use:
2023-07-07 05:52:30 -07:00
```bash
2023-01-27 16:42:13 -07:00
CCACHE_DISABLE=true make
```
2016-08-09 21:47:04 -07:00
2019-01-10 17:20:15 -07:00
Pull requests (PRs)
2016-08-09 21:47:04 -07:00
---------------------
2016-06-03 12:05:44 -07:00
2021-08-21 18:26:33 -07:00
- To avoid duplicate work, create a draft pull request.
- Your PR must include [test coverage][run-tests].
2017-06-06 06:02:51 -07:00
- Avoid cosmetic changes to unrelated files in the same commit.
2016-06-03 12:05:44 -07:00
- Use a [feature branch][git-feature-branch] instead of the master branch.
2023-07-07 05:52:30 -07:00
- Use a _rebase workflow_ for all PRs.
2022-10-09 05:21:52 -07:00
- 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).
2015-04-21 14:35:06 -07:00
2021-08-17 05:58:49 -07:00
### Stages: Draft and Ready for review
2015-04-21 14:35:06 -07:00
2021-08-17 05:58:49 -07:00
Pull requests have two stages: Draft and Ready for review.
2015-03-09 16:20:15 -07:00
2021-08-17 05:58:49 -07:00
1. [Create a Draft PR][pr-draft] while you are _not_ requesting feedback as
you are still working on the PR.
2021-08-21 18:26:33 -07:00
- You can skip this if your PR is ready for review.
2021-08-17 05:58:49 -07:00
2. [Change your PR to ready][pr-ready] when the PR is ready for review.
2021-08-21 18:26:33 -07:00
- You can convert back to Draft at any time.
2021-08-17 05:58:49 -07:00
2021-08-21 18:26:33 -07:00
Do __not__ add labels like `[RFC]` or `[WIP]` in the title to indicate the
2021-08-17 05:58:49 -07:00
state of your PR: this just adds noise. Non-Draft PRs are assumed to be open
2021-08-21 18:26:33 -07:00
for comments; if you want feedback from specific people, `@` -mention them in
a comment.
2015-03-09 16:20:15 -07:00
2016-06-03 12:05:44 -07:00
### Commit messages
2015-03-09 16:20:15 -07:00
2021-06-10 10:08:58 -07:00
Follow the [conventional commits guidelines][conventional_commits] to *make reviews easier* and to make
2021-08-21 18:26:33 -07:00
the VCS/git logs more valuable. The general structure of a commit message is:
2015-03-09 16:20:15 -07:00
2021-06-10 10:08:58 -07:00
```
< type > ([optional scope]): < description >
[optional body]
[optional footer(s)]
```
2021-08-21 18:26:33 -07:00
- Prefix the commit subject with one of these [_types_ ](https://github.com/commitizen/conventional-commit-types/blob/master/index.json ):
2023-02-10 09:03:01 -07:00
- `build` , `ci` , `docs` , `feat` , `fix` , `perf` , `refactor` , `revert` , `test` , `vim-patch`
2021-08-21 18:26:33 -07:00
- You can **ignore this for "fixup" commits** or any commits you expect to be squashed.
- Append optional scope to _type_ such as `(lsp)` , `(treesitter)` , `(float)` , …
- _Description_ shouldn't start with a capital letter or end in a period.
- Use the _imperative voice_ : "Fix bug" rather than "Fixed bug" or "Fixes bug."
2021-06-10 10:08:58 -07:00
- Try to keep the first line under 72 characters.
2021-08-21 18:26:33 -07:00
- A blank line must follow the subject.
- Breaking API changes must be indicated by
1. "!" after the type/scope, and
2. a "BREAKING CHANGE" footer describing the change.
Example:
```
refactor(provider)!: drop support for Python 2
2021-07-26 03:23:49 -07:00
2021-08-21 18:26:33 -07:00
BREAKING CHANGE: refactor to use Python 3 features since Python 2 is no longer supported.
```
2015-03-09 16:20:15 -07:00
2023-07-07 05:52:30 -07:00
### News
High level release notes are maintained in [news.txt ](runtime/doc/news.txt ). A PR is not required to add a news item
but is generally recommended.
2016-06-03 12:05:44 -07:00
### Automated builds (CI)
2015-03-09 16:20:15 -07:00
2022-09-08 15:12:42 -07:00
Each pull request must pass the automated builds on [Cirrus CI] and [GitHub Actions].
2015-03-09 16:20:15 -07:00
2017-06-06 06:02:51 -07:00
- CI builds are compiled with [`-Werror`][gcc-warnings], so compiler warnings
will fail the build.
2021-09-20 19:00:50 -07:00
- If any tests fail, the build will fail. See [test/README.md#running-tests][run-tests] to run tests locally.
2017-07-29 09:51:31 -07:00
- CI runs [ASan] and other analyzers.
- To run valgrind locally: `VALGRIND=1 make test`
2023-10-07 06:07:45 -07:00
- 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.
2023-11-04 09:33:22 -07:00
- The [lint ](#lint ) build checks that the code is formatted correctly and
passes various linter checks.
2022-09-08 15:12:42 -07:00
- CI for FreeBSD runs on [Cirrus CI].
2021-09-20 19:00:50 -07:00
- To see CI results faster in your PR, you can temporarily set `TEST_FILE` in
2023-02-18 02:47:22 -07:00
[test.yml ](https://github.com/neovim/neovim/blob/e35b9020b16985eee26e942f9a3f6b045bc3809b/.github/workflows/test.yml#L29 ).
2017-01-31 00:53:16 -07:00
2019-01-08 11:58:06 -07:00
### Coverity
2016-06-03 12:05:44 -07:00
2024-01-18 01:14:48 -07:00
Coverity runs against the master build. To view the defects you must
[request access ](https://scan.coverity.com/projects/neovim-neovim ) (Coverity
does not have a "public" view), then you will be approved as soon as
a maintainer sees the email.
2017-04-17 14:52:38 -07:00
2019-01-08 11:58:06 -07:00
- Use this format for commit messages (where `{id}` is the CID (Coverity ID);
([example](https://github.com/neovim/neovim/pull/804))):
```
2021-10-01 12:22:32 -07:00
fix(coverity/{id}): {description}
2019-01-08 11:58:06 -07:00
```
- Search the Neovim commit history to find examples:
2023-07-07 05:52:30 -07:00
```bash
2019-01-08 11:58:06 -07:00
git log --oneline --no-merges --grep coverity
```
2021-08-28 14:00:54 -07:00
2023-11-04 09:33:22 -07:00
### Sanitizers (ASAN and UBSAN)
2017-04-17 14:52:38 -07:00
2021-06-30 05:57:52 -07:00
ASAN/UBSAN can be used to detect memory errors and other common forms of undefined behavior at runtime in debug builds.
2021-08-28 14:00:54 -07:00
- To build Neovim with sanitizers enabled, use
2021-06-30 05:57:52 -07:00
```
2023-03-16 11:24:04 -07:00
rm -rf build & & CMAKE_EXTRA_FLAGS="-DCMAKE_C_COMPILER=clang -DENABLE_ASAN_UBSAN=1" make
2021-06-30 05:57:52 -07:00
```
2021-08-28 14:00:54 -07:00
- When running Neovim, use
2021-06-30 05:57:52 -07:00
```
2023-04-21 18:27:32 -07:00
ASAN_OPTIONS=log_path=/tmp/nvim_asan nvim args...
2021-06-30 05:57:52 -07:00
```
2021-08-28 14:00:54 -07:00
- If Neovim exits unexpectedly, check `/tmp/nvim_asan.{PID}` (or your preferred `log_path` ) for log files with error messages.
2019-07-19 12:32:04 -07:00
Coding
------
### Lint
You can run the linter locally by:
2023-07-07 05:52:30 -07:00
```bash
make lint
```
2019-07-19 12:32:04 -07:00
### Style
2022-08-02 03:32:57 -07:00
- You can format files by using:
2023-07-07 05:52:30 -07:00
```bash
make format # or formatc, formatlua
2022-08-23 06:18:05 -07:00
```
This will format changed Lua and C files with all appropriate flags set.
2021-09-24 12:19:34 -07:00
- Style rules are (mostly) defined by `src/uncrustify.cfg` which tries to match
the [style-guide]. To use the Nvim `gq` command with `uncrustify` :
2023-07-07 05:52:30 -07:00
```vim
2021-10-02 14:32:18 -07:00
if !empty(findfile('src/uncrustify.cfg', ';'))
setlocal formatprg=uncrustify\ -q\ -l\ C\ -c\ src/uncrustify.cfg\ --no-backup
2021-09-24 12:19:34 -07:00
endif
```
- There is also `.clang-format` which has drifted from the [style-guide], but
is available for reference. To use the Nvim `gq` command with `clang-format` :
2023-07-07 05:52:30 -07:00
```vim
2021-09-24 12:19:34 -07:00
if !empty(findfile('.clang-format', ';'))
setlocal formatprg=clang-format\ -style=file
endif
```
2019-07-19 12:32:04 -07:00
### Navigate
2023-07-07 05:52:30 -07:00
- Set `blame.ignoreRevsFile` to ignore [noisy commits ](https://github.com/neovim/neovim/commit/2d240024acbd68c2d3f82bc72cb12b1a4928c6bf ) in git blame:
```bash
2021-08-28 14:00:54 -07:00
git config blame.ignoreRevsFile .git-blame-ignore-revs
```
2022-08-23 06:18:05 -07:00
- Recommendation is to use ** [clangd]**.
Can use the maintained config in [nvim-lspconfig/clangd].
2019-07-19 12:32:04 -07:00
- Explore the source code [on the web ](https://sourcegraph.com/github.com/neovim/neovim ).
2022-08-23 06:18:05 -07:00
### Includes
For managing includes in C files, use [include-what-you-use].
- [Install include-what-you-use][include-what-you-use-install]
2023-01-19 02:34:45 -07:00
- To see which includes needs fixing use the cmake preset `iwyu` :
2023-07-07 05:52:30 -07:00
```bash
2023-03-11 11:21:54 -07:00
cmake --preset iwyu
2023-08-26 02:20:40 -07:00
cmake --build build
2022-09-11 08:12:44 -07:00
```
- There's also a make target that automatically fixes the suggestions from
IWYU:
2023-07-07 05:52:30 -07:00
```bash
2022-09-11 08:12:44 -07:00
make iwyu
2022-08-23 06:18:05 -07:00
```
See [#549][549] for more details.
2019-07-19 12:32:04 -07:00
2023-06-19 02:24:44 -07:00
### Lua runtime files
Most of the Lua core [`runtime/` ](./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:
2023-07-07 05:52:30 -07:00
```bash
VIMRUNTIME=./runtime ./build/bin/nvim --luamod-dev
```
2023-06-19 02:24:44 -07:00
2023-09-20 04:15:23 -07:00
Documentation
-------------
2022-08-25 00:06:37 -07:00
2023-06-19 02:24:44 -07:00
Read [:help dev-doc][dev-doc-guide] to understand the expected documentation style and conventions.
2022-08-25 00:06:37 -07:00
2023-06-19 02:24:44 -07:00
### Generating :help
2022-08-25 00:06:37 -07:00
2023-08-17 03:14:58 -07:00
Many `:help` docs are autogenerated from (C or Lua) docstrings. To generate the documentation run:
2022-08-25 00:06:37 -07:00
2023-07-07 05:52:30 -07:00
```bash
2023-08-17 03:14:58 -07:00
make doc
2023-07-07 05:52:30 -07:00
```
2022-08-25 00:06:37 -07:00
2024-01-28 15:22:39 -07:00
To validate the documentation files, run:
```bash
make lintdoc
```
2023-08-17 03:14:58 -07:00
If you need to modify or debug the documentation flow, these are the main files:
2024-02-15 10:16:04 -07:00
- `./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
2023-08-17 03:14:58 -07:00
- `./scripts/gen_eval_files.lua` :
2023-09-20 04:15:23 -07:00
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
```
2023-08-17 03:14:58 -07:00
2024-01-28 15:22:39 -07:00
- `./scripts/lintdoc.lua` : Validation and linting of documentation files.
2023-06-19 02:24:44 -07:00
### Lua docstrings
2022-08-25 00:06:37 -07:00
2023-08-03 04:41:47 -07:00
Use [LuaLS] annotations in Lua docstrings to annotate parameter types, return
2024-01-18 01:14:48 -07:00
types, etc. See [:help dev-lua-doc][dev-lua-doc].
2022-08-25 00:06:37 -07:00
2023-06-19 02:24:44 -07:00
- The template for function documentation is:
```lua
--- {Brief}
---
--- {Long explanation}
---
2023-09-27 21:57:22 -07:00
--- @param arg1 type {description}
--- @param arg2 type {description}
2023-06-19 02:24:44 -07:00
--- ...
---
2023-09-27 21:57:22 -07:00
--- @return type {description}
2023-06-19 02:24:44 -07:00
```
- If possible, add type information (`table`, `string` , `number` , ...). Multiple valid types are separated by a bar (`string|table`). Indicate optional parameters via `type|nil` .
2023-07-12 10:27:14 -07:00
- 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` .
2022-08-25 00:06:37 -07:00
2024-03-18 04:23:53 -07:00
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:
```bash
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 requires running `make distclean` the first time once to remove traces of
the previous build. Hash checking is always skipped in this case regardless of
`DEPS_IGNORE_SHA` .
```bash
LUAJIT_URL /home/user/luajit
```
2016-08-09 21:47:04 -07:00
Reviewing
---------
2016-06-03 12:05:44 -07:00
2015-03-09 16:20:15 -07:00
Reviewing can be done on GitHub, but you may find it easier to do locally.
2021-12-01 17:28:05 -07:00
Using [GitHub CLI][gh], you can create a new branch with the contents of a pull
2016-06-03 12:05:44 -07:00
request, e.g. [#1820][1820]:
2014-05-07 19:33:41 -07:00
2023-07-07 05:52:30 -07:00
```bash
gh pr checkout https://github.com/neovim/neovim/pull/1820
```
2015-03-09 16:20:15 -07:00
Use [`git log -p master..FETCH_HEAD`][git-history-filtering] 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.
2022-08-23 06:18:05 -07:00
[549]: https://github.com/neovim/neovim/issues/549
[1820]: https://github.com/neovim/neovim/pull/1820
[3174]: https://github.com/neovim/neovim/issues/3174
[ASan]: http://clang.llvm.org/docs/AddressSanitizer.html
2022-09-08 15:12:42 -07:00
[Cirrus CI]: https://cirrus-ci.com/github/neovim/neovim
2022-08-23 06:18:05 -07:00
[Clang report]: https://neovim.io/doc/reports/clang/
[GitHub Actions]: https://github.com/neovim/neovim/actions
[clangd]: https://clangd.llvm.org
2023-12-12 14:48:48 -07:00
[Merge a Vim patch]: https://neovim.io/doc/user/dev_vimpatch.html
2022-08-23 06:18:05 -07:00
[complexity:low]: https://github.com/neovim/neovim/issues?q=is%3Aopen+is%3Aissue+label%3Acomplexity%3Alow
[conventional_commits]: https://www.conventionalcommits.org
2023-06-19 02:24:44 -07:00
[dev-doc-guide]: https://neovim.io/doc/user/develop.html#dev-doc
2024-01-18 01:14:48 -07:00
[dev-lua-doc]: https://neovim.io/doc/user/develop.html#dev-lua-doc
[LuaLS]: https://luals.github.io/wiki/annotations/
2015-03-09 16:20:15 -07:00
[gcc-warnings]: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
2022-08-23 06:18:05 -07:00
[gh]: https://cli.github.com/
2017-12-27 11:30:23 -07:00
[git-bisect]: http://git-scm.com/book/en/v2/Git-Tools-Debugging-with-Git
2015-03-09 16:20:15 -07:00
[git-feature-branch]: https://www.atlassian.com/git/tutorials/comparing-workflows
[git-history-filtering]: https://www.atlassian.com/git/tutorials/git-log/filtering-the-commit-history
[github-issues]: https://github.com/neovim/neovim/issues
2022-08-23 06:18:05 -07:00
[include-what-you-use-install]: https://github.com/include-what-you-use/include-what-you-use#how-to-install
[include-what-you-use]: https://github.com/include-what-you-use/include-what-you-use#using-with-cmake
[lua-language-server]: https://github.com/sumneko/lua-language-server/
[nvim-lspconfig/clangd]: https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#clangd
2021-08-17 05:58:49 -07:00
[pr-draft]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request
[pr-ready]: https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request
2022-08-23 06:18:05 -07:00
[run-tests]: https://github.com/neovim/neovim/blob/master/test/README.md#running-tests
[style-guide]: https://neovim.io/doc/user/dev_style.html#dev-style
2023-12-13 09:31:39 -07:00
[wiki-faq]: https://neovim.io/doc/user/faq.html