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.
2019-01-08 11:58:06 -07:00
- Fix bugs found by [Clang ](#clang-scan-build ), [PVS ](#pvs-studio ) or
[Coverity ](#coverity ).
2021-08-21 18:26:33 -07:00
- [Improve documentation][wiki-contribute-help]
2021-08-02 05:36:10 -07:00
- [Merge a Vim patch] (Familiarity with Vim is *strongly* recommended)
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").
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.
2019-07-19 12:32:04 -07:00
- When reporting a crash, [include a stacktrace ](https://github.com/neovim/neovim/wiki/FAQ#backtrace-linux ).
2021-06-30 05:57:52 -07:00
- Use [ASAN/UBSAN ](#clang-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
--------------------
2021-08-27 03:59:13 -07:00
- Read `:help dev` 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 `ninja` for faster builds of Nvim.
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.
```
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.
2017-04-17 14:52:38 -07:00
- Use a **rebase workflow** for small PRs.
- After addressing review comments, it's fine to rebase and force-push.
- Use a **merge workflow** for big, high-risk PRs.
- Merge `master` into your PR when there are conflicts or when master
introduces breaking changes.
- Use the `ri` git alias:
```
[alias]
2017-05-08 11:28:41 -07:00
ri = "!sh -c 't=\"${1:-master}\"; s=\"${2:-HEAD}\"; mb=\"$(git merge-base \"$t\" \"$s\")\"; if test \"x$mb\" = x ; then o=\"$t\"; else lm=\"$(git log -n1 --merges \"$t..$s\" --pretty=%H)\"; if test \"x$lm\" = x ; then o=\"$mb\"; else o=\"$lm\"; fi; fi; test $# -gt 0 && shift; test $# -gt 0 && shift; git rebase --interactive \"$o\" \"$@\"'"
2017-04-17 14:52:38 -07:00
```
2017-04-06 15:31:39 -07:00
This avoids unnecessary rebases yet still allows you to combine related
commits, separate monolithic commits, etc.
2017-04-17 14:52:38 -07:00
- Do not edit commits that come before the merge commit.
- During a squash/fixup, use `exec make -C build unittest` between each
pick/edit/reword.
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-07-07 15:28:44 -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 ):
- `build` , `ci` , `docs` , `feat` , `fix` , `perf` , `refactor` , `revert` , `test` , `vim-patch` , `chore`
- 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
2016-06-03 12:05:44 -07:00
### Automated builds (CI)
2015-03-09 16:20:15 -07:00
2021-08-21 18:26:33 -07:00
Each pull request must pass the automated builds on [sourcehut] 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.
2016-06-03 12:05:44 -07:00
- If any tests fail, the build will fail.
2017-11-14 02:47:49 -07:00
See [test/README.md#running-tests][run-tests] to run tests locally.
2016-06-03 12:05:44 -07:00
Passing locally doesn't guarantee passing the CI build, because of the
different compilers and platforms tested against.
2017-07-29 09:51:31 -07:00
- CI runs [ASan] and other analyzers.
- To run valgrind locally: `VALGRIND=1 make test`
- To run Clang ASan/UBSan locally: `CC=clang make CMAKE_FLAGS="-DCLANG_ASAN_UBSAN=ON"`
2019-07-19 12:32:04 -07:00
- The [lint ](#lint ) build checks modified lines _and their immediate
neighbors_, to encourage incrementally updating the legacy style to meet our
[style ](#style ). (See [#3174][3174] for background.)
2019-10-19 18:04:08 -07:00
- CI for freebsd and openbsd runs on [sourcehut].
- To get a backtrace on freebsd (after connecting via ssh):
```sh
sudo pkg install tmux # If you want tmux.
lldb build/bin/nvim -c nvim.core
# To get a full backtrace:
# 1. Rebuild with debug info.
rm -rf nvim.core build
2020-11-12 11:20:00 -07:00
gmake CMAKE_BUILD_TYPE=RelWithDebInfo CMAKE_EXTRA_FLAGS="-DCI_BUILD=ON -DMIN_LOG_LEVEL=3" nvim
2019-10-19 18:04:08 -07:00
# 2. Run the failing test to generate a new core file.
TEST_FILE=test/functional/foo.lua gmake functionaltest
lldb build/bin/nvim -c nvim.core
2019-07-19 12:32:04 -07:00
```
2017-01-31 00:53:16 -07:00
2017-06-05 18:43:53 -07:00
### Clang scan-build
2019-01-08 11:58:06 -07:00
View the [Clang report] to see potential bugs found by the Clang
[scan-build ](https://clang-analyzer.llvm.org/scan-build.html ) analyzer.
2017-06-05 18:43:53 -07:00
2019-01-08 11:58:06 -07:00
- Search the Neovim commit history to find examples:
```
git log --oneline --no-merges --grep clang
```
- To verify a fix locally, run `scan-build` like this:
```
rm -rf build/
scan-build --use-analyzer=/usr/bin/clang make
```
2015-03-09 16:20:15 -07:00
2019-01-08 11:58:06 -07:00
### PVS-Studio
2015-03-09 16:20:15 -07:00
2019-01-08 11:58:06 -07:00
View the [PVS report ](https://neovim.io/doc/reports/pvs/PVS-studio.html.d/ ) to
see potential bugs found by [PVS Studio ](https://www.viva64.com/en/pvs-studio/ ).
2015-03-09 16:20:15 -07:00
2019-01-08 11:58:06 -07:00
- Use this format for commit messages (where `{id}` is the PVS warning-id)):
```
2021-10-01 12:22:32 -07:00
fix(PVS/V{id}): {description}
2019-01-08 11:58:06 -07:00
```
- Search the Neovim commit history to find examples:
```
git log --oneline --no-merges --grep PVS
```
- Try `./scripts/pvscheck.sh` to run PVS locally.
2015-03-09 16:20:15 -07:00
2019-01-08 11:58:06 -07:00
### Coverity
2016-06-03 12:05:44 -07:00
2019-01-08 11:58:06 -07:00
[Coverity ](https://scan.coverity.com/projects/neovim-neovim ) runs against the
master build. To view the defects, just request access; you will be approved.
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:
```
git log --oneline --no-merges --grep coverity
```
2021-08-28 14:00:54 -07:00
2021-06-30 05:57:52 -07:00
### Clang 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
```
rm -rf build & & CMAKE_EXTRA_FLAGS="-DCMAKE_C_COMPILER=clang -DCLANG_ASAN_UBSAN=1" make
```
2021-08-28 14:00:54 -07:00
- When running Neovim, use
2021-06-30 05:57:52 -07:00
```
UBSAN_OPTIONS=print_stacktrace=1 ASAN_OPTIONS=log_path=/tmp/nvim_asan nvim args...
```
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:
make lint
The lint step downloads the [master error list] and excludes them, so only lint
errors related to the local changes are reported.
You can lint a single file (but this will _not_ exclude legacy errors):
./src/clint.py src/nvim/ops.c
### Style
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` :
```
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
```
2021-10-02 14:32:18 -07:00
The required version of `uncrustify` is specified in `uncrustify.cfg` .
2021-09-24 12:19:34 -07:00
- 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` :
```
if !empty(findfile('.clang-format', ';'))
setlocal formatprg=clang-format\ -style=file
endif
```
2019-07-19 12:32:04 -07:00
### Navigate
2021-08-28 14:00:54 -07:00
- Set `blame.ignoreRevsFile` to ignore [noise commits ](https://github.com/neovim/neovim/commit/2d240024acbd68c2d3f82bc72cb12b1a4928c6bf ) in git blame:
```
git config blame.ignoreRevsFile .git-blame-ignore-revs
```
2019-07-19 12:32:04 -07:00
- Use ** [universal-ctags ](https://github.com/universal-ctags/ctags ).**
("Exuberant ctags", the typical `ctags` binary provided by your distro, is
unmaintained and won't recognize many function signatures in Neovim source.)
- Explore the source code [on the web ](https://sourcegraph.com/github.com/neovim/neovim ).
2021-12-01 12:09:50 -07:00
- If using [lua-language-server][], symlink `contrib/luarc.json` into the
project root:
$ ln -s contrib/luarc.json .luarc.json
2019-07-19 12:32:04 -07:00
2016-08-09 21:47:04 -07:00
Reviewing
---------
2016-06-03 12:05:44 -07:00
To help review pull requests, start with [this checklist][review-checklist].
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
2021-12-01 17:28:05 -07:00
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.
[gcc-warnings]: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
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
[git-history-rewriting]: http://git-scm.com/book/en/v2/Git-Tools-Rewriting-History
[git-rebasing]: http://git-scm.com/book/en/v2/Git-Branching-Rebasing
[github-issues]: https://github.com/neovim/neovim/issues
2016-06-03 12:05:44 -07:00
[1820]: https://github.com/neovim/neovim/pull/1820
2021-12-01 17:28:05 -07:00
[gh]: https://cli.github.com/
2021-06-10 10:08:58 -07:00
[conventional_commits]: https://www.conventionalcommits.org
2021-09-24 12:19:34 -07:00
[style-guide]: https://neovim.io/doc/user/dev_style.html#dev-style
2016-06-03 12:05:44 -07:00
[ASan]: http://clang.llvm.org/docs/AddressSanitizer.html
2017-11-14 02:47:49 -07:00
[run-tests]: https://github.com/neovim/neovim/blob/master/test/README.md#running-tests
2015-04-21 14:35:06 -07:00
[wiki-faq]: https://github.com/neovim/neovim/wiki/FAQ
2016-06-03 12:05:44 -07:00
[review-checklist]: https://github.com/neovim/neovim/wiki/Code-review-checklist
[3174]: https://github.com/neovim/neovim/issues/3174
2019-10-19 18:04:08 -07:00
[sourcehut]: https://builds.sr.ht/~jmk
2021-08-21 18:26:33 -07:00
[GitHub Actions]: https://github.com/neovim/neovim/actions
2017-06-06 06:02:51 -07:00
[Merge a Vim patch]: https://github.com/neovim/neovim/wiki/Merging-patches-from-upstream-Vim
2019-01-08 11:58:06 -07:00
[Clang report]: https://neovim.io/doc/reports/clang/
2016-08-09 21:47:04 -07:00
[complexity:low]: https://github.com/neovim/neovim/issues?q=is%3Aopen+is%3Aissue+label%3Acomplexity%3Alow
2019-07-19 12:32:04 -07:00
[master error list]: https://raw.githubusercontent.com/neovim/doc/gh-pages/reports/clint/errors.json
2021-01-27 13:15:52 -07:00
[wiki-contribute-help]: https://github.com/neovim/neovim/wiki/contribute-%3Ahelp
2021-08-17 05:58:49 -07:00
[pr-draft]: https://docs.github.com/en/github/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
2021-12-01 17:28:05 -07:00
[uncrustify]: http://uncrustify.sourceforge.net/
2021-12-01 12:09:50 -07:00
[lua-language-server]: https://github.com/sumneko/lua-language-server/