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. | ||||
| - Fix bugs found by [Clang](#clang-scan-build), [PVS](#pvs-studio) or | ||||
|   [Coverity](#coverity). | ||||
| - [Improve documentation][wiki-contribute-help] | ||||
|  | ||||
| Reporting problems | ||||
| ------------------ | ||||
| @@ -18,17 +19,17 @@ 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. | ||||
| - 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). | ||||
| - 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 `$NVIM_LOG_FILE`, if it exists. | ||||
| - Check the logs. `:edit $NVIM_LOG_FILE` | ||||
| - Include `cmake --system-information` for build-related issues. | ||||
|  | ||||
| Developer guidelines | ||||
| -------------------- | ||||
|  | ||||
| - Nvim contributors should read `:help dev`. | ||||
| - Nvim developers should read `:help dev`. | ||||
| - External UI developers should read `:help dev-ui`. | ||||
| - API client developers should read `:help dev-api-client`. | ||||
| - Nvim developers are _strongly encouraged_ to install `ninja` for faster builds. | ||||
| @@ -37,13 +38,12 @@ Developer guidelines | ||||
|   make distclean | ||||
|   make  # Nvim build system uses ninja automatically, if available. | ||||
|   ``` | ||||
| - [Improve documentation][wiki-contribute-help] | ||||
|  | ||||
| Pull requests (PRs) | ||||
| --------------------- | ||||
|  | ||||
| - To avoid duplicate work, create a draft pull request as soon as possible. | ||||
| - Your PR must include **test coverage.** See [test/README.md][run-tests]. | ||||
| - To avoid duplicate work, create a draft pull request. | ||||
| - Your PR must include [test coverage][run-tests]. | ||||
| - Avoid cosmetic changes to unrelated files in the same commit. | ||||
| - Use a [feature branch][git-feature-branch] instead of the master branch. | ||||
| - 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 | ||||
|   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. | ||||
|     - 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 | ||||
| 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 | ||||
| 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 by default; if you want feedback from specific people, `@`-ping | ||||
| them in a comment. | ||||
| for comments; if you want feedback from specific people, `@`-mention them in | ||||
| a comment. | ||||
|  | ||||
| ### Commit messages | ||||
|  | ||||
| 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> | ||||
| @@ -92,43 +90,27 @@ the VCS/git logs more valuable. The general structure of a commit message is as | ||||
| [optional footer(s)] | ||||
| ``` | ||||
|  | ||||
| - Prefix the commit subject with one of the following _types_: | ||||
|     - `build`: all changes related to the build system (involving scripts, configurations or tools) and package dependencies. | ||||
|     - `ci`: all changes related to the continuous integration and deployment system - involving scripts, configurations or tools. | ||||
|     - `docs`: all documentation changes. This includes both external documentation for users as well as internal documentation for developers. | ||||
|     - `feat`: new abilities or functionality. | ||||
|     - `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. | ||||
|  | ||||
| - 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." | ||||
| - 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**. | ||||
|  | ||||
| - 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. | ||||
|        ``` | ||||
|  | ||||
| - Use the _imperative voice_: "Fix bug" rather than "Fixed bug" or "Fixes bug." | ||||
|  | ||||
| ### Automated builds (CI) | ||||
|  | ||||
| Each pull request must pass the automated builds on [Travis CI], [sourcehut] | ||||
| and [AppVeyor]. | ||||
| Each pull request must pass the automated builds on [sourcehut] and [GitHub Actions]. | ||||
|  | ||||
| - CI builds are compiled with [`-Werror`][gcc-warnings], so compiler warnings | ||||
|   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 | ||||
| [review-checklist]: https://github.com/neovim/neovim/wiki/Code-review-checklist | ||||
| [3174]: https://github.com/neovim/neovim/issues/3174 | ||||
| [Travis CI]: https://travis-ci.org/neovim/neovim | ||||
| [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 | ||||
| [Clang report]: https://neovim.io/doc/reports/clang/ | ||||
| [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 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. | ||||
| - `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. | ||||
|  | ||||
|  | ||||
| NVIM IS... HIGH SPEED AND SMALL IN SIZE			*design-speed-size* | ||||
| NVIM IS... FAST AND SMALL				*design-speed-size* | ||||
|  | ||||
| Keep Nvim small and fast. | ||||
| - 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'		boolean	(default on) | ||||
| 			global | ||||
| 	When off a buffer is unloaded when it is |abandon|ed.  When on a | ||||
| 	buffer becomes hidden when it is |abandon|ed.  If the buffer is still | ||||
| 	displayed in another window, it does not become hidden, of course. | ||||
| 	The commands that move through the buffer list sometimes make a buffer | ||||
| 	hidden although the 'hidden' option is off: When the buffer is | ||||
| 	modified, 'autowrite' is off or writing is not possible, and the '!' | ||||
| 	flag was used.  See also |windows.txt|. | ||||
| 	To only make one buffer hidden use the 'bufhidden' option. | ||||
| 	This option is set for one command with ":hide {command}" |:hide|. | ||||
| 	WARNING: It's easy to forget that you have changes in hidden buffers. | ||||
| 	Think twice when using ":q!" or ":qa!". | ||||
| 	When off a buffer is unloaded (including loss of undo information) | ||||
| 	when it is |abandon|ed.  When on a buffer becomes hidden when it is | ||||
| 	|abandon|ed.  A buffer displayed in another window does not become | ||||
| 	hidden, of course. | ||||
| 	Commands that move through the buffer list sometimes hide a buffer | ||||
| 	although the 'hidden' option is off: when the buffer is modified, | ||||
| 	'autowrite' is off or writing is not possible, and the '!' flag was | ||||
| 	used.  See also |windows|. | ||||
| 	To hide a specific buffer use the 'bufhidden' option. | ||||
| 	'hidden' is set for one command with ":hide {command}" |:hide|. | ||||
|  | ||||
| 						*'history'* *'hi'* | ||||
| '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. | ||||
|  | ||||
| 							*K* | ||||
| [count]K       		Run a program to lookup the keyword under the | ||||
| 			cursor.  The name of the program is given with the | ||||
| 			'keywordprg' (kp) option (default is "man").  The | ||||
| 			keyword is formed of letters, numbers and the | ||||
| 			characters in 'iskeyword'.  The keyword under or | ||||
| 			right of the cursor is used.  The same can be done | ||||
| 			with the command > | ||||
| 				:!{program} {keyword} | ||||
| [count]K       		Runs the program given by 'keywordprg' to lookup the | ||||
| 			|word| (defined by 'iskeyword') under or right of the | ||||
| 			cursor. Default is "man". Works like this: > | ||||
| 				:tabnew | terminal {program} {keyword} | ||||
| <			Special cases: | ||||
| 			- If 'keywordprg' begins with ":" it is invoked as | ||||
| 			  a Vim command with [count]. | ||||
| 			- If 'keywordprg' is empty, the ":help" command is | ||||
| 			  used.  It's a good idea to include more characters | ||||
| 			  in 'iskeyword' then, to be able to find more help. | ||||
| 			- If 'keywordprg' is empty, |:help| is used. | ||||
| 			- When 'keywordprg' is equal to "man", a [count] | ||||
| 			  before "K" is inserted after the "man" command and | ||||
| 			  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 | ||||
|  | ||||
| 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 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Justin M. Keyes
					Justin M. Keyes