mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	docs #15447
- update ":help 'hidden'" #15410 - update ":help K" #15398 - try to capture some of the debug steps from #12036 (bpftrace, USDT probes)
This commit is contained in:
		| @@ -11,6 +11,7 @@ low-risk/isolated tasks: | |||||||
| - Try a [good first issue](../../labels/good-first-issue) or [complexity:low] issue. | - Try a [good first issue](../../labels/good-first-issue) or [complexity:low] issue. | ||||||
| - Fix bugs found by [Clang](#clang-scan-build), [PVS](#pvs-studio) or | - Fix bugs found by [Clang](#clang-scan-build), [PVS](#pvs-studio) or | ||||||
|   [Coverity](#coverity). |   [Coverity](#coverity). | ||||||
|  | - [Improve documentation][wiki-contribute-help] | ||||||
|  |  | ||||||
| Reporting problems | Reporting problems | ||||||
| ------------------ | ------------------ | ||||||
| @@ -18,17 +19,17 @@ Reporting problems | |||||||
| - [Check the FAQ][wiki-faq]. | - [Check the FAQ][wiki-faq]. | ||||||
| - [Search existing issues][github-issues] (including closed!) | - [Search existing issues][github-issues] (including closed!) | ||||||
| - Update Neovim to the latest version to see if your problem persists. | - Update Neovim to the latest version to see if your problem persists. | ||||||
| - Disable plugins incrementally, to narrow down the cause of the issue. | - [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. | ||||||
| - When reporting a crash, [include a stacktrace](https://github.com/neovim/neovim/wiki/FAQ#backtrace-linux). | - When reporting a crash, [include a stacktrace](https://github.com/neovim/neovim/wiki/FAQ#backtrace-linux). | ||||||
| - Use [ASAN/UBSAN](#clang-sanitizers-asan-and-ubsan) to get detailed errors for segfaults and undefined behavior. | - Use [ASAN/UBSAN](#clang-sanitizers-asan-and-ubsan) to get detailed errors for segfaults and undefined behavior. | ||||||
| - [Bisect][git-bisect] to the cause of a regression, if you are able. This is _extremely_ helpful. | - Check the logs. `:edit $NVIM_LOG_FILE` | ||||||
| - Check `$NVIM_LOG_FILE`, if it exists. |  | ||||||
| - Include `cmake --system-information` for build-related issues. | - Include `cmake --system-information` for build-related issues. | ||||||
|  |  | ||||||
| Developer guidelines | Developer guidelines | ||||||
| -------------------- | -------------------- | ||||||
|  |  | ||||||
| - Nvim contributors should read `:help dev`. | - Nvim developers should read `:help dev`. | ||||||
| - External UI developers should read `:help dev-ui`. | - External UI developers should read `:help dev-ui`. | ||||||
| - API client developers should read `:help dev-api-client`. | - API client developers should read `:help dev-api-client`. | ||||||
| - Nvim developers are _strongly encouraged_ to install `ninja` for faster builds. | - Nvim developers are _strongly encouraged_ to install `ninja` for faster builds. | ||||||
| @@ -37,13 +38,12 @@ Developer guidelines | |||||||
|   make distclean |   make distclean | ||||||
|   make  # Nvim build system uses ninja automatically, if available. |   make  # Nvim build system uses ninja automatically, if available. | ||||||
|   ``` |   ``` | ||||||
| - [Improve documentation][wiki-contribute-help] |  | ||||||
|  |  | ||||||
| Pull requests (PRs) | Pull requests (PRs) | ||||||
| --------------------- | --------------------- | ||||||
|  |  | ||||||
| - To avoid duplicate work, create a draft pull request as soon as possible. | - To avoid duplicate work, create a draft pull request. | ||||||
| - Your PR must include **test coverage.** See [test/README.md][run-tests]. | - Your PR must include [test coverage][run-tests]. | ||||||
| - Avoid cosmetic changes to unrelated files in the same commit. | - Avoid cosmetic changes to unrelated files in the same commit. | ||||||
| - Use a [feature branch][git-feature-branch] instead of the master branch. | - Use a [feature branch][git-feature-branch] instead of the master branch. | ||||||
| - Use a **rebase workflow** for small PRs. | - Use a **rebase workflow** for small PRs. | ||||||
| @@ -68,21 +68,19 @@ Pull requests have two stages: Draft and Ready for review. | |||||||
|  |  | ||||||
| 1. [Create a Draft PR][pr-draft] while you are _not_ requesting feedback as | 1. [Create a Draft PR][pr-draft] while you are _not_ requesting feedback as | ||||||
|   you are still working on the PR. |   you are still working on the PR. | ||||||
|  |     - You can skip this if your PR is ready for review. | ||||||
| 2. [Change your PR to ready][pr-ready] when the PR is ready for review. | 2. [Change your PR to ready][pr-ready] when the PR is ready for review. | ||||||
|  |     - You can convert back to Draft at any time. | ||||||
|  |  | ||||||
| You can convert the state of your PR back to Draft (or Ready for review) at any | Do __not__ add labels like `[RFC]` or `[WIP]` in the title to indicate the | ||||||
| time. You can also skip the Draft stage if your PR is ready for review from the |  | ||||||
| beginning. |  | ||||||
|  |  | ||||||
| Do __not__ add any 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 | state of your PR: this just adds noise. Non-Draft PRs are assumed to be open | ||||||
| for comments by default; if you want feedback from specific people, `@`-ping | for comments; if you want feedback from specific people, `@`-mention them in | ||||||
| them in a comment. | a comment. | ||||||
|  |  | ||||||
| ### Commit messages | ### Commit messages | ||||||
|  |  | ||||||
| Follow the [conventional commits guidelines][conventional_commits] to *make reviews easier* and to make | Follow the [conventional commits guidelines][conventional_commits] to *make reviews easier* and to make | ||||||
| the VCS/git logs more valuable. The general structure of a commit message is as follows: | the VCS/git logs more valuable. The general structure of a commit message is: | ||||||
|  |  | ||||||
| ``` | ``` | ||||||
| <type>([optional scope]): <description> | <type>([optional scope]): <description> | ||||||
| @@ -92,43 +90,27 @@ the VCS/git logs more valuable. The general structure of a commit message is as | |||||||
| [optional footer(s)] | [optional footer(s)] | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| - Prefix the commit subject with one of the following _types_: | - Prefix the commit subject with one of these [_types_](https://github.com/commitizen/conventional-commit-types/blob/master/index.json): | ||||||
|     - `build`: all changes related to the build system (involving scripts, configurations or tools) and package dependencies. |     - `build`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `test`, `vim-patch`, `chore` | ||||||
|     - `ci`: all changes related to the continuous integration and deployment system - involving scripts, configurations or tools. |     - You can **ignore this for "fixup" commits** or any commits you expect to be squashed. | ||||||
|     - `docs`: all documentation changes. This includes both external documentation for users as well as internal documentation for developers. | - Append optional scope to _type_ such as `(lsp)`, `(treesitter)`, `(float)`, … | ||||||
|     - `feat`: new abilities or functionality. | - _Description_ shouldn't start with a capital letter or end in a period. | ||||||
|     - `fix`: a bug fix. |  | ||||||
|     - `perf`: performance improvements. |  | ||||||
|     - `refactor`: modification of the code base which neither adds a feature nor fixes a bug - such as removing redundant code, simplifying code, renaming variables, etc. |  | ||||||
|     - `revert`: revert previous commits. |  | ||||||
|     - `test`: all changes related to tests such as refactoring existing tests or adding new tests. |  | ||||||
|     - `vim-patch`: all patches from upstream Vim. The commit messages for patches has [slightly different rules](https://github.com/neovim/neovim/wiki/Merging-patches-from-upstream-Vim#pull-requests) as not to interfere with existing scripts. |  | ||||||
|     - `chore`: Lastly, if none of the types above fits you may use `chore` as the type. |  | ||||||
|  |  | ||||||
| - Append optional scope to _type_ such as `(lsp)`, `(treesitter)`, `(float)`, ... |  | ||||||
|  |  | ||||||
| - The _description_ shouldn't start with a capital letter or end in a period. |  | ||||||
|  |  | ||||||
| - Try to keep the first line under 72 characters. |  | ||||||
|  |  | ||||||
| - A blank line must separate the subject from the description. |  | ||||||
|  |  | ||||||
| - A breaking API change must be indicated by appending `!` after the type/scope and at the very beginning of the footer with a **BREAKING CHANGE**. |  | ||||||
|  |  | ||||||
|     Example: |  | ||||||
|  |  | ||||||
|     ``` |  | ||||||
|     refactor(provider)!: drop support for Python 2 |  | ||||||
|  |  | ||||||
|     BREAKING CHANGE: refactor to use Python 3 features since Python 2 is no longer supported. |  | ||||||
|     ``` |  | ||||||
|  |  | ||||||
| - Use the _imperative voice_: "Fix bug" rather than "Fixed bug" or "Fixes bug." | - Use the _imperative voice_: "Fix bug" rather than "Fixed bug" or "Fixes bug." | ||||||
|  | - Try to keep the first line under 72 characters. | ||||||
|  | - 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 | ||||||
|  |  | ||||||
|  |        BREAKING CHANGE: refactor to use Python 3 features since Python 2 is no longer supported. | ||||||
|  |        ``` | ||||||
|  |  | ||||||
| ### Automated builds (CI) | ### Automated builds (CI) | ||||||
|  |  | ||||||
| Each pull request must pass the automated builds on [Travis CI], [sourcehut] | Each pull request must pass the automated builds on [sourcehut] and [GitHub Actions]. | ||||||
| and [AppVeyor]. |  | ||||||
|  |  | ||||||
| - CI builds are compiled with [`-Werror`][gcc-warnings], so compiler warnings | - CI builds are compiled with [`-Werror`][gcc-warnings], so compiler warnings | ||||||
|   will fail the build. |   will fail the build. | ||||||
| @@ -282,9 +264,8 @@ as context, use the `-W` argument as well. | |||||||
| [wiki-faq]: https://github.com/neovim/neovim/wiki/FAQ | [wiki-faq]: https://github.com/neovim/neovim/wiki/FAQ | ||||||
| [review-checklist]: https://github.com/neovim/neovim/wiki/Code-review-checklist | [review-checklist]: https://github.com/neovim/neovim/wiki/Code-review-checklist | ||||||
| [3174]: https://github.com/neovim/neovim/issues/3174 | [3174]: https://github.com/neovim/neovim/issues/3174 | ||||||
| [Travis CI]: https://travis-ci.org/neovim/neovim |  | ||||||
| [sourcehut]: https://builds.sr.ht/~jmk | [sourcehut]: https://builds.sr.ht/~jmk | ||||||
| [AppVeyor]: https://ci.appveyor.com/project/neovim/neovim | [GitHub Actions]: https://github.com/neovim/neovim/actions | ||||||
| [Merge a Vim patch]: https://github.com/neovim/neovim/wiki/Merging-patches-from-upstream-Vim | [Merge a Vim patch]: https://github.com/neovim/neovim/wiki/Merging-patches-from-upstream-Vim | ||||||
| [Clang report]: https://neovim.io/doc/reports/clang/ | [Clang report]: https://neovim.io/doc/reports/clang/ | ||||||
| [complexity:low]: https://github.com/neovim/neovim/issues?q=is%3Aopen+is%3Aissue+label%3Acomplexity%3Alow | [complexity:low]: https://github.com/neovim/neovim/issues?q=is%3Aopen+is%3Aissue+label%3Acomplexity%3Alow | ||||||
|   | |||||||
| @@ -64,7 +64,7 @@ To install to a non-default location: | |||||||
|     make CMAKE_INSTALL_PREFIX=/full/path/ |     make CMAKE_INSTALL_PREFIX=/full/path/ | ||||||
|     make install |     make install | ||||||
|  |  | ||||||
| To inspect the build, these CMake features are useful: | CMake hints for inspecting the build: | ||||||
|  |  | ||||||
| - `cmake --build build --target help` lists all build targets. | - `cmake --build build --target help` lists all build targets. | ||||||
| - `build/CMakeCache.txt` (or `cmake -LAH build/`) contains the resolved values of all CMake variables. | - `build/CMakeCache.txt` (or `cmake -LAH build/`) contains the resolved values of all CMake variables. | ||||||
|   | |||||||
| @@ -46,7 +46,7 @@ NVIM IS... WELL DOCUMENTED				*design-documented* | |||||||
|   item is easier to find. |   item is easier to find. | ||||||
|  |  | ||||||
|  |  | ||||||
| NVIM IS... HIGH SPEED AND SMALL IN SIZE			*design-speed-size* | NVIM IS... FAST AND SMALL				*design-speed-size* | ||||||
|  |  | ||||||
| Keep Nvim small and fast. | Keep Nvim small and fast. | ||||||
| - Computers are becoming faster and bigger each year.  Vim can grow too, but | - Computers are becoming faster and bigger each year.  Vim can grow too, but | ||||||
|   | |||||||
| @@ -3080,17 +3080,16 @@ A jump table for the options with a short description can be found at |Q_op|. | |||||||
| 				     *'hidden'* *'hid'* *'nohidden'* *'nohid'* | 				     *'hidden'* *'hid'* *'nohidden'* *'nohid'* | ||||||
| 'hidden' 'hid'		boolean	(default on) | 'hidden' 'hid'		boolean	(default on) | ||||||
| 			global | 			global | ||||||
| 	When off a buffer is unloaded when it is |abandon|ed.  When on a | 	When off a buffer is unloaded (including loss of undo information) | ||||||
| 	buffer becomes hidden when it is |abandon|ed.  If the buffer is still | 	when it is |abandon|ed.  When on a buffer becomes hidden when it is | ||||||
| 	displayed in another window, it does not become hidden, of course. | 	|abandon|ed.  A buffer displayed in another window does not become | ||||||
| 	The commands that move through the buffer list sometimes make a buffer | 	hidden, of course. | ||||||
| 	hidden although the 'hidden' option is off: When the buffer is | 	Commands that move through the buffer list sometimes hide a buffer | ||||||
| 	modified, 'autowrite' is off or writing is not possible, and the '!' | 	although the 'hidden' option is off: when the buffer is modified, | ||||||
| 	flag was used.  See also |windows.txt|. | 	'autowrite' is off or writing is not possible, and the '!' flag was | ||||||
| 	To only make one buffer hidden use the 'bufhidden' option. | 	used.  See also |windows|. | ||||||
| 	This option is set for one command with ":hide {command}" |:hide|. | 	To hide a specific buffer use the 'bufhidden' option. | ||||||
| 	WARNING: It's easy to forget that you have changes in hidden buffers. | 	'hidden' is set for one command with ":hide {command}" |:hide|. | ||||||
| 	Think twice when using ":q!" or ":qa!". |  | ||||||
|  |  | ||||||
| 						*'history'* *'hi'* | 						*'history'* *'hi'* | ||||||
| 'history' 'hi'		number	(Vim default: 10000, Vi default: 0) | 'history' 'hi'		number	(Vim default: 10000, Vi default: 0) | ||||||
|   | |||||||
| @@ -460,20 +460,14 @@ defined while executing a function, user command or autocommand, the script in | |||||||
| which it was defined is reported. | which it was defined is reported. | ||||||
|  |  | ||||||
| 							*K* | 							*K* | ||||||
| [count]K       		Run a program to lookup the keyword under the | [count]K       		Runs the program given by 'keywordprg' to lookup the | ||||||
| 			cursor.  The name of the program is given with the | 			|word| (defined by 'iskeyword') under or right of the | ||||||
| 			'keywordprg' (kp) option (default is "man").  The | 			cursor. Default is "man". Works like this: > | ||||||
| 			keyword is formed of letters, numbers and the | 				:tabnew | terminal {program} {keyword} | ||||||
| 			characters in 'iskeyword'.  The keyword under or |  | ||||||
| 			right of the cursor is used.  The same can be done |  | ||||||
| 			with the command > |  | ||||||
| 				:!{program} {keyword} |  | ||||||
| <			Special cases: | <			Special cases: | ||||||
| 			- If 'keywordprg' begins with ":" it is invoked as | 			- If 'keywordprg' begins with ":" it is invoked as | ||||||
| 			  a Vim command with [count]. | 			  a Vim command with [count]. | ||||||
| 			- If 'keywordprg' is empty, the ":help" command is | 			- If 'keywordprg' is empty, |:help| is used. | ||||||
| 			  used.  It's a good idea to include more characters |  | ||||||
| 			  in 'iskeyword' then, to be able to find more help. |  | ||||||
| 			- When 'keywordprg' is equal to "man", a [count] | 			- When 'keywordprg' is equal to "man", a [count] | ||||||
| 			  before "K" is inserted after the "man" command and | 			  before "K" is inserted after the "man" command and | ||||||
| 			  before the keyword.  For example, using "2K" while | 			  before the keyword.  For example, using "2K" while | ||||||
|   | |||||||
| @@ -75,8 +75,108 @@ Logs will be written to `${HOME}/logs/*san.PID` then. | |||||||
|  |  | ||||||
| For more information: https://github.com/google/sanitizers/wiki/SanitizerCommonFlags | For more information: https://github.com/google/sanitizers/wiki/SanitizerCommonFlags | ||||||
|  |  | ||||||
| TUI debugging | Debug: Performance | ||||||
| ------------- | ------------------ | ||||||
|  |  | ||||||
|  | ### Profiling (easy) | ||||||
|  |  | ||||||
|  | For debugging performance bottlenecks in any code, there is a simple (and very | ||||||
|  | effective) approach: | ||||||
|  |  | ||||||
|  | 1. Run the slow code in a loop. | ||||||
|  | 2. Break execution ~5 times and save the stacktrace. | ||||||
|  | 3. The cause of the bottleneck will (almost always) appear in most of the stacktraces. | ||||||
|  |  | ||||||
|  | ### Profiling (fancy) | ||||||
|  |  | ||||||
|  | For more advanced profiling, consider `perf` + `flamegraph`. | ||||||
|  |  | ||||||
|  | ### USDT profiling (powerful) | ||||||
|  |  | ||||||
|  | Or you can use USDT probes via `NVIM_PROBE` ([#12036](https://github.com/neovim/neovim/pull/12036)). | ||||||
|  |  | ||||||
|  | > USDT is basically a way to define stable probe points in userland binaries. | ||||||
|  | > The benefit of bcc is the ability to define logic to go along with the probe | ||||||
|  | > points. | ||||||
|  |  | ||||||
|  | Tools: | ||||||
|  | - bpftrace provides an awk-like language to the kernel bytecode, BPF. | ||||||
|  | - BCC provides a subset of C. Provides more complex logic than bpftrace, but takes a bit more effort. | ||||||
|  |  | ||||||
|  | Example using bpftrace to track slow vim functions, and print out any files | ||||||
|  | that were opened during the trace. At the end, it prints a histogram of | ||||||
|  | function timing: | ||||||
|  |  | ||||||
|  |     #!/usr/bin/env bpftrace | ||||||
|  |  | ||||||
|  |     BEGIN { | ||||||
|  |       @depth = -1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     tracepoint:sched:sched_process_fork /@pidmap[args->parent_pid]/ { | ||||||
|  |       @pidmap[args->child_pid] = 1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     tracepoint:sched:sched_process_exit /@pidmap[args->pid]/ { | ||||||
|  |       delete(@pidmap[args->pid]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     usdt:build/bin/nvim:neovim:eval__call_func__entry { | ||||||
|  |         @pidmap[pid] = 1; | ||||||
|  |         @depth++; | ||||||
|  |         @funcentry[@depth] = nsecs; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     usdt:build/bin/nvim:neovim:eval__call_func__return { | ||||||
|  |         $func = str(arg0); | ||||||
|  |         $msecs = (nsecs - @funcentry[@depth]) / 1000000; | ||||||
|  |  | ||||||
|  |         @time_histo = hist($msecs); | ||||||
|  |  | ||||||
|  |         if ($msecs >= 1000) { | ||||||
|  |           printf("%u ms for %s\n", $msecs, $func); | ||||||
|  |           print(@files); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         clear(@files); | ||||||
|  |         delete(@funcentry[@depth]); | ||||||
|  |         @depth--; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     tracepoint:syscalls:sys_enter_open, | ||||||
|  |     tracepoint:syscalls:sys_enter_openat { | ||||||
|  |       if (@pidmap[pid] == 1 && @depth >= 0) { | ||||||
|  |         @files[str(args->filename)] = count(); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     END { | ||||||
|  |       clear(@depth); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $ sudo bpftrace funcslower.bt | ||||||
|  |     1527 ms for Slower | ||||||
|  |     @files[/usr/lib/libstdc++.so.6]: 2 | ||||||
|  |     @files[/etc/fish/config.fish]: 2 | ||||||
|  |     <snip> | ||||||
|  |  | ||||||
|  |     ^C | ||||||
|  |     @time_histo: | ||||||
|  |     [0]                71430 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| | ||||||
|  |     [1]                  346 |                                                    | | ||||||
|  |     [2, 4)               208 |                                                    | | ||||||
|  |     [4, 8)                91 |                                                    | | ||||||
|  |     [8, 16)               22 |                                                    | | ||||||
|  |     [16, 32)              85 |                                                    | | ||||||
|  |     [32, 64)               7 |                                                    | | ||||||
|  |     [64, 128)              0 |                                                    | | ||||||
|  |     [128, 256)             0 |                                                    | | ||||||
|  |     [256, 512)             6 |                                                    | | ||||||
|  |     [512, 1K)              1 |                                                    | | ||||||
|  |     [1K, 2K)               5 |                                                    | | ||||||
|  |  | ||||||
|  | Debug: TUI | ||||||
|  | ---------- | ||||||
|  |  | ||||||
| ### TUI troubleshoot | ### TUI troubleshoot | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Justin M. Keyes
					Justin M. Keyes