fix #24699
fix #25253
This commit is contained in:
Justin M. Keyes 2023-09-20 04:15:23 -07:00 committed by GitHub
parent 50d5fcc0bc
commit 1b55f51d0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 160 additions and 145 deletions

View File

@ -10,7 +10,7 @@ low-risk/isolated tasks:
- Try a [complexity:low] issue.
- Fix bugs found by [Clang](#clang-scan-build), [PVS](#pvs-studio) or
[Coverity](#coverity).
- [Improve documentation](#documenting)
- [Improve documentation](#documentation)
- [Merge a Vim patch] (requires strong familiarity with Vim)
- NOTE: read the above link before sending improvements to "runtime files" (anything in `runtime/`).
- Vimscript and documentation files are (mostly) maintained by [Vim](https://github.com/vim/vim), not Nvim.
@ -267,8 +267,8 @@ to `runtime/lua/vim/_editor.lua` then:
VIMRUNTIME=./runtime ./build/bin/nvim --luamod-dev
```
Documenting
-----------
Documentation
-------------
Read [:help dev-doc][dev-doc-guide] to understand the expected documentation style and conventions.
@ -287,10 +287,15 @@ If you need to modify or debug the documentation flow, these are the main files:
- `./scripts/lua2dox.lua`:
Used by `gen_vimdoc.py` to transform Lua files into a format compatible with doxygen.
- `./scripts/gen_eval_files.lua`:
Generates documentation and Lua type files from metadata files including:
- Eval functions (`src/nvim/eval.lua`)
- Options (`src/nvim/options.lua`)
- API
Generates documentation and Lua type files from metadata files:
```
runtime/lua/vim/* => runtime/doc/lua.txt
runtime/lua/vim/* => runtime/doc/lua.txt
runtime/lua/vim/lsp/ => runtime/doc/lsp.txt
src/nvim/api/* => runtime/doc/api.txt
src/nvim/eval.lua => runtime/doc/builtin.txt
src/nvim/options.lua => runtime/doc/options.txt
```
### Lua docstrings

View File

@ -1505,7 +1505,7 @@ nvim_set_keymap({mode}, {lhs}, {rhs}, {*opts}) *nvim_set_keymap()*
• {rhs} Right-hand-side |{rhs}| of the mapping.
• {opts} Optional parameters map: Accepts all |:map-arguments| as keys
except |<buffer>|, values are booleans (default false). Also:
• "noremap" non-recursive mapping |:noremap|
• "noremap" disables |recursive_mapping|, like |:noremap|
• "desc" human-readable description.
• "callback" Lua function called in place of {rhs}.
• "replace_keycodes" (boolean) When "expr" is true, replace

View File

@ -3738,7 +3738,7 @@ jobresize({job}, {width}, {height}) *jobresize()*
Fails if the job was not started with `"pty":v:true`.
jobstart({cmd} [, {opts}]) *jobstart()*
Note: Prefer |vim.system()| in Lua.
Note: Prefer |vim.system()| in Lua (unless using the `pty` option).
Spawns {cmd} as a job.
If {cmd} is a List it runs directly (no 'shell').

View File

@ -312,6 +312,12 @@ See also |dev-naming|.
- Avoid functions that depend on cursor position, current buffer, etc. Instead
the function should take a position parameter, buffer parameter, etc.
Where things go ~
- API (libnvim/RPC): exposes low-level internals, or fundamental things (such
as `nvim_exec_lua()`) needed by clients or C consumers.
- Lua stdlib = high-level functionality that builds on top of the API.
NAMING GUIDELINES *dev-naming*
Naming is exceedingly important: the name of a thing is the primary interface

View File

@ -536,7 +536,7 @@ CTRL-O in Insert mode you get a beep but you are still in Insert mode, type
Visual *2 ^G c C -- : --
Select *5 ^O ^G *6 -- -- --
Insert <Esc> -- -- <Insert> -- --
Replace <Esc> -- -- <Insert> -- --
Replace <Esc> -- -- <Insert> -- --
Command-line `*3` -- -- :start -- --
Ex :vi -- -- -- -- --

View File

@ -1880,25 +1880,22 @@ vim.deepcopy({orig}) *vim.deepcopy()*
Return: ~
(table) Table of copied keys and (nested) values.
vim.defaulttable({create}) *vim.defaulttable()*
Creates a table whose members are automatically created when accessed, if
they don't already exist.
vim.defaulttable({createfn}) *vim.defaulttable()*
Creates a table whose missing keys are provided by {createfn} (like
Python's "defaultdict").
They mimic defaultdict in python.
If {create} is `nil`, this will create a defaulttable whose constructor
function is this function, effectively allowing to create nested tables on
the fly: >lua
If {createfn} is `nil` it defaults to defaulttable() itself, so accessing
nested keys creates nested tables: >lua
local a = vim.defaulttable()
a.b.c = 1
<
Parameters: ~
• {create} function?(key:any):any The function called to create a
missing value.
• {createfn} function?(key:any):any Provides the value for a missing
`key`.
Return: ~
(table) Empty table with metamethod
(table) Empty table with `__index` metamethod.
vim.endswith({s}, {suffix}) *vim.endswith()*
Tests if `s` ends with `suffix`.
@ -2061,13 +2058,13 @@ vim.Ringbuf:push({item}) *Ringbuf:push()*
• {item} any
vim.spairs({t}) *vim.spairs()*
Enumerate a table sorted by its keys.
Enumerates key-value pairs of a table, ordered by key.
Parameters: ~
• {t} (table) Dict-like table
Return: ~
(function) iterator over sorted keys and their values
(function) |for-in| iterator over sorted keys and their values
See also: ~
• Based on https://github.com/premake/premake-core/blob/master/src/base/table.lua
@ -2232,12 +2229,14 @@ vim.tbl_get({o}, {...}) *vim.tbl_get()*
any Nested value indexed by key (if it exists), else nil
vim.tbl_isarray({t}) *vim.tbl_isarray()*
Tests if a Lua table can be treated as an array (a table indexed by
integers).
Tests if `t` is an "array": a table indexed only by integers (potentially non-contiguous).
Empty table `{}` is assumed to be an array, unless it was created by
|vim.empty_dict()| or returned as a dict-like |API| or Vimscript result,
for example from |rpcrequest()| or |vim.fn|.
If the indexes start from 1 and are contiguous then the array is also a
list. |vim.tbl_islist()|
Empty table `{}` is an array, unless it was created by |vim.empty_dict()|
or returned as a dict-like |API| or Vimscript result, for example from
|rpcrequest()| or |vim.fn|.
Parameters: ~
• {t} (table)
@ -2245,6 +2244,9 @@ vim.tbl_isarray({t}) *vim.tbl_isarray()*
Return: ~
(boolean) `true` if array-like table, else `false`.
See also: ~
• https://github.com/openresty/luajit2#tableisarray
vim.tbl_isempty({t}) *vim.tbl_isempty()*
Checks if a table is empty.
@ -2258,12 +2260,12 @@ vim.tbl_isempty({t}) *vim.tbl_isempty()*
• https://github.com/premake/premake-core/blob/master/src/base/table.lua
vim.tbl_islist({t}) *vim.tbl_islist()*
Tests if a Lua table can be treated as a list (a table indexed by
consecutive integers starting from 1).
Tests if `t` is a "list": a table indexed only by contiguous integers starting from 1 (what |lua-length| calls a "regular
array").
Empty table `{}` is assumed to be an list, unless it was created by
|vim.empty_dict()| or returned as a dict-like |API| or Vimscript result,
for example from |rpcrequest()| or |vim.fn|.
Empty table `{}` is a list, unless it was created by |vim.empty_dict()| or
returned as a dict-like |API| or Vimscript result, for example from
|rpcrequest()| or |vim.fn|.
Parameters: ~
• {t} (table)
@ -2271,6 +2273,9 @@ vim.tbl_islist({t}) *vim.tbl_islist()*
Return: ~
(boolean) `true` if list-like table, else `false`.
See also: ~
• |vim.tbl_isarray()|
vim.tbl_keys({t}) *vim.tbl_keys()*
Return a list of all keys used in a table. However, the order of the
return table of keys is not guaranteed.

View File

@ -568,8 +568,7 @@ Binary operators comprise arithmetic operators (see |lua-arithmetic|),
relational operators (see |lua-relational|), logical operators (see
|lua-logicalop|), and the concatenation operator (see |lua-concat|).
Unary operators comprise the unary minus (see |lua-arithmetic|), the unary
`not` (see |lua-logicalop|), and the unary length operator (see
|lua-length|).
`not` (see |lua-logicalop|), and the unary length operator (see |lua-length|).
Both function calls and vararg expressions may result in multiple values. If
the expression is used as a statement (see |lua-funcstatement|)
@ -690,7 +689,7 @@ according to the rules mentioned in |lua-coercion|. Otherwise, the
"concat" metamethod is called (see |lua-metatable|).
------------------------------------------------------------------------------
2.5.5 The Length Operator *lua-length*
2.5.5 The Length Operator *lua-#* *lua-length*
The length operator is denoted by the unary operator `#`. The length of a
string is its number of bytes (that is, the usual meaning of string length
@ -3505,7 +3504,7 @@ luaL_where *luaL_where()*
This function is used to build a prefix for error messages.
==============================================================================
5 STANDARD LIBRARIES *lua-Lib*
5 STANDARD LIBRARIES *lua-lib*
The standard libraries provide useful functions that are implemented directly
through the C API. Some of these functions provide essential services to the
@ -3653,8 +3652,8 @@ next({table} [, {index}]) *next()*
argument is absent, then it is interpreted as `nil`. In particular,
you can use `next(t)` to check whether a table is empty.
The order in which the indices are enumerated is not specified, `even
for` `numeric indices`. (To traverse a table in numeric order, use a
The order in which the indices are enumerated is not specified, even
for numeric indices. (To traverse a table in numeric order, use a
numerical `for` or the |ipairs()| function.)
The behavior of `next` is `undefined` if, during the traversal, you
@ -3759,7 +3758,7 @@ unpack({list} [, {i} [, {j}]]) *unpack()*
<
except that the above code can be written only for a fixed number of
elements. By default, {i} is 1 and {j} is the length of the list, as
defined by the length operator(see |lua-length|).
defined by the length operator (see |lua-length|).
_VERSION *_VERSION*
A global variable (not a function) that holds a string containing the
@ -4299,12 +4298,11 @@ table.remove({table} [, {pos}]) *table.remove()*
table.sort({table} [, {comp}]) *table.sort()*
Sorts table elements in a given order, `in-place`, from `table[1]` to
`table[n]`, where `n` is the length of the table (see
|lua-length|). If {comp} is given, then it must be a function
that receives two table elements, and returns true when the first is
less than the second (so that `not comp(a[i+1],a[i])` will be true
after the sort). If {comp} is not given, then the standard Lua
operator `<` is used instead.
`table[n]`, where `n` is the length of the table (see |lua-length|).
If {comp} is given, then it must be a function that receives two table
elements, and returns true when the first is less than the second (so
that `not comp(a[i+1],a[i])` will be true after the sort). If {comp}
is not given, then the standard Lua operator `<` is used instead.
The sort algorithm is `not` stable, that is, elements considered equal by the
given order may have their relative positions changed by the sort.

View File

@ -3235,9 +3235,8 @@ A jump table for the options with a short description can be found at |Q_op|.
*'ignorecase'* *'ic'* *'noignorecase'* *'noic'*
'ignorecase' 'ic' boolean (default off)
global
Ignore case in search patterns. Also used when searching in the tags
file.
Also see 'smartcase' and 'tagcase'.
Ignore case in search patterns, completion, and when searching the tags file.
See also 'smartcase' and 'tagcase'.
Can be overruled by using "\c" or "\C" in the pattern, see
|/ignorecase|.

View File

@ -854,12 +854,14 @@ add_predicate({name}, {handler}, {force})
• {force} (boolean|nil)
edit({lang}) *vim.treesitter.query.edit()*
Open a window for live editing of a treesitter query.
Opens a live editor to query the buffer you started from.
Can also be shown with `:EditQuery`. *:EditQuery*
Can also be shown with *:EditQuery*.
Note that the editor opens a scratch buffer, and so queries aren't
persisted on disk.
If you move the cursor to a capture name ("@foo"), text matching the
capture is highlighted in the source buffer. The query editor is a scratch
buffer, use `:write` to save it. You can find example queries at
`$VIMRUNTIME/queries/`.
Parameters: ~
• {lang} (string|nil) language to open the query editor for. If

View File

@ -1903,7 +1903,7 @@ function vim.api.nvim_set_hl_ns_fast(ns_id) end
--- @param rhs string Right-hand-side `{rhs}` of the mapping.
--- @param opts vim.api.keyset.keymap Optional parameters map: Accepts all `:map-arguments` as keys
--- except `<buffer>`, values are booleans (default false). Also:
--- • "noremap" non-recursive mapping `:noremap`
--- • "noremap" disables `recursive_mapping`, like `:noremap`
--- • "desc" human-readable description.
--- • "callback" Lua function called in place of {rhs}.
--- • "replace_keycodes" (boolean) When "expr" is true, replace

View File

@ -3088,9 +3088,8 @@ vim.go.icon = vim.o.icon
vim.o.iconstring = ""
vim.go.iconstring = vim.o.iconstring
--- Ignore case in search patterns. Also used when searching in the tags
--- file.
--- Also see 'smartcase' and 'tagcase'.
--- Ignore case in search patterns, completion, and when searching the tags file.
--- See also 'smartcase' and 'tagcase'.
--- Can be overruled by using "\c" or "\C" in the pattern, see
--- `/ignorecase`.
---

View File

@ -4528,7 +4528,7 @@ function vim.fn.jobresize(job, width, height) end
--- @return any
function vim.fn.jobsend(...) end
--- Note: Prefer |vim.system()| in Lua.
--- Note: Prefer |vim.system()| in Lua (unless using the `pty` option).
---
--- Spawns {cmd} as a job.
--- If {cmd} is a List it runs directly (no 'shell').

View File

@ -534,12 +534,12 @@ function vim.tbl_flatten(t)
return result
end
--- Enumerate a table sorted by its keys.
--- Enumerates key-value pairs of a table, ordered by key.
---
---@see Based on https://github.com/premake/premake-core/blob/master/src/base/table.lua
---
---@param t table Dict-like table
---@return function iterator over sorted keys and their values
---@return function # |for-in| iterator over sorted keys and their values
function vim.spairs(t)
assert(type(t) == 'table', string.format('Expected table, got %s', type(t)))
@ -551,7 +551,6 @@ function vim.spairs(t)
table.sort(keys)
-- Return the iterator function.
-- TODO(justinmk): Return "iterator function, table {t}, and nil", like pairs()?
local i = 0
return function()
i = i + 1
@ -561,11 +560,14 @@ function vim.spairs(t)
end
end
--- Tests if a Lua table can be treated as an array (a table indexed by integers).
--- Tests if `t` is an "array": a table indexed _only_ by integers (potentially non-contiguous).
---
--- Empty table `{}` is assumed to be an array, unless it was created by
--- |vim.empty_dict()| or returned as a dict-like |API| or Vimscript result,
--- for example from |rpcrequest()| or |vim.fn|.
--- If the indexes start from 1 and are contiguous then the array is also a list. |vim.tbl_islist()|
---
--- Empty table `{}` is an array, unless it was created by |vim.empty_dict()| or returned as
--- a dict-like |API| or Vimscript result, for example from |rpcrequest()| or |vim.fn|.
---
---@see https://github.com/openresty/luajit2#tableisarray
---
---@param t table
---@return boolean `true` if array-like table, else `false`.
@ -597,11 +599,13 @@ function vim.tbl_isarray(t)
end
end
--- Tests if a Lua table can be treated as a list (a table indexed by consecutive integers starting from 1).
--- Tests if `t` is a "list": a table indexed _only_ by contiguous integers starting from 1 (what
--- |lua-length| calls a "regular array").
---
--- Empty table `{}` is assumed to be an list, unless it was created by
--- |vim.empty_dict()| or returned as a dict-like |API| or Vimscript result,
--- for example from |rpcrequest()| or |vim.fn|.
--- Empty table `{}` is a list, unless it was created by |vim.empty_dict()| or returned as
--- a dict-like |API| or Vimscript result, for example from |rpcrequest()| or |vim.fn|.
---
---@see |vim.tbl_isarray()|
---
---@param t table
---@return boolean `true` if list-like table, else `false`.
@ -705,61 +709,6 @@ function vim.endswith(s, suffix)
return #suffix == 0 or s:sub(-#suffix) == suffix
end
--- Validates a parameter specification (types and values).
---
--- Usage example:
---
--- ```lua
--- function user.new(name, age, hobbies)
--- vim.validate{
--- name={name, 'string'},
--- age={age, 'number'},
--- hobbies={hobbies, 'table'},
--- }
--- ...
--- end
--- ```
---
--- Examples with explicit argument values (can be run directly):
---
--- ```lua
--- vim.validate{arg1={{'foo'}, 'table'}, arg2={'foo', 'string'}}
--- --> NOP (success)
---
--- vim.validate{arg1={1, 'table'}}
--- --> error('arg1: expected table, got number')
---
--- vim.validate{arg1={3, function(a) return (a % 2) == 0 end, 'even number'}}
--- --> error('arg1: expected even number, got 3')
--- ```
---
--- If multiple types are valid they can be given as a list.
---
--- ```lua
--- vim.validate{arg1={{'foo'}, {'table', 'string'}}, arg2={'foo', {'table', 'string'}}}
--- -- NOP (success)
---
--- vim.validate{arg1={1, {'string', 'table'}}}
--- -- error('arg1: expected string|table, got number')
---
--- ```
---
---@param opt table Names of parameters to validate. Each key is a parameter
--- name; each value is a tuple in one of these forms:
--- 1. (arg_value, type_name, optional)
--- - arg_value: argument value
--- - type_name: string|table type name, one of: ("table", "t", "string",
--- "s", "number", "n", "boolean", "b", "function", "f", "nil",
--- "thread", "userdata") or list of them.
--- - optional: (optional) boolean, if true, `nil` is valid
--- 2. (arg_value, fn, msg)
--- - arg_value: argument value
--- - fn: any function accepting one argument, returns true if and
--- only if the argument is valid. Can optionally return an additional
--- informative error message as the second returned value.
--- - msg: (optional) error string if validation fails
function vim.validate(opt) end -- luacheck: no unused
do
local type_names = {
['table'] = 'table',
@ -844,6 +793,59 @@ do
return true, nil
end
--- Validates a parameter specification (types and values).
---
--- Usage example:
---
--- ```lua
--- function user.new(name, age, hobbies)
--- vim.validate{
--- name={name, 'string'},
--- age={age, 'number'},
--- hobbies={hobbies, 'table'},
--- }
--- ...
--- end
--- ```
---
--- Examples with explicit argument values (can be run directly):
---
--- ```lua
--- vim.validate{arg1={{'foo'}, 'table'}, arg2={'foo', 'string'}}
--- --> NOP (success)
---
--- vim.validate{arg1={1, 'table'}}
--- --> error('arg1: expected table, got number')
---
--- vim.validate{arg1={3, function(a) return (a % 2) == 0 end, 'even number'}}
--- --> error('arg1: expected even number, got 3')
--- ```
---
--- If multiple types are valid they can be given as a list.
---
--- ```lua
--- vim.validate{arg1={{'foo'}, {'table', 'string'}}, arg2={'foo', {'table', 'string'}}}
--- -- NOP (success)
---
--- vim.validate{arg1={1, {'string', 'table'}}}
--- -- error('arg1: expected string|table, got number')
---
--- ```
---
---@param opt table Names of parameters to validate. Each key is a parameter
--- name; each value is a tuple in one of these forms:
--- 1. (arg_value, type_name, optional)
--- - arg_value: argument value
--- - type_name: string|table type name, one of: ("table", "t", "string",
--- "s", "number", "n", "boolean", "b", "function", "f", "nil",
--- "thread", "userdata") or list of them.
--- - optional: (optional) boolean, if true, `nil` is valid
--- 2. (arg_value, fn, msg)
--- - arg_value: argument value
--- - fn: any function accepting one argument, returns true if and
--- only if the argument is valid. Can optionally return an additional
--- informative error message as the second returned value.
--- - msg: (optional) error string if validation fails
function vim.validate(opt)
local ok, err_msg = is_valid(opt)
if not ok then
@ -866,28 +868,25 @@ function vim.is_callable(f)
return type(m.__call) == 'function'
end
--- Creates a table whose members are automatically created when accessed, if they don't already
--- exist.
--- Creates a table whose missing keys are provided by {createfn} (like Python's "defaultdict").
---
--- They mimic defaultdict in python.
---
--- If {create} is `nil`, this will create a defaulttable whose constructor function is
--- this function, effectively allowing to create nested tables on the fly:
--- If {createfn} is `nil` it defaults to defaulttable() itself, so accessing nested keys creates
--- nested tables:
---
--- ```lua
--- local a = vim.defaulttable()
--- a.b.c = 1
--- ```
---
---@param create function?(key:any):any The function called to create a missing value.
---@return table Empty table with metamethod
function vim.defaulttable(create)
create = create or function(_)
---@param createfn function?(key:any):any Provides the value for a missing `key`.
---@return table # Empty table with `__index` metamethod.
function vim.defaulttable(createfn)
createfn = createfn or function(_)
return vim.defaulttable()
end
return setmetatable({}, {
__index = function(tbl, key)
rawset(tbl, key, create(key))
rawset(tbl, key, createfn(key))
return rawget(tbl, key)
end,
})

View File

@ -597,8 +597,9 @@ function M.edit_query(lang)
})
api.nvim_buf_set_lines(query_buf, 0, -1, false, {
';; Write your query here. Use @captures to highlight matches in the source buffer.',
';; Completion for grammar nodes is available (see :h compl-omni)',
';; Write queries here (see $VIMRUNTIME/queries/ for examples).',
';; Move cursor to a capture ("@foo") to highlight matches in the source buffer.',
';; Completion for grammar nodes is available (:help compl-omni)',
'',
'',
})

View File

@ -843,11 +843,13 @@ function M.omnifunc(findstart, base)
return require('vim.treesitter._query_linter').omnifunc(findstart, base)
end
--- Open a window for live editing of a treesitter query.
--- Opens a live editor to query the buffer you started from.
---
--- Can also be shown with `:EditQuery`. *:EditQuery*
--- Can also be shown with *:EditQuery*.
---
--- Note that the editor opens a scratch buffer, and so queries aren't persisted on disk.
--- If you move the cursor to a capture name ("@foo"), text matching the capture is highlighted in
--- the source buffer. The query editor is a scratch buffer, use `:write` to save it. You can find
--- example queries at `$VIMRUNTIME/queries/`.
---
--- @param lang? string language to open the query editor for. If omitted, inferred from the current buffer's filetype.
function M.edit(lang)

View File

@ -1441,7 +1441,7 @@ ArrayOf(Dictionary) nvim_get_keymap(String mode)
/// @param rhs Right-hand-side |{rhs}| of the mapping.
/// @param opts Optional parameters map: Accepts all |:map-arguments| as keys except |<buffer>|,
/// values are booleans (default false). Also:
/// - "noremap" non-recursive mapping |:noremap|
/// - "noremap" disables |recursive_mapping|, like |:noremap|
/// - "desc" human-readable description.
/// - "callback" Lua function called in place of {rhs}.
/// - "replace_keycodes" (boolean) When "expr" is true, replace keycodes in the

View File

@ -5572,7 +5572,7 @@ M.funcs = {
jobstart = {
args = { 1, 2 },
desc = [=[
Note: Prefer |vim.system()| in Lua.
Note: Prefer |vim.system()| in Lua (unless using the `pty` option).
Spawns {cmd} as a job.
If {cmd} is a List it runs directly (no 'shell').

View File

@ -3938,9 +3938,8 @@ return {
cb = 'did_set_ignorecase',
defaults = { if_true = false },
desc = [=[
Ignore case in search patterns. Also used when searching in the tags
file.
Also see 'smartcase' and 'tagcase'.
Ignore case in search patterns, completion, and when searching the tags file.
See also 'smartcase' and 'tagcase'.
Can be overruled by using "\c" or "\C" in the pattern, see
|/ignorecase|.
]=],