commit ebb7c38ca2e59ca7b413750d83ac1cf38d7bb180
parent 45ca080bd184c826bae5c25911430cb4fa5c5528
Author: Justin M. Keyes <justinkz@gmail.com>
Date: Wed, 26 Nov 2025 01:17:06 -0500
docs: misc
fix https://github.com/neovim/neovim.github.io/issues/419
Co-authored-by: Rob Pilling <robpilling@gmail.com>
Diffstat:
35 files changed, 334 insertions(+), 251 deletions(-)
diff --git a/INSTALL.md b/INSTALL.md
@@ -52,7 +52,7 @@ Several Neovim GUIs are available from scoop (extras): [scoop.sh/#/apps?q=neovim
### Pre-built archives
-0. If you are missing `VCRUNTIME140.dll`, install the [Visual Studio 2015 C++ redistributable](https://support.microsoft.com/en-us/kb/2977003) (choose x86_64 or x86 depending on your system).
+0. If you are missing `VCRUNTIME170.dll`, install the [Visual Studio C++ redistributable](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist) (choose x86_64 or x86 depending on your system).
1. Choose a package (**nvim-winXX.zip**) from the [releases page](https://github.com/neovim/neovim/releases).
2. Unzip the package. Any location is fine, administrator privileges are _not_ required.
- `$VIMRUNTIME` will be set to that location automatically.
diff --git a/MAINTAIN.md b/MAINTAIN.md
@@ -239,6 +239,34 @@ Some github labels are used to trigger certain jobs:
* `needs:response` - close PR after a certain amount of time if author doesn't
respond
+Vim patches
+-----------
+
+Multiple Vim versions are tracked in `version.c`, so that `has('patch-x.y.z')`
+works even if `v:version` is "behind". Whenever we "complete" merging all
+patches from a Vim `v:version`, the steps to bump `v:version` are:
+
+1. Remove the fully-merged version from `version.c:Versions`.
+2. Adjust the regexp in `vim-patch.sh`. For example to remove 8.1:
+ ```diff
+ diff --git a/scripts/vim-patch.sh b/scripts/vim-patch.sh
+ index d64f6b6..1d3dcdf 100755
+ --- a/scripts/vim-patch.sh
+ +++ b/scripts/vim-patch.sh
+ @@ -577,7 +577,7 @@ list_vimpatch_tokens() {
+ # Left-pad the patch number of "vim-patch:xxx" for stable sort + dedupe.
+ # Filter reverted Vim tokens.
+ list_vimpatch_numbers() {
+ - local patch_pat='(8\.[12]|9\.[0-9])\.[0-9]{1,4}'
+ + local patch_pat='(8\.[2]|9\.[0-9])\.[0-9]{1,4}'
+ diff "${NVIM_SOURCE_DIR}/scripts/vimpatch_token_reverts.txt" <(
+ git -C "${NVIM_SOURCE_DIR}" log --format="%s%n%b" -E --grep="^[* ]*vim-patch:${patch_pat}" |
+ grep -oE "^[* ]*vim-patch:${patch_pat}" |
+ ```
+3. Run `nvim -l scripts/vimpatch.lua` to regenerate `version.c`. Or wait for the
+ `vim_patches.yml` CI job to do it.
+
+
See also
--------
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
@@ -1945,7 +1945,7 @@ nvim_parse_expression({expr}, {flags}, {highlight})
• "error": Dict with error, present only if parser saw some error.
Contains the following keys:
• "message": String, error message in printf format, translated.
- Must contain exactly one "%.*s".
+ Must contain exactly one `%.*s`.
• "arg": String, error message argument.
• "len": Amount of bytes successfully parsed. With flags equal to ""
that should be equal to the length of expr string. ("Successfully
@@ -3768,8 +3768,8 @@ nvim_open_win({buffer}, {enter}, {config}) *nvim_open_win()*
current window. If -1 is provided, a top-level split will be created.
`vertical` and `split` are only valid for normal windows, and are used to
control split direction. For `vertical`, the exact direction is determined
- by 'splitright' and 'splitbelow'. Split windows cannot have
- `bufpos`/`row`/`col`/`border`/`title`/`footer` properties.
+ by 'splitright' and 'splitbelow'. Split windows cannot have `bufpos`,
+ `row`, `col`, `border`, `title`, `footer` properties.
With relative=editor (row=0,col=0) refers to the top-left corner of the
screen-grid and (row=Lines-1,col=Columns-1) refers to the bottom-right
@@ -3782,17 +3782,17 @@ nvim_open_win({buffer}, {enter}, {config}) *nvim_open_win()*
could let floats hover outside of the main window like a tooltip, but this
should not be used to specify arbitrary WM screen positions.
- Example: window-relative float >lua
- vim.api.nvim_open_win(0, false,
- {relative='win', row=3, col=3, width=12, height=3})
-<
+ Examples: >lua
+ -- Window-relative float with 'statusline' enabled:
+ local w1 = vim.api.nvim_open_win(0, false,
+ {relative='win', row=3, col=3, width=40, height=4})
+ vim.wo[w1].statusline = vim.o.statusline
- Example: buffer-relative float (travels as buffer is scrolled) >lua
+ -- Buffer-relative float (travels as buffer is scrolled):
vim.api.nvim_open_win(0, false,
- {relative='win', width=12, height=3, bufpos={100,10}})
-<
+ {relative='win', width=40, height=4, bufpos={100,10}})
- Example: vertical split left of the current window >lua
+ -- Vertical split left of the current window:
vim.api.nvim_open_win(0, false, { split = 'left', win = 0, })
<
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
@@ -1047,7 +1047,10 @@ TabClosed After closing a tab page. <afile> expands to
the tab page number.
*TermOpen*
TermOpen When a |terminal| job is starting. Can be
- used to configure the terminal buffer.
+ used to configure the terminal buffer. To get
+ the terminal process details: >lua
+ vim.print(vim.api.nvim_get_chan_info(vim.bo.channel))
+<
*TermEnter*
TermEnter After entering |Terminal-mode|.
After TermOpen.
@@ -1160,11 +1163,11 @@ VimEnter After doing all the startup stuff, including
Just before this event is triggered the
|v:vim_did_enter| variable is set, so that you
can do: >
- if v:vim_did_enter
- call s:init()
- else
- au VimEnter * call s:init()
- endif
+ if v:vim_did_enter
+ call s:init()
+ else
+ au VimEnter * call s:init()
+ endif
< *VimLeave*
VimLeave Before exiting Vim, just after writing the
.shada file. Executed only once, like
diff --git a/runtime/doc/dev_vimpatch.txt b/runtime/doc/dev_vimpatch.txt
@@ -147,7 +147,7 @@ TYPES OF "NOT APPLICABLE" VIM PATCHES ~
https://github.com/neovim/neovim/pull/11996
- Many tests in `test_prompt_buffer.vim` require incompatible Vim features
such as `channel`; they should still be included, but skipped
-- non-runtime documentation: Moved to https://neovim.io/doc/,
+- Non-runtime documentation: Moved to `BUILD.md`, `INSTALL.md`.
- NA files: `Filelist`, `README`, `INSTALL`,
- Anything else might be relevant; err on the side of caution, and post an
issue if you aren't sure.
diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt
@@ -1620,7 +1620,7 @@ There are three different types of searching:
special wildcard when it is at the start of a name.
The usage of "*" is quite simple: It matches 0 or more characters. In a
- search pattern this would be ".*". Note that the "." is not used for file
+ search pattern this would be `.*`. Note that the "." is not used for file
searching.
"**" is more sophisticated:
diff --git a/runtime/doc/faq.txt b/runtime/doc/faq.txt
@@ -462,7 +462,7 @@ WHY EMBED LUA INSTEAD OF X?
See also:
- Why Lua https://web.archive.org/web/20150219224654/https://blog.datamules.com/blog/2012/01/30/why-lua/
-- The Design of Lua https://cacm.acm.org/magazines/2018/11/232214-a-look-at-the-design-of-lua/fulltext
+- The Design of Lua https://cacm.acm.org/research/a-look-at-the-design-of-lua/
- Scripting architecture considerations http://oldblog.antirez.com/post/redis-and-scripting.html
- LuaJIT performance https://julialang.org/benchmarks/
- Discussion of JavaScript vs Lua https://github.com/vim/vim/pull/5198#issuecomment-554693754
diff --git a/runtime/doc/ft_ada.txt b/runtime/doc/ft_ada.txt
@@ -489,7 +489,7 @@ taglist.vim
https://www.vim.org/scripts/script.php?script_id=273
Source code explorer sidebar. There is a patch for Ada available.
-The GNU Ada Project distribution (http://gnuada.sourceforge.net) of Vim
+The GNU Ada Project distribution (https://sourceforge.net/projects/gnuada/) of Vim
contains all of the above.
vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/helphelp.txt b/runtime/doc/helphelp.txt
@@ -481,15 +481,12 @@ aligned on a line.
When referring to an existing help tag and to create a hot-link, place the
name between two bars ("|") eg. |help-writing|.
-When referring to a Vim command and to create a hot-link, place the
-name between two backticks, eg. inside `:filetype`. You will see this is
-highlighted as a command, like a code block (see below).
-
When referring to a Vim option in the help file, place the option name between
two single quotes, eg. 'statusline'
-When referring to any other technical term, such as a filename or function
-parameter, surround it in backticks, eg. `~/.path/to/init.vim`.
+When referring to any other technical term or symbol, such as a filename or
+function parameter, surround it in backticks, eg. `~/.path/to/init.vim`. This
+renders it as "inline" code (as opposed to a "codeblock" |help-codeblock|).
HIGHLIGHTING
diff --git a/runtime/doc/intro.txt b/runtime/doc/intro.txt
@@ -42,7 +42,7 @@ There are many resources to learn Vi, Vim, and Nvim. We recommend:
- "Practical Vim" by Drew Neil. Acclaimed for its focus on quickly learning
common editing tasks with Vim.
- "Modern Vim" by Drew Neil. Explores new features in Nvim and Vim 8.
-- https://vimcasts.org/publications/
+- http://vimcasts.org
- "Vim - Vi Improved" by Steve Oualline. This was the first book dedicated to
Vim. Parts of it were included in the Vim user manual. |frombook| ISBN:
0735710015
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
@@ -1017,8 +1017,11 @@ config({name}, {cfg}) *vim.lsp.config()*
• {cfg} (`vim.lsp.Config`) See |vim.lsp.Config|.
enable({name}, {enable}) *vim.lsp.enable()*
- Auto-starts LSP when a buffer is opened, based on the |lsp-config|
- `filetypes`, `root_markers`, and `root_dir` fields.
+ Auto-activates LSP in each buffer based on the |lsp-config| `filetypes`,
+ `root_markers`, and `root_dir`.
+
+ To disable, pass `enable=false`: Stops related clients and servers
+ (force-stops servers after a timeout, unless `exit_timeout=false`).
Examples: >lua
vim.lsp.enable('clangd')
@@ -1048,10 +1051,11 @@ enable({name}, {enable}) *vim.lsp.enable()*
Parameters: ~
• {name} (`string|string[]`) Name(s) of client(s) to enable.
- • {enable} (`boolean?`) `true|nil` to enable, `false` to disable
- (actively stops and detaches clients as needed, and force
- stops them if necessary after `client.exit_timeout`
- milliseconds)
+ • {enable} (`boolean?`) If `true|nil`, enables auto-activation of the
+ given LSP config on current and future buffers. If `false`,
+ disables auto-activation and stops related LSP clients and
+ servers (force-stops servers after `exit_timeout`
+ milliseconds).
foldclose({kind}, {winid}) *vim.lsp.foldclose()*
Close all {kind} of folds in the the window with {winid}.
@@ -1600,8 +1604,7 @@ Lua module: vim.lsp.client *lsp-client*
before sending kill -15. If set to false,
waits indefinitely. If set to true, nvim will
kill the server immediately.
- • {flags} (`table`) A table with flags for the client.
- The current (experimental) flags are:
+ • {flags} (`table`) Experimental client flags:
• {allow_incremental_sync}? (`boolean`,
default: `true`) Allow using incremental
sync for buffer edits
@@ -1727,8 +1730,7 @@ Lua module: vim.lsp.client *lsp-client*
sending kill -15. If set to false, waits
indefinitely. If set to true, nvim will kill
the server immediately.
- • {flags}? (`table`) A table with flags for the client.
- The current (experimental) flags are:
+ • {flags}? (`table`) Experimental client flags:
• {allow_incremental_sync}? (`boolean`,
default: `true`) Allow using incremental sync
for buffer edits
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
@@ -55,9 +55,8 @@ These changes may require adaptations in your config or plugins.
API
• Decoration provider has `on_range()` callback.
-• nvim_get_commands()'s dictionaries' `complete` member is now a Lua function,
- if that is how the command was created. `preview` and `callback`
- have also been added, if they were specified in `nvim_create_user_command()`
+• |nvim_get_commands()| returns `complete` as a Lua function, if it was
+ defined as such.
BUILD
@@ -74,10 +73,10 @@ DIAGNOSTICS
EDITOR
-- |i_CTRL-R| inserts named/clipboard registers (A-Z,a-z,0-9+) literally, like
+• |i_CTRL-R| inserts named/clipboard registers (A-Z,a-z,0-9+) literally, like
pasting instead of like user input. Improves performance, avoids broken
formatting. To get the old behavior you can use `<C-R>=@x`.
-- Buffer name URI scheme parsing more closely follows RFC3986, so for example
+• Buffer name URI scheme parsing more closely follows RFC3986, so for example
"svn+ssh:", "ed2k:", and "iris.xpc:" are recognized as URI schemes.
EVENTS
@@ -154,6 +153,8 @@ API
escape sequences to the terminal when Nvim is running in the |TUI|.
• |nvim_echo()| can set the |ui-messages| kind with which to emit the message.
• |nvim_echo()| can create |Progress| messages
+• |nvim_get_commands()| returns `preview` and `callback` as Lua functions if
+ they were so specified in `nvim_create_user_command()`.
• |nvim_open_win()| floating windows can show a 'statusline'. Plugins can use
`style='minimal'` or `:setlocal statusline=` to hide the statusline.
• Added experimental |nvim__exec_lua_fast()| to allow remote API clients to
@@ -274,14 +275,16 @@ LSP
• Support for `textDocument/onTypeFormatting`: |lsp-on_type_formatting|
https://microsoft.github.io/language-server-protocol/specification/#textDocument_onTypeFormatting
• The filter option of |vim.lsp.buf.code_action()| now receives the client ID as an argument.
-• |Client:stop()| now accepts a numerical `force` argument to be interpreted
- as the time to wait before forcing the shutdown.
+• |Client:stop()| and |vim.lsp.enable()| accept `force` as an integer, which is
+ treated as the time to wait before before "stop" escalates to "force-stop".
+• |vim.lsp.ClientConfig| `exit_timeout` decides the time waited before "stop"
+ escalates to "force-stop" for |vim.lsp.enable()|, |Client:stop()|, and
+ during Nvim shutdown.
+ • `exit_timeout` graduated from "experimental" `flags.exit_timeout`
+ to a top-level field. Defaults to `false`.
• Add cmp field to opts of |vim.lsp.completion.enable()| for custom completion ordering.
• Push diagnostics (|vim.lsp.diagnostic.on_publish_diagnostics()|) now respect
the `version` property in the notification params.
-• |vim.lsp.ClientConfig| has an `exit_timeout` field to control the timeout of
- client force stopping. Defaults to `false`.
-• |Client:stop()| now uses the `Client.exit_timeout` field to control the default of `force`.
• Support for `workspace/diagnostic/refresh`:
https://microsoft.github.io/language-server-protocol/specification/#diagnostic_refresh
- Support for dynamic registration for `textDocument/diagnostic`
@@ -335,7 +338,9 @@ PERFORMANCE
support for nested braces and follows LSP 3.17 specification with
additional constraints for improved correctness and resistance to
backtracking edge cases.
-- |i_CTRL-R| inserts named/clipboard registers literally, 10x speedup.
+• |i_CTRL-R| inserts named/clipboard registers literally, 10x speedup.
+• LSP `textDocument/semanticTokens/range` is supported which requests tokens
+ for the viewport (visible screen) only.
PLUGINS
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
@@ -4331,7 +4331,7 @@ A jump table for the options with a short description can be found at |Q_op|.
behaves like CTRL-C was typed.
Running into the limit often means that the pattern is very
inefficient or too complex. This may already happen with the pattern
- "\(.\)*" on a very long line. ".*" works much better.
+ `\(.\)*` on a very long line. `.*` works much better.
Might also happen on redraw, when syntax rules try to match a complex
text structure.
Vim may run out of memory before hitting the 'maxmempattern' limit, in
diff --git a/runtime/doc/pattern.txt b/runtime/doc/pattern.txt
@@ -620,7 +620,7 @@ overview.
"^" it matches the star character.
Be aware that repeating "\_." can match a lot of text and take a long
- time. For example, "\_.*END" matches all text from the current
+ time. For example, `\_.*END` matches all text from the current
position to the last occurrence of "END" in the file. Since the "*"
will match as many as possible, this first skips over all lines until
the end of the file and then tries matching "END", backing up one
@@ -704,8 +704,8 @@ overview.
if \(\(then\)\@!.\)*$ "if " not followed by "then"
Using "\@!" is tricky, because there are many places where a pattern
- does not match. "a.*p\@!" will match from an "a" to the end of the
- line, because ".*" can match all characters in the line and the "p"
+ does not match. `a.*p\@!` will match from an "a" to the end of the
+ line, because `.*` can match all characters in the line and the "p"
doesn't match at the end of the line. "a.\{-}p\@!" will match any
"a", "ap", "app", etc. that isn't followed by a "p", because the "."
can match a "p" and "p\@!" doesn't match after that.
@@ -719,7 +719,7 @@ overview.
Useful example: to find "foo" in a line that does not contain "bar": >
/^\%(.*bar\)\@!.*\zsfoo
< This pattern first checks that there is not a single position in the
- line where "bar" matches. If ".*bar" matches somewhere the \@! will
+ line where "bar" matches. If `.*bar` matches somewhere the \@! will
reject the pattern. When there is no match any "foo" will be found.
The "\zs" is to have the match start just before "foo".
@@ -772,13 +772,13 @@ overview.
before what follows. |/zero-width|
Like "(?<!pattern)" in Perl, but Vim allows non-fixed-width patterns.
The match with the preceding atom is made to end just before the match
- with what follows, thus an atom that ends in ".*" will work.
+ with what follows, thus an atom that ends in `.*` will work.
Warning: This can be slow (because many positions need to be checked
for a match). Use a limit if you can, see below.
- Example matches ~
+ Example matches >
\(foo\)\@<!bar any "bar" that's not in "foobar"
\(\/\/.*\)\@<!in "in" which is not after "//"
-
+<
\@123<!
Like "\@<!" but only look back 123 bytes. This avoids trying lots of
matches that are known to fail and make executing the pattern very
@@ -843,7 +843,7 @@ $ At end of pattern or in front of "\|", "\)" or "\n" ('magic' on):
*/\_.*
\_. Matches any single character or end-of-line.
- Careful: "\_.*" matches all text to the end of the buffer!
+ Careful: `\_.*` matches all text to the end of the buffer!
*/\<*
\< Matches the beginning of a word: The next char is the first char of a
@@ -1020,7 +1020,7 @@ $ At end of pattern or in front of "\|", "\)" or "\n" ('magic' on):
this will also highlight column 17: >
/.*\%17v
< Column 17 is highlighted by 'hlsearch' because there is another match
- where ".*" matches zero characters.
+ where `.*` matches zero characters.
Character classes:
diff --git a/runtime/doc/pi_zip.txt b/runtime/doc/pi_zip.txt
@@ -172,9 +172,9 @@ Copyright: Copyright (C) 2005-2015 Charles E Campbell *zip-copyright*
* g:zip_shq provided to allow for quoting control for the
command being passed via :r! ... commands.
v8 Apr 10, 2006 * Bram Moolenaar reported that he received an error message
- due to "Pattern not found: ^.*\%0c"; this was caused by
+ due to `Pattern not found: ^.*\%0c`; this was caused by
stridx finding a Name... at the beginning of the line;
- zip.vim tried 4,$s/^.*\%0c//, but that doesn't work.
+ zip.vim tried `4,$s/^.*\%0c//`, but that doesn't work.
Fixed.
v7 Mar 22, 2006 * escaped some characters that can cause filename handling
problems.
diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt
@@ -2295,7 +2295,7 @@ remove the comment lines. For the '\' notation at the start of some lines see
\%E!\ %m,
< Start of multi-line warning messages; the first two also
include the line number. Meaning of some regular expressions:
- - "%.%#" (".*") matches a (possibly empty) string
+ - "%.%#" (`.*`) matches a (possibly empty) string
- "%*\\d" ("\d\+") matches a number >
\%+WLaTeX\ %.%#Warning:\ %.%#line\ %l%.%#,
\%+W%.%#\ at\ lines\ %l--%*\\d,
diff --git a/runtime/doc/spell.txt b/runtime/doc/spell.txt
@@ -490,7 +490,7 @@ You can create a Vim spell file from the .aff and .dic files that Myspell
uses. Myspell is used by OpenOffice.org and Mozilla. The OpenOffice .oxt
files are zip files which contain the .aff and .dic files. You should be able
to find them here:
- https://extensions.openoffice.org/en/search@f[0]=field_project_application%253A1&f[1]=field_project_tags%253A94.html
+ https://extensions.openoffice.org/en/search@f%5B0%5D%3Dfield_project_tags%253A311.html
The older, OpenOffice 2 files may be used if this doesn't work:
http://wiki.services.openoffice.org/wiki/Dictionaries
You can also use a plain word list. The results are the same, the choice
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
@@ -4406,7 +4406,7 @@ highlighting, and "bbb" where ccBar is used. >
fff bbb fff bbb
Note the use of ".\{-}" to skip as little as possible until the next Bar.
-when ".*" would be used, the "asdf" in between "Bar" and "Foo" would be
+when `.*` would be used, the "asdf" in between "Bar" and "Foo" would be
highlighted according to the "ccFoobar" group, because the ccFooBar match
would include the first "Foo" and the last "Bar" in the line (see |pattern|).
@@ -4438,7 +4438,7 @@ Example: >
:syn match ifstart "\<if.*" nextgroup=ifline skipwhite skipempty
:syn match ifline "[^ \t].*" nextgroup=ifline skipwhite skipempty contained
:syn match ifline "endif" contained
-Note that the "[^ \t].*" match matches all non-white text. Thus it would also
+Note that the `[^ \t].*` match matches all non-white text. Thus it would also
match "endif". Therefore the "endif" match is put last, so that it takes
precedence.
Note that this example doesn't work for nested "if"s. You need to add
diff --git a/runtime/doc/usr_03.txt b/runtime/doc/usr_03.txt
@@ -342,7 +342,7 @@ the <Left> and <Right> cursor keys when necessary.
Pressing <Enter> executes the command.
Note:
- The characters .*[]^%/\?~$ have special meanings. If you want to use
+ The characters `.*[]^%/\?~$` have special meanings. If you want to use
them in a search you must put a \ in front of them. See below.
To find the next occurrence of the same string use the "n" command. Use this
diff --git a/runtime/doc/usr_12.txt b/runtime/doc/usr_12.txt
@@ -111,9 +111,9 @@ command. The "%" is the line range, which stands for the whole file. Thus
the substitution is done in every line in the file.
The arguments for the substitute command are "/from/to/". The slashes
separate the "from" pattern and the "to" string. This is what the "from"
-pattern contains:
- \([^,]*\), \(.*\) ~
-
+pattern contains: >
+ \([^,]*\), \(.*\)
+<
The first part between \( \) matches "Last" \( \)
match anything but a comma [^,]
any number of times *
diff --git a/runtime/doc/usr_27.txt b/runtime/doc/usr_27.txt
@@ -317,7 +317,7 @@ This matches "axb" in "axbxb". If this pattern would be used: >
/a.*b
-It would try to match as many characters as possible with ".*", thus it
+It would try to match as many characters as possible with `.*`, thus it
matches "axbxb" as a whole.
==============================================================================
diff --git a/runtime/doc/vimfn.txt b/runtime/doc/vimfn.txt
@@ -258,8 +258,9 @@ assert_equal({expected}, {actual} [, {msg}]) *assert_equal()*
always matters.
Example: >vim
call assert_equal('foo', 'bar', 'baz')
-< Will add the following to |v:errors|:
- test.vim line 12: baz: Expected 'foo' but got 'bar' ~
+< Will add the following to |v:errors|: >
+ test.vim line 12: baz: Expected 'foo' but got 'bar'
+<
Parameters: ~
• {expected} (`any`)
@@ -401,8 +402,9 @@ assert_match({pattern}, {actual} [, {msg}]) *assert_match()*
Example: >vim
call assert_match('^f.*o$', 'foobar')
-< Will result in a string to be added to |v:errors|:
- test.vim line 12: Pattern '^f.*o$' does not match 'foobar' ~
+< Will result in a string to be added to |v:errors|: >
+ test.vim line 12: Pattern '^f.*o$' does not match 'foobar'
+<
Parameters: ~
• {pattern} (`string`)
@@ -7500,54 +7502,54 @@ printf({fmt}, {expr1} ...) *printf()*
*E1500*
You cannot mix positional and non-positional arguments: >vim
echo printf("%s%1$s", "One", "Two")
-< E1500: Cannot mix positional and non-positional arguments:
- %s%1$s
-
+ " E1500: Cannot mix positional and non-positional arguments:
+ " %s%1$s
+<
*E1501*
You cannot skip a positional argument in a format string: >vim
echo printf("%3$s%1$s", "One", "Two", "Three")
-< E1501: format argument 2 unused in $-style format:
- %3$s%1$s
-
+ " E1501: format argument 2 unused in $-style format:
+ " %3$s%1$s
+<
*E1502*
You can re-use a [field-width] (or [precision]) argument: >vim
echo printf("%1$d at width %2$d is: %01$*2$d", 1, 2)
-< 1 at width 2 is: 01
-
+ " 1 at width 2 is: 01
+<
However, you can't use it as a different type: >vim
echo printf("%1$d at width %2$ld is: %01$*2$d", 1, 2)
-< E1502: Positional argument 2 used as field width reused as
- different type: long int/int
-
+ " E1502: Positional argument 2 used as field width reused as
+ " different type: long int/int
+<
*E1503*
When a positional argument is used, but not the correct number
or arguments is given, an error is raised: >vim
echo printf("%1$d at width %2$d is: %01$*2$.*3$d", 1, 2)
-< E1503: Positional argument 3 out of bounds: %1$d at width
- %2$d is: %01$*2$.*3$d
-
+ " E1503: Positional argument 3 out of bounds: %1$d at width
+ " %2$d is: %01$*2$.*3$d
+<
Only the first error is reported: >vim
echo printf("%01$*2$.*3$d %4$d", 1, 2)
-< E1503: Positional argument 3 out of bounds: %01$*2$.*3$d
- %4$d
-
+ " E1503: Positional argument 3 out of bounds: %01$*2$.*3$d
+ " %4$d
+<
*E1504*
A positional argument can be used more than once: >vim
echo printf("%1$s %2$s %1$s", "One", "Two")
-< One Two One
-
+ " One Two One
+<
However, you can't use a different type the second time: >vim
echo printf("%1$s %2$s %1$d", "One", "Two")
-< E1504: Positional argument 1 type used inconsistently:
- int/string
-
+ " E1504: Positional argument 1 type used inconsistently:
+ " int/string
+<
*E1505*
Various other errors that lead to a format string being
wrongly formatted lead to: >vim
echo printf("%1$d at width %2$d is: %01$*2$.3$d", 1, 2)
-< E1505: Invalid format specifier: %1$d at width %2$d is:
- %01$*2$.3$d
-
+ " E1505: Invalid format specifier: %1$d at width %2$d is:
+ " %01$*2$.3$d
+<
*E1507*
This internal error indicates that the logic to parse a
positional format argument ran into a problem that couldn't be
diff --git a/runtime/lua/vim/_meta/api.lua b/runtime/lua/vim/_meta/api.lua
@@ -1721,8 +1721,7 @@ function vim.api.nvim_open_term(buffer, opts) end
--- If -1 is provided, a top-level split will be created. `vertical` and `split` are
--- only valid for normal windows, and are used to control split direction. For `vertical`,
--- the exact direction is determined by 'splitright' and 'splitbelow'.
---- Split windows cannot have `bufpos`/`row`/`col`/`border`/`title`/`footer`
---- properties.
+--- Split windows cannot have `bufpos`, `row`, `col`, `border`, `title`, `footer` properties.
---
--- With relative=editor (row=0,col=0) refers to the top-left corner of the
--- screen-grid and (row=Lines-1,col=Columns-1) refers to the bottom-right
@@ -1735,23 +1734,19 @@ function vim.api.nvim_open_term(buffer, opts) end
--- could let floats hover outside of the main window like a tooltip, but
--- this should not be used to specify arbitrary WM screen positions.
---
---- Example: window-relative float
+--- Examples:
---
--- ```lua
---- vim.api.nvim_open_win(0, false,
---- {relative='win', row=3, col=3, width=12, height=3})
---- ```
+--- -- Window-relative float with 'statusline' enabled:
+--- local w1 = vim.api.nvim_open_win(0, false,
+--- {relative='win', row=3, col=3, width=40, height=4})
+--- vim.wo[w1].statusline = vim.o.statusline
---
---- Example: buffer-relative float (travels as buffer is scrolled)
----
---- ```lua
+--- -- Buffer-relative float (travels as buffer is scrolled):
--- vim.api.nvim_open_win(0, false,
---- {relative='win', width=12, height=3, bufpos={100,10}})
---- ```
----
---- Example: vertical split left of the current window
+--- {relative='win', width=40, height=4, bufpos={100,10}})
---
---- ```lua
+--- -- Vertical split left of the current window:
--- vim.api.nvim_open_win(0, false, { split = 'left', win = 0, })
--- ```
---
@@ -1957,7 +1952,7 @@ function vim.api.nvim_parse_cmd(str, opts) end
--- - "error": Dict with error, present only if parser saw some
--- error. Contains the following keys:
--- - "message": String, error message in printf format, translated.
---- Must contain exactly one "%.*s".
+--- Must contain exactly one `%.*s`.
--- - "arg": String, error message argument.
--- - "len": Amount of bytes successfully parsed. With flags equal to ""
--- that should be equal to the length of expr string.
diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua
@@ -4398,7 +4398,7 @@ vim.go.mmd = vim.go.maxmapdepth
--- behaves like CTRL-C was typed.
--- Running into the limit often means that the pattern is very
--- inefficient or too complex. This may already happen with the pattern
---- "\(.\)*" on a very long line. ".*" works much better.
+--- `\(.\)*` on a very long line. `.*` works much better.
--- Might also happen on redraw, when syntax rules try to match a complex
--- text structure.
--- Vim may run out of memory before hitting the 'maxmempattern' limit, in
diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua
@@ -212,8 +212,9 @@ function vim.fn.assert_beeps(cmd) end
--- always matters.
--- Example: >vim
--- call assert_equal('foo', 'bar', 'baz')
---- <Will add the following to |v:errors|:
---- test.vim line 12: baz: Expected 'foo' but got 'bar' ~
+--- <Will add the following to |v:errors|: >
+--- test.vim line 12: baz: Expected 'foo' but got 'bar'
+--- <
---
--- @param expected any
--- @param actual any
@@ -336,8 +337,9 @@ function vim.fn.assert_inrange(lower, upper, actual, msg) end
---
--- Example: >vim
--- call assert_match('^f.*o$', 'foobar')
---- <Will result in a string to be added to |v:errors|:
---- test.vim line 12: Pattern '^f.*o$' does not match 'foobar' ~
+--- <Will result in a string to be added to |v:errors|: >
+--- test.vim line 12: Pattern '^f.*o$' does not match 'foobar'
+--- <
---
--- @param pattern string
--- @param actual string
@@ -6820,54 +6822,54 @@ function vim.fn.prevnonblank(lnum) end
--- *E1500*
--- You cannot mix positional and non-positional arguments: >vim
--- echo printf("%s%1$s", "One", "Two")
---- < E1500: Cannot mix positional and non-positional arguments:
---- %s%1$s
----
+--- " E1500: Cannot mix positional and non-positional arguments:
+--- " %s%1$s
+--- <
--- *E1501*
--- You cannot skip a positional argument in a format string: >vim
--- echo printf("%3$s%1$s", "One", "Two", "Three")
---- < E1501: format argument 2 unused in $-style format:
---- %3$s%1$s
----
+--- " E1501: format argument 2 unused in $-style format:
+--- " %3$s%1$s
+--- <
--- *E1502*
--- You can re-use a [field-width] (or [precision]) argument: >vim
--- echo printf("%1$d at width %2$d is: %01$*2$d", 1, 2)
---- < 1 at width 2 is: 01
----
+--- " 1 at width 2 is: 01
+--- <
--- However, you can't use it as a different type: >vim
--- echo printf("%1$d at width %2$ld is: %01$*2$d", 1, 2)
---- < E1502: Positional argument 2 used as field width reused as
---- different type: long int/int
----
+--- " E1502: Positional argument 2 used as field width reused as
+--- " different type: long int/int
+--- <
--- *E1503*
--- When a positional argument is used, but not the correct number
--- or arguments is given, an error is raised: >vim
--- echo printf("%1$d at width %2$d is: %01$*2$.*3$d", 1, 2)
---- < E1503: Positional argument 3 out of bounds: %1$d at width
---- %2$d is: %01$*2$.*3$d
----
+--- " E1503: Positional argument 3 out of bounds: %1$d at width
+--- " %2$d is: %01$*2$.*3$d
+--- <
--- Only the first error is reported: >vim
--- echo printf("%01$*2$.*3$d %4$d", 1, 2)
---- < E1503: Positional argument 3 out of bounds: %01$*2$.*3$d
---- %4$d
----
+--- " E1503: Positional argument 3 out of bounds: %01$*2$.*3$d
+--- " %4$d
+--- <
--- *E1504*
--- A positional argument can be used more than once: >vim
--- echo printf("%1$s %2$s %1$s", "One", "Two")
---- < One Two One
----
+--- " One Two One
+--- <
--- However, you can't use a different type the second time: >vim
--- echo printf("%1$s %2$s %1$d", "One", "Two")
---- < E1504: Positional argument 1 type used inconsistently:
---- int/string
----
+--- " E1504: Positional argument 1 type used inconsistently:
+--- " int/string
+--- <
--- *E1505*
--- Various other errors that lead to a format string being
--- wrongly formatted lead to: >vim
--- echo printf("%1$d at width %2$d is: %01$*2$.3$d", 1, 2)
---- < E1505: Invalid format specifier: %1$d at width %2$d is:
---- %01$*2$.3$d
----
+--- " E1505: Invalid format specifier: %1$d at width %2$d is:
+--- " %01$*2$.3$d
+--- <
--- *E1507*
--- This internal error indicates that the logic to parse a
--- positional format argument ran into a problem that couldn't be
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
@@ -515,8 +515,11 @@ local function lsp_enable_callback(bufnr)
end
end
---- Auto-starts LSP when a buffer is opened, based on the |lsp-config| `filetypes`, `root_markers`,
---- and `root_dir` fields.
+--- Auto-activates LSP in each buffer based on the |lsp-config| `filetypes`, `root_markers`, and
+--- `root_dir`.
+---
+--- To disable, pass `enable=false`: Stops related clients and servers (force-stops servers after
+--- a timeout, unless `exit_timeout=false`).
---
--- Examples:
---
@@ -549,8 +552,9 @@ end
---@since 13
---
--- @param name string|string[] Name(s) of client(s) to enable.
---- @param enable? boolean `true|nil` to enable, `false` to disable (actively stops and detaches
---- clients as needed, and force stops them if necessary after `client.exit_timeout` milliseconds)
+--- @param enable? boolean If `true|nil`, enables auto-activation of the given LSP config on current
+--- and future buffers. If `false`, disables auto-activation and stops related LSP clients and
+--- servers (force-stops servers after `exit_timeout` milliseconds).
function lsp.enable(name, enable)
validate('name', name, { 'string', 'table' })
@@ -1055,8 +1059,8 @@ end
--- vim.lsp.stop_client(vim.lsp.get_clients())
--- ```
---
---- By default asks the server to shutdown, unless stop was requested
---- already for this client, then force-shutdown is attempted.
+--- By default asks the server to shutdown, unless stop was requested already for this client (then
+--- force-shutdown is attempted, unless `exit_timeout=false`).
---
---@deprecated
---@param client_id integer|integer[]|vim.lsp.Client[] id, list of id's, or list of |vim.lsp.Client| objects
diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua
@@ -75,7 +75,7 @@ local all_clients = {}
--- (default: `false`)
--- @field exit_timeout? integer|boolean
---
---- A table with flags for the client. The current (experimental) flags are:
+--- Experimental client flags:
--- @field flags? vim.lsp.Client.Flags
---
--- Language ID as string. Defaults to the buffer filetype.
@@ -163,7 +163,7 @@ local all_clients = {}
--- (default: `false`)
--- @field exit_timeout integer|boolean
---
---- A table with flags for the client. The current (experimental) flags are:
+--- Experimental client flags:
--- @field flags vim.lsp.Client.Flags
---
--- See [vim.lsp.ClientConfig].
diff --git a/src/gen/gen_help_html.lua b/src/gen/gen_help_html.lua
@@ -54,6 +54,12 @@ local spell_ignore_files = {
['news.txt'] = { 'tree-sitter' }, -- in news, may refer to the upstream "tree-sitter" library
['news-0.10.txt'] = { 'tree-sitter' },
}
+--- Punctuation that indicates a word is part of a path, module name, etc.
+--- Example: ".lua" is likely part of a filename, thus we don't want to enforce its spelling.
+local spell_punc = {
+ ['.'] = true,
+ ['/'] = true,
+}
local language = nil
local M = {}
@@ -118,15 +124,14 @@ local exclude_invalid_urls = {
['http://.'] = 'usr_23.txt',
['http://aspell.net/man-html/Affix-Compression.html'] = 'spell.txt',
['http://aspell.net/man-html/Phonetic-Code.html'] = 'spell.txt',
- ['http://canna.sourceforge.jp/'] = 'mbyte.txt',
- ['http://gnuada.sourceforge.net'] = 'ft_ada.txt',
['http://lua-users.org/wiki/StringLibraryTutorial'] = 'lua.txt',
['http://michael.toren.net/code/'] = 'pi_tar.txt',
+ ['http://oldblog.antirez.com/post/redis-and-scripting.html'] = 'faq.txt',
['http://papp.plan9.de'] = 'syntax.txt',
+ ['http://vimcasts.org'] = 'intro.txt',
['http://wiki.services.openoffice.org/wiki/Dictionaries'] = 'spell.txt',
['http://www.adapower.com'] = 'ft_ada.txt',
['http://www.jclark.com/'] = 'quickfix.txt',
- ['http://oldblog.antirez.com/post/redis-and-scripting.html'] = 'faq.txt',
}
-- Deprecated, brain-damaged files that I don't care about.
@@ -189,7 +194,8 @@ end
--- Removes common punctuation from URLs.
---
---- TODO: fix this in the parser instead... https://github.com/neovim/tree-sitter-vimdoc
+--- NOTE: this is currently a no-op, since known issues were fixed in the parser:
+--- https://github.com/neovim/tree-sitter-vimdoc/pull/157
---
--- @param url string
--- @return string, string (fixed_url, removed_chars) where `removed_chars` is in the order found in the input.
@@ -197,12 +203,12 @@ local function fix_url(url)
local removed_chars = ''
local fixed_url = url
-- Remove up to one of each char from end of the URL, in this order.
- for _, c in ipairs({ '.', ')' }) do
- if fixed_url:sub(-1) == c then
- removed_chars = c .. removed_chars
- fixed_url = fixed_url:sub(1, -2)
- end
- end
+ -- for _, c in ipairs({ '.', ')', ',' }) do
+ -- if fixed_url:sub(-1) == c then
+ -- removed_chars = c .. removed_chars
+ -- fixed_url = fixed_url:sub(1, -2)
+ -- end
+ -- end
return fixed_url, removed_chars
end
@@ -374,6 +380,22 @@ local function first(node, name)
return nil
end
+--- Gets the kind and node text of the previous and next siblings of node `n`.
+--- @param n any node
+local function get_prev_next(n)
+ -- Previous sibling kind (string).
+ local prev = n:prev_sibling()
+ and (n:prev_sibling().named and n:prev_sibling():named())
+ and n:prev_sibling():type()
+ or nil
+ -- Next sibling kind (string).
+ local next_ = n:next_sibling()
+ and (n:next_sibling().named and n:next_sibling():named())
+ and n:next_sibling():type()
+ or nil
+ return prev, next_
+end
+
local function validate_link(node, bufnr, fname)
local helppage, tagname = get_tagname(node:child(1), bufnr)
local ignored = false
@@ -416,14 +438,19 @@ end
---@param stats table
local function visit_validate(root, level, lang_tree, opt, stats)
level = level or 0
- local node_name = (root.named and root:named()) and root:type() or nil
- -- Parent kind (string).
- local parent = root:parent() and root:parent():type() or nil
- local toplevel = level < 1
+
local function node_text(node)
return vim.treesitter.get_node_text(node or root, opt.buf)
end
+
local text = trim(node_text())
+ local node_name = (root.named and root:named()) and root:type() or nil
+ -- Parent kind (string).
+ local parent = root:parent() and root:parent():type() or nil
+ local toplevel = level < 1
+ -- local prev, next_ = get_prev_next(root)
+ local prev_text = root:prev_sibling() and node_text(root:prev_sibling()) or nil
+ local next_text = root:next_sibling() and node_text(root:next_sibling()) or nil
if root:child_count() > 0 then
for node, _ in root:iter_children() do
@@ -455,6 +482,7 @@ local function visit_validate(root, level, lang_tree, opt, stats)
(spell_ignore_files[fname_basename] or {}) --[[ @as string[] ]],
text_nopunct
)
+ or (spell_punc[next_text] or spell_punc[prev_text])
)
if not should_ignore then
invalid_spelling[text_nopunct] = invalid_spelling[text_nopunct] or {}
@@ -498,19 +526,12 @@ end
local function visit_node(root, level, lang_tree, headings, opt, stats)
level = level or 0
- local node_name = (root.named and root:named()) and root:type() or nil
- -- Previous sibling kind (string).
- local prev = root:prev_sibling()
- and (root:prev_sibling().named and root:prev_sibling():named())
- and root:prev_sibling():type()
- or nil
- -- Next sibling kind (string).
- local next_ = root:next_sibling()
- and (root:next_sibling().named and root:next_sibling():named())
- and root:next_sibling():type()
- or nil
- -- Parent kind (string).
- local parent = root:parent() and root:parent():type() or nil
+ local function node_text(node, ws_)
+ node = node or root
+ ws_ = (ws_ == nil or ws_ == true) and getws(node, opt.buf) or ''
+ return string.format('%s%s', ws_, vim.treesitter.get_node_text(node, opt.buf))
+ end
+
-- Gets leading whitespace of `node`.
local function ws(node)
node = node or root
@@ -522,11 +543,11 @@ local function visit_node(root, level, lang_tree, headings, opt, stats)
end
return ws_
end
- local function node_text(node, ws_)
- node = node or root
- ws_ = (ws_ == nil or ws_ == true) and getws(node, opt.buf) or ''
- return string.format('%s%s', ws_, vim.treesitter.get_node_text(node, opt.buf))
- end
+
+ local node_name = (root.named and root:named()) and root:type() or nil
+ local prev, next_ = get_prev_next(root)
+ -- Parent kind (string).
+ local parent = root:parent() and root:parent():type() or nil
local text = ''
local trimmed ---@type string
@@ -1397,7 +1418,7 @@ function M.gen(help_dir, to_dir, include, commit, parser_path)
vim.validate('commit', commit, 'string', true)
vim.validate('parser_path', parser_path, function(f)
return vim.fn.filereadable(vim.fs.normalize(f)) == 1
- end, true, 'valid vimdoc.{so,dll} filepath')
+ end, true, 'valid vimdoc.{so,dll,dylib} filepath')
local err_count = 0
local redirects_count = 0
@@ -1510,7 +1531,7 @@ function M.validate(help_dir, include, parser_path, request_urls)
vim.validate('include', include, 'table', true)
vim.validate('parser_path', parser_path, function(f)
return vim.fn.filereadable(vim.fs.normalize(f)) == 1
- end, true, 'valid vimdoc.{so,dll} filepath')
+ end, true, 'valid vimdoc.{so,dll,dylib} filepath')
local err_count = 0 ---@type integer
local files_to_errors = {} ---@type table<string, string[]>
ensure_runtimepath()
diff --git a/src/nvim/api/vimscript.c b/src/nvim/api/vimscript.c
@@ -382,7 +382,7 @@ typedef kvec_withinit_t(ExprASTConvStackItem, 16) ExprASTConvStack;
/// - "error": Dict with error, present only if parser saw some
/// error. Contains the following keys:
/// - "message": String, error message in printf format, translated.
-/// Must contain exactly one "%.*s".
+/// Must contain exactly one `%.*s`.
/// - "arg": String, error message argument.
/// - "len": Amount of bytes successfully parsed. With flags equal to ""
/// that should be equal to the length of expr string.
diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c
@@ -57,8 +57,7 @@
/// If -1 is provided, a top-level split will be created. `vertical` and `split` are
/// only valid for normal windows, and are used to control split direction. For `vertical`,
/// the exact direction is determined by 'splitright' and 'splitbelow'.
-/// Split windows cannot have `bufpos`/`row`/`col`/`border`/`title`/`footer`
-/// properties.
+/// Split windows cannot have `bufpos`, `row`, `col`, `border`, `title`, `footer` properties.
///
/// With relative=editor (row=0,col=0) refers to the top-left corner of the
/// screen-grid and (row=Lines-1,col=Columns-1) refers to the bottom-right
@@ -71,23 +70,19 @@
/// could let floats hover outside of the main window like a tooltip, but
/// this should not be used to specify arbitrary WM screen positions.
///
-/// Example: window-relative float
+/// Examples:
///
/// ```lua
-/// vim.api.nvim_open_win(0, false,
-/// {relative='win', row=3, col=3, width=12, height=3})
-/// ```
+/// -- Window-relative float with 'statusline' enabled:
+/// local w1 = vim.api.nvim_open_win(0, false,
+/// {relative='win', row=3, col=3, width=40, height=4})
+/// vim.wo[w1].statusline = vim.o.statusline
///
-/// Example: buffer-relative float (travels as buffer is scrolled)
-///
-/// ```lua
+/// -- Buffer-relative float (travels as buffer is scrolled):
/// vim.api.nvim_open_win(0, false,
-/// {relative='win', width=12, height=3, bufpos={100,10}})
-/// ```
-///
-/// Example: vertical split left of the current window
+/// {relative='win', width=40, height=4, bufpos={100,10}})
///
-/// ```lua
+/// -- Vertical split left of the current window:
/// vim.api.nvim_open_win(0, false, { split = 'left', win = 0, })
/// ```
///
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
@@ -314,9 +314,9 @@ M.funcs = {
always matters.
Example: >vim
call assert_equal('foo', 'bar', 'baz')
- <Will add the following to |v:errors|:
- test.vim line 12: baz: Expected 'foo' but got 'bar' ~
-
+ <Will add the following to |v:errors|: >
+ test.vim line 12: baz: Expected 'foo' but got 'bar'
+ <
]=],
name = 'assert_equal',
params = { { 'expected', 'any' }, { 'actual', 'any' }, { 'msg', 'any' } },
@@ -470,9 +470,9 @@ M.funcs = {
Example: >vim
call assert_match('^f.*o$', 'foobar')
- <Will result in a string to be added to |v:errors|:
- test.vim line 12: Pattern '^f.*o$' does not match 'foobar' ~
-
+ <Will result in a string to be added to |v:errors|: >
+ test.vim line 12: Pattern '^f.*o$' does not match 'foobar'
+ <
]=],
name = 'assert_match',
params = { { 'pattern', 'string' }, { 'actual', 'string' }, { 'msg', 'string' } },
@@ -8300,54 +8300,54 @@ M.funcs = {
*E1500*
You cannot mix positional and non-positional arguments: >vim
echo printf("%s%1$s", "One", "Two")
- < E1500: Cannot mix positional and non-positional arguments:
- %s%1$s
-
+ " E1500: Cannot mix positional and non-positional arguments:
+ " %s%1$s
+ <
*E1501*
You cannot skip a positional argument in a format string: >vim
echo printf("%3$s%1$s", "One", "Two", "Three")
- < E1501: format argument 2 unused in $-style format:
- %3$s%1$s
-
+ " E1501: format argument 2 unused in $-style format:
+ " %3$s%1$s
+ <
*E1502*
You can re-use a [field-width] (or [precision]) argument: >vim
echo printf("%1$d at width %2$d is: %01$*2$d", 1, 2)
- < 1 at width 2 is: 01
-
+ " 1 at width 2 is: 01
+ <
However, you can't use it as a different type: >vim
echo printf("%1$d at width %2$ld is: %01$*2$d", 1, 2)
- < E1502: Positional argument 2 used as field width reused as
- different type: long int/int
-
+ " E1502: Positional argument 2 used as field width reused as
+ " different type: long int/int
+ <
*E1503*
When a positional argument is used, but not the correct number
or arguments is given, an error is raised: >vim
echo printf("%1$d at width %2$d is: %01$*2$.*3$d", 1, 2)
- < E1503: Positional argument 3 out of bounds: %1$d at width
- %2$d is: %01$*2$.*3$d
-
+ " E1503: Positional argument 3 out of bounds: %1$d at width
+ " %2$d is: %01$*2$.*3$d
+ <
Only the first error is reported: >vim
echo printf("%01$*2$.*3$d %4$d", 1, 2)
- < E1503: Positional argument 3 out of bounds: %01$*2$.*3$d
- %4$d
-
+ " E1503: Positional argument 3 out of bounds: %01$*2$.*3$d
+ " %4$d
+ <
*E1504*
A positional argument can be used more than once: >vim
echo printf("%1$s %2$s %1$s", "One", "Two")
- < One Two One
-
+ " One Two One
+ <
However, you can't use a different type the second time: >vim
echo printf("%1$s %2$s %1$d", "One", "Two")
- < E1504: Positional argument 1 type used inconsistently:
- int/string
-
+ " E1504: Positional argument 1 type used inconsistently:
+ " int/string
+ <
*E1505*
Various other errors that lead to a format string being
wrongly formatted lead to: >vim
echo printf("%1$d at width %2$d is: %01$*2$.3$d", 1, 2)
- < E1505: Invalid format specifier: %1$d at width %2$d is:
- %01$*2$.3$d
-
+ " E1505: Invalid format specifier: %1$d at width %2$d is:
+ " %01$*2$.3$d
+ <
*E1507*
This internal error indicates that the logic to parse a
positional format argument ran into a problem that couldn't be
diff --git a/src/nvim/option.c b/src/nvim/option.c
@@ -1047,6 +1047,7 @@ static const char *find_tty_option_end(const char *arg)
p++;
}
if (p[0] == 't' && p[1] == '_' && p[2] && p[3]) {
+ // "t_xx" ("t_Co") option.
p += 4;
} else if (delimit) {
// Search for delimiting >.
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
@@ -5715,7 +5715,7 @@ local options = {
behaves like CTRL-C was typed.
Running into the limit often means that the pattern is very
inefficient or too complex. This may already happen with the pattern
- "\(.\)*" on a very long line. ".*" works much better.
+ `\(.\)*` on a very long line. `.*` works much better.
Might also happen on redraw, when syntax rules try to match a complex
text structure.
Vim may run out of memory before hitting the 'maxmempattern' limit, in
diff --git a/src/nvim/usercmd.c b/src/nvim/usercmd.c
@@ -1814,9 +1814,7 @@ Dict commands_array(buf_T *buf, Arena *arena)
PUT_C(d, "complete", LUAREF_OBJ(api_new_luaref(cmd->uc_compl_luaref)));
} else {
char *cmd_compl = get_command_complete(cmd->uc_compl);
-
- PUT_C(d, "complete", (cmd_compl == NULL
- ? NIL : CSTR_AS_OBJ(cmd_compl)));
+ PUT_C(d, "complete", (cmd_compl == NULL ? NIL : CSTR_AS_OBJ(cmd_compl)));
}
PUT_C(d, "complete_arg", cmd->uc_compl_arg == NULL
? NIL : CSTR_AS_OBJ(cmd->uc_compl_arg));
diff --git a/test/functional/api/command_spec.lua b/test/functional/api/command_spec.lua
@@ -159,6 +159,39 @@ describe('nvim_get_commands', function()
keepscript = false,
script_id = 4,
}
+ local previewCmd = {
+ addr = NIL,
+ bang = false,
+ bar = false,
+ complete = 'customlist',
+ complete_arg = 's:cpt',
+ count = NIL,
+ definition = '',
+ name = 'PreviewCmd',
+ nargs = '1',
+ range = NIL,
+ register = false,
+ keepscript = false,
+ script_id = 5,
+ }
+ local previewLuaCmd = {
+ addr = NIL,
+ bang = false,
+ bar = false,
+ callback = NIL, -- RPC serializes Lua callback as NIL.
+ complete = NIL, -- RPC serializes Lua callback as NIL.
+ preview = NIL, -- RPC serializes Lua callback as NIL.
+ complete_arg = NIL,
+ count = NIL,
+ definition = '',
+ name = 'PreviewLuaCmd',
+ nargs = '1',
+ range = NIL,
+ register = false,
+ keepscript = false,
+ script_id = -8, -- Lua
+ }
+
source([[
let s:foo = 1
command -complete=custom,ListUsers -nargs=+ Finger !finger <args>
@@ -186,12 +219,12 @@ describe('nvim_get_commands', function()
function! s:cpt() abort
return 1
endfunction
- command -nargs=1 -complete=customlist,s:cpt CmdWithPreview
+ command -nargs=1 -complete=customlist,s:cpt PreviewCmd
]])
source([[
lua << EOF
vim.api.nvim_create_user_command(
- 'CmdWithPreviewLua',
+ 'PreviewLuaCmd',
function() end,
{
nargs = 1,
@@ -203,18 +236,15 @@ describe('nvim_get_commands', function()
]])
-- TODO(justinmk): Order is stable but undefined. Sort before return?
local commands = api.nvim_get_commands({ builtin = false })
- local cmd_with_preview = commands.CmdWithPreview
- commands.CmdWithPreview = nil
- local cmd_with_preview_lua = commands.CmdWithPreviewLua
- commands.CmdWithPreviewLua = nil
- eq({ Cmd2 = cmd2, Cmd3 = cmd3, Cmd4 = cmd4, Finger = cmd1, TestCmd = cmd0 }, commands)
-
- eq(cmd_with_preview.complete, 'customlist')
- eq(cmd_with_preview.preview, nil)
-
- -- user data (NIL), because these are passed through RPC:
- eq(cmd_with_preview_lua.complete, NIL)
- eq(cmd_with_preview_lua.preview, NIL)
+ eq({
+ Cmd2 = cmd2,
+ Cmd3 = cmd3,
+ Cmd4 = cmd4,
+ Finger = cmd1,
+ TestCmd = cmd0,
+ PreviewCmd = previewCmd,
+ PreviewLuaCmd = previewLuaCmd,
+ }, commands)
end)
it('gets callbacks defined as Lua functions', function()