mirror of
https://github.com/neovim/neovim.git
synced 2026-09-13 01:21:06 +00:00
build: enable more EmmyLua checks
- call-non-callable - missing-fields - redefined-label - redefined-local - undefined-field - unreachable-code Promote redefined-local and unreachable-code to warnings. Fix DOS line-ending handling for multiline semantic tokens, and support intersection types in the help parser. AI-assisted
This commit is contained in:
committed by
Lewis Russell
parent
ec65796cea
commit
6a54396db4
10
.emmyrc.json
10
.emmyrc.json
@@ -29,31 +29,27 @@
|
||||
"annotation-usage-error",
|
||||
"assign-type-mismatch",
|
||||
"await-in-sync",
|
||||
"call-non-callable",
|
||||
"code-style-check",
|
||||
"deprecated",
|
||||
"global-in-non-module",
|
||||
"incomplete-signature-doc",
|
||||
"invert-if",
|
||||
"iter-variable-reassign",
|
||||
"missing-fields",
|
||||
"missing-global-doc",
|
||||
"need-check-nil",
|
||||
"non-literal-expressions-in-assert",
|
||||
"param-type-mismatch",
|
||||
"preferred-local-alias",
|
||||
"redefined-label",
|
||||
"redefined-local",
|
||||
"return-type-mismatch",
|
||||
"undefined-field",
|
||||
"unknown-doc-tag",
|
||||
"unnecessary-assert",
|
||||
"unnecessary-if",
|
||||
"unreachable-code",
|
||||
"unused"
|
||||
],
|
||||
"severity": {
|
||||
"duplicate-require": "warning"
|
||||
"duplicate-require": "warning",
|
||||
"redefined-local": "warning",
|
||||
"unreachable-code": "warning"
|
||||
}
|
||||
},
|
||||
"codeAction": {
|
||||
|
||||
@@ -659,11 +659,11 @@ Lua module: vim.diagnostic *diagnostic-api*
|
||||
• {severity}? (`vim.diagnostic.SeverityFilter`) Only show signs for
|
||||
diagnostics matching the given severity
|
||||
|diagnostic-severity|
|
||||
• {text}? (`table<vim.diagnostic.Severity,string>`) A table mapping
|
||||
|diagnostic-severity| to the sign text to display in the
|
||||
sign column and statusline. The default is to use `"E"`,
|
||||
`"W"`, `"I"`, and `"H"` for errors, warnings,
|
||||
information, and hints, respectively. Example: >lua
|
||||
• {text}? (`table<vim.diagnostic.Severity|vim.diagnostic.SeverityName,string>`)
|
||||
A table mapping |diagnostic-severity| to the sign text to
|
||||
display in the sign column and statusline. The default is
|
||||
to use `"E"`, `"W"`, `"I"`, and `"H"` for errors,
|
||||
warnings, information, and hints, respectively. Example: >lua
|
||||
vim.diagnostic.config({
|
||||
signs = { text = { [vim.diagnostic.severity.ERROR] = 'E', ... } }
|
||||
})
|
||||
@@ -803,6 +803,9 @@ config({opts}, {namespace}) *vim.diagnostic.config()*
|
||||
• {namespace} (`integer?`) Update the options for the given namespace.
|
||||
When omitted, update the global diagnostic options.
|
||||
|
||||
Overloads: ~
|
||||
• `fun(opts?: nil, namespace?: integer): vim.diagnostic.Opts`
|
||||
|
||||
Return: ~
|
||||
(`vim.diagnostic.Opts?`) Current diagnostic config if {opts} is
|
||||
omitted.
|
||||
|
||||
@@ -1438,7 +1438,8 @@ tagfunc({pattern}, {flags}) *vim.lsp.tagfunc()*
|
||||
• {flags} (`string`) See |tag-function|
|
||||
|
||||
Return: ~
|
||||
(`table[]`) tags A list of matching tags
|
||||
(`table[]|vim.NIL`) tags A list of matching tags, or `vim.NIL` to use
|
||||
the built-in tags.
|
||||
|
||||
|
||||
==============================================================================
|
||||
|
||||
@@ -1828,7 +1828,12 @@ vim.list.bisect({t}, {val}, {opts}) *vim.list.bisect()*
|
||||
Use {bound} to determine whether to return the first or the last position,
|
||||
defaults to "lower", i.e., the first position.
|
||||
|
||||
NOTE: Behavior is undefined on unsorted lists!
|
||||
With {opts.key}, {val} may differ from the list elements, provided the key
|
||||
function accepts both. For a string key, that field must exist on both. A
|
||||
partial record is sufficient if it contains all fields used by the key.
|
||||
|
||||
NOTE: The values being compared must support `<`, and the list must be
|
||||
sorted by those values (after applying {opts.key}, if provided).
|
||||
|
||||
Example: >lua
|
||||
|
||||
@@ -1858,7 +1863,7 @@ vim.list.bisect({t}, {val}, {opts}) *vim.list.bisect()*
|
||||
Since: 0.12.0
|
||||
|
||||
Parameters: ~
|
||||
• {t} (`any[]`) A comparable list.
|
||||
• {t} (`any[]`) A sorted list.
|
||||
• {val} (`any`) The value to search.
|
||||
• {opts} (`table?`) A table with the following fields:
|
||||
• {bound}? (`'lower'|'upper'`, default: `'lower'`) Specifies
|
||||
@@ -1869,11 +1874,17 @@ vim.list.bisect({t}, {val}, {opts}) *vim.list.bisect()*
|
||||
keeps the list sorted..
|
||||
• {hi}? (`integer`, default: `#t + 1`) End index of the list,
|
||||
exclusive.
|
||||
• {key}? (`string|fun(val: any): any`) Optional, compare the
|
||||
return value instead of the {val} itself if provided. If a
|
||||
string, index each value by this field name.
|
||||
• {key}? (`(string & keyof T)|fun(val: T): any`) Applied to
|
||||
{val} and the list elements being compared. If a string,
|
||||
index both by this field name. If a function, it must accept
|
||||
both {val} and the list elements and return mutually
|
||||
comparable keys.
|
||||
• {lo}? (`integer`, default: `1`) Start index of the list.
|
||||
|
||||
Overloads: ~
|
||||
• `fun<T, Q>(t: T[], val: Q, opts: vim.list.bisect.Opts<T|Q> & { key: fun(val: T|Q): any }): integer`
|
||||
• `fun<T: table, Q: table>(t: T[], val: Q, opts: vim.list.bisect.Opts<T|Q> & { key: string & keyof T & keyof Q }): integer`
|
||||
|
||||
Return: ~
|
||||
(`integer`) index serves as either the lower bound or the upper bound
|
||||
position.
|
||||
@@ -2252,11 +2263,11 @@ vim.tbl_map({fn}, {t}) *vim.tbl_map()*
|
||||
change).
|
||||
|
||||
Parameters: ~
|
||||
• {fn} (`fun(value: T): any`) Function
|
||||
• {fn} (`fun(value: T): R`) Function
|
||||
• {t} (`table<any, T>`) Table
|
||||
|
||||
Return: ~
|
||||
(`table`) Table of transformed values
|
||||
(`table<any, R>`) Table of transformed values
|
||||
|
||||
vim.tbl_values({t}) *vim.tbl_values()*
|
||||
Return a list of all values used in a table. However, the order of the
|
||||
|
||||
@@ -96,7 +96,8 @@ local function runnables()
|
||||
|
||||
if name == 'code' then
|
||||
local code = vim.treesitter.get_node_text(node, 0)
|
||||
local lang_node = match[metadata[id].lang][1] --[[@as TSNode]]
|
||||
local lang_id = metadata[id].lang --[[@as integer]]
|
||||
local lang_node = match[lang_id][1]
|
||||
local lang = vim.treesitter.get_node_text(lang_node, 0)
|
||||
for i = start + 1, end_ do
|
||||
code_blocks[i] = { lang = lang, code = code }
|
||||
|
||||
@@ -270,12 +270,13 @@ function M._match_manpage_path(paths, name, sect)
|
||||
end
|
||||
|
||||
-- find any that match the specified name
|
||||
--- @type string[]
|
||||
--- @param v string
|
||||
local namematches = vim.tbl_filter(function(v)
|
||||
local tail = vim.fs.basename(v)
|
||||
return tail:find(name, 1, true) ~= nil
|
||||
end, paths) or {}
|
||||
local sectmatches = {}
|
||||
end, paths)
|
||||
local sectmatches = {} --- @type string[]
|
||||
|
||||
if #namematches > 0 and sect ~= '' then
|
||||
--- @param v string
|
||||
|
||||
@@ -272,10 +272,10 @@ end
|
||||
--- Applies function `fn` to all values of table `t`, in `pairs()` iteration order (which is not
|
||||
--- guaranteed to be stable, even when the data doesn't change).
|
||||
---
|
||||
---@generic T
|
||||
---@param fn fun(value: T): any Function
|
||||
---@generic T, R
|
||||
---@param fn fun(value: T): R Function
|
||||
---@param t table<any, T> Table
|
||||
---@return table : Table of transformed values
|
||||
---@return table<any, R> : Table of transformed values
|
||||
function vim.tbl_map(fn, t)
|
||||
vim.validate('fn', fn, 'callable')
|
||||
vim.validate('t', t, 'table')
|
||||
@@ -457,7 +457,7 @@ function vim.list.unique(t, key)
|
||||
return t
|
||||
end
|
||||
|
||||
---@class vim.list.bisect.Opts
|
||||
---@class vim.list.bisect.Opts<T>
|
||||
---@inlinedoc
|
||||
---
|
||||
--- Start index of the list.
|
||||
@@ -468,9 +468,10 @@ end
|
||||
--- (default: `#t + 1`)
|
||||
---@field hi? integer
|
||||
---
|
||||
--- Optional, compare the return value instead of the {val} itself if provided.
|
||||
--- If a string, index each value by this field name.
|
||||
---@field key? string|fun(val: any): any
|
||||
--- Applied to {val} and the list elements being compared.
|
||||
--- If a string, index both by this field name. If a function, it must accept both
|
||||
--- {val} and the list elements and return mutually comparable keys.
|
||||
---@field key? (string & keyof T)|fun(val: T): any
|
||||
---
|
||||
--- Specifies the search variant.
|
||||
--- - "lower": returns the first position
|
||||
@@ -480,12 +481,12 @@ end
|
||||
--- (default: `'lower'`)
|
||||
---@field bound? 'lower' | 'upper'
|
||||
|
||||
---@generic T
|
||||
---@generic T, Q
|
||||
---@param t T[]
|
||||
---@param val T
|
||||
---@param val Q
|
||||
---@param lo integer
|
||||
---@param hi integer
|
||||
---@param key_fn fun(val: any): any
|
||||
---@param key_fn fun(val: T|Q): any
|
||||
---@return integer i in range such that `t[j]` < {val} for all j < i,
|
||||
--- and `t[j]` >= {val} for all j >= i,
|
||||
--- or return {hi} if no such index is found.
|
||||
@@ -503,12 +504,12 @@ local function lower_bound(t, val, lo, hi, key_fn)
|
||||
return lo
|
||||
end
|
||||
|
||||
---@generic T
|
||||
---@generic T, Q
|
||||
---@param t T[]
|
||||
---@param val T
|
||||
---@param val Q
|
||||
---@param lo integer
|
||||
---@param hi integer
|
||||
---@param key_fn fun(val: any): any
|
||||
---@param key_fn fun(val: T|Q): any
|
||||
---@return integer i in range such that `t[j]` <= {val} for all j < i,
|
||||
--- and `t[j]` > {val} for all j >= i,
|
||||
--- or return {hi} if no such index is found.
|
||||
@@ -532,7 +533,12 @@ end
|
||||
--- Use {bound} to determine whether to return the first or the last position,
|
||||
--- defaults to "lower", i.e., the first position.
|
||||
---
|
||||
--- NOTE: Behavior is undefined on unsorted lists!
|
||||
--- With {opts.key}, {val} may differ from the list elements, provided the key
|
||||
--- function accepts both. For a string key, that field must exist on both.
|
||||
--- A partial record is sufficient if it contains all fields used by the key.
|
||||
---
|
||||
--- NOTE: The values being compared must support `<`, and the list must be sorted
|
||||
--- by those values (after applying {opts.key}, if provided).
|
||||
---
|
||||
--- Example:
|
||||
--- ```lua
|
||||
@@ -560,10 +566,12 @@ end
|
||||
--- ```
|
||||
---@since 14
|
||||
---@generic T
|
||||
---@param t T[] A comparable list.
|
||||
---@param t T[] A sorted list.
|
||||
---@param val T The value to search.
|
||||
---@param opts? vim.list.bisect.Opts
|
||||
---@param opts? vim.list.bisect.Opts<T>
|
||||
---@return integer index serves as either the lower bound or the upper bound position.
|
||||
---@overload fun<T, Q>(t: T[], val: Q, opts: vim.list.bisect.Opts<T|Q> & { key: fun(val: T|Q): any }): integer
|
||||
---@overload fun<T: table, Q: table>(t: T[], val: Q, opts: vim.list.bisect.Opts<T|Q> & { key: string & keyof T & keyof Q }): integer
|
||||
function vim.list.bisect(t, val, opts)
|
||||
vim.validate('t', t, 'table')
|
||||
vim.validate('opts', opts, 'table', true)
|
||||
@@ -1131,6 +1139,7 @@ do
|
||||
end
|
||||
elseif vim.is_callable(validator) then
|
||||
-- Check user-provided validation function
|
||||
---@cast validator fun(v: any): boolean, string?
|
||||
local valid, opt_msg = validator(val)
|
||||
if not valid then
|
||||
local err_msg = ('%s: expected %s, got %s'):format(
|
||||
|
||||
@@ -237,6 +237,7 @@ local function setup_output(output, text)
|
||||
end
|
||||
end
|
||||
|
||||
--- @diagnostic disable-next-line:missing-fields luvit/luv#827
|
||||
local pipe_fd = assert(uv.pipe({ nonblock = true }, {}))
|
||||
local pipe = assert(uv.new_pipe(false))
|
||||
pipe:open(pipe_fd.read)
|
||||
@@ -268,6 +269,7 @@ local function setup_input(input)
|
||||
towrite = input
|
||||
end
|
||||
|
||||
--- @diagnostic disable-next-line:missing-fields luvit/luv#827
|
||||
local pipe_fd = assert(uv.pipe({}, { nonblock = true }))
|
||||
local pipe = assert(uv.new_pipe(false))
|
||||
pipe:open(pipe_fd.write)
|
||||
|
||||
@@ -21,6 +21,8 @@ if not has_clear then
|
||||
end
|
||||
end
|
||||
|
||||
---@cast new fun(narr: integer, nrec: integer): table
|
||||
---@cast clear fun(tab: table)
|
||||
M.new = new
|
||||
M.clear = clear
|
||||
|
||||
|
||||
@@ -737,13 +737,14 @@ end
|
||||
---@param focus? boolean Enter the pager: it was explicitly requested.
|
||||
function M.set_pos(tgt, focus)
|
||||
for t, win in pairs(ui.wins) do
|
||||
local cfg = (t == tgt or (tgt == nil and t ~= 'cmd'))
|
||||
local current_cfg = (t == tgt or (tgt == nil and t ~= 'cmd'))
|
||||
and api.nvim_win_is_valid(win)
|
||||
and api.nvim_win_get_config(win)
|
||||
if cfg and (tgt or not cfg.hide) then
|
||||
if current_cfg and (tgt or not current_cfg.hide) then
|
||||
local texth = api.nvim_win_text_height(win, { max_height = o.lines })
|
||||
local top = { mopt.msgsep, 'MsgSeparator' }
|
||||
cfg = { hide = false, relative = 'laststatus', col = 10000 } ---@type table
|
||||
---@type vim.api.keyset.win_config
|
||||
local cfg = { hide = false, relative = 'laststatus', col = 10000 }
|
||||
cfg.row, cfg.height, cfg.border = win_row_height_border(t, texth.all)
|
||||
cfg.border = cfg.border and t ~= 'msg' and { '', top, '', '', '', '', '', '' } or nil
|
||||
cfg.mouse = tgt == 'cmd' or t == 'msg' or nil
|
||||
|
||||
@@ -245,9 +245,9 @@ function M.watchdirs(path, opts, callback)
|
||||
for name, type in
|
||||
vim.fs.dir(path, {
|
||||
depth = max_depth,
|
||||
skip = function(name)
|
||||
skip = function(dir)
|
||||
return not opts.exclude_pattern
|
||||
or opts.exclude_pattern:match(vim.fs.joinpath(path, name)) == nil
|
||||
or opts.exclude_pattern:match(vim.fs.joinpath(path, dir)) == nil
|
||||
end,
|
||||
})
|
||||
do
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local M = {}
|
||||
local health = vim.health
|
||||
|
||||
local deprecated = {} ---@type [string, table, string][]
|
||||
local deprecated = {} ---@type table<string, [string, string[], string?]>
|
||||
|
||||
function M.check()
|
||||
if next(deprecated) == nil then
|
||||
|
||||
@@ -309,7 +309,7 @@ local M = vim._defer_require('vim.diagnostic', {
|
||||
--- signs = { text = { [vim.diagnostic.severity.ERROR] = 'E', ... } }
|
||||
--- })
|
||||
--- ```
|
||||
--- @field text? table<vim.diagnostic.Severity,string>
|
||||
--- @field text? table<vim.diagnostic.Severity|vim.diagnostic.SeverityName,string>
|
||||
---
|
||||
--- A table mapping |diagnostic-severity| to the highlight group used for the
|
||||
--- line number where the sign is placed.
|
||||
@@ -441,6 +441,7 @@ local all_namespaces = {}
|
||||
---@param namespace integer? Update the options for the given namespace.
|
||||
--- When omitted, update the global diagnostic options.
|
||||
---@return vim.diagnostic.Opts? : Current diagnostic config if {opts} is omitted.
|
||||
---@overload fun(opts?: nil, namespace?: integer): vim.diagnostic.Opts
|
||||
function M.config(opts, namespace)
|
||||
return M._config.config(opts, namespace)
|
||||
end
|
||||
|
||||
@@ -95,6 +95,7 @@ end
|
||||
--- @param namespace integer? Update the options for the given namespace.
|
||||
--- When omitted, update the global diagnostic options.
|
||||
--- @return vim.diagnostic.Opts? : Current diagnostic config if {opts} is omitted.
|
||||
--- @overload fun(opts?: nil, namespace?: integer): vim.diagnostic.Opts
|
||||
function M.config(opts, namespace)
|
||||
vim.validate('opts', opts, 'table', true)
|
||||
vim.validate('namespace', namespace, 'number', true)
|
||||
|
||||
@@ -219,8 +219,11 @@ function M.signs.show(namespace, bufnr, diagnostics, opts)
|
||||
|
||||
for _, diagnostic0 in ipairs(diagnostics) do
|
||||
if diagnostic0.lnum <= line_count then
|
||||
local severity_name = (
|
||||
severity --[[@as table<vim.diagnostic.Severity, vim.diagnostic.SeverityName>]]
|
||||
)[diagnostic0.severity]
|
||||
api.nvim_buf_set_extmark(bufnr, ns.user_data.sign_ns, diagnostic0.lnum, 0, {
|
||||
sign_text = text[diagnostic0.severity] or text[severity[diagnostic0.severity]] or 'U',
|
||||
sign_text = text[diagnostic0.severity] or text[severity_name] or 'U',
|
||||
sign_hl_group = sign_highlight_map[diagnostic0.severity],
|
||||
number_hl_group = numhl[diagnostic0.severity],
|
||||
line_hl_group = linehl[diagnostic0.severity],
|
||||
|
||||
@@ -135,11 +135,11 @@ local function filepath_to_healthcheck(path)
|
||||
else
|
||||
local rtp_lua = vim
|
||||
.iter(vim.api.nvim_get_runtime_file('lua/', true))
|
||||
:map(function(rtp_lua)
|
||||
return vim.fs.abspath(vim.fs.normalize(rtp_lua))
|
||||
:map(function(dir)
|
||||
return vim.fs.abspath(vim.fs.normalize(dir))
|
||||
end)
|
||||
:find(function(rtp_lua)
|
||||
return vim.fs.relpath(rtp_lua, path)
|
||||
:find(function(dir)
|
||||
return vim.fs.relpath(dir, path)
|
||||
end)
|
||||
-- "/path/to/rtp/lua/foo/bar/health.lua" => "foo/bar/health.lua"
|
||||
-- "/another/rtp/lua/baz/health/init.lua" => "baz/health/init.lua"
|
||||
@@ -314,6 +314,8 @@ function M.error(msg, ...)
|
||||
check_summary['error'] = check_summary['error'] + 1
|
||||
end
|
||||
|
||||
---@param path string
|
||||
---@return string
|
||||
local path2name = function(path)
|
||||
if vim.fs.ext(path) == 'lua' then
|
||||
-- Lua: transform "../lua/vim/lsp/health.lua" into "vim.lsp"
|
||||
@@ -340,13 +342,12 @@ end
|
||||
local PATTERNS = { '/autoload/health/*.vim', '/lua/**/**/health.lua', '/lua/**/**/health/init.lua' }
|
||||
--- :checkhealth completion function used by cmdexpand.c get_healthcheck_names()
|
||||
M._complete = function()
|
||||
local unique = vim ---@type table<string,boolean>
|
||||
---@param pattern string
|
||||
---@type table<string,boolean>
|
||||
local unique = vim
|
||||
.iter(vim.tbl_map(function(pattern)
|
||||
return vim.tbl_map(path2name, vim.api.nvim_get_runtime_file(pattern, true))
|
||||
end, PATTERNS))
|
||||
:flatten()
|
||||
---@param t table<string,boolean>
|
||||
:fold({}, function(t, name)
|
||||
t[name] = true -- Remove duplicates
|
||||
return t
|
||||
|
||||
@@ -1313,8 +1313,11 @@ function IterArray.new(t)
|
||||
}, IterArray)
|
||||
end
|
||||
|
||||
return setmetatable(M, {
|
||||
setmetatable(M, {
|
||||
__call = function(_, ...)
|
||||
return Iter.new(...)
|
||||
end,
|
||||
})
|
||||
|
||||
-- Return M separately to work around EmmyLuaLs/emmylua-analyzer-rust#1240.
|
||||
return M
|
||||
|
||||
@@ -284,8 +284,9 @@ end
|
||||
---
|
||||
--- @param name string
|
||||
--- @param cfg vim.lsp.Config
|
||||
--- @type vim.lsp.config
|
||||
--- @diagnostic disable-next-line:assign-type-mismatch
|
||||
function lsp.config(name, cfg)
|
||||
lsp.config = function(name, cfg)
|
||||
local _, _ = name, cfg -- ignore unused
|
||||
-- dummy proto for docs
|
||||
end
|
||||
@@ -321,6 +322,7 @@ end
|
||||
--- @class vim.lsp.config
|
||||
--- @field [string] vim.lsp.Config?
|
||||
--- @field package _configs table<string,vim.lsp.Config>
|
||||
--- @overload fun(name: string, cfg: vim.lsp.Config)
|
||||
lsp.config = setmetatable({ _configs = {} }, {
|
||||
--- @param self vim.lsp.config
|
||||
--- @param name string
|
||||
@@ -332,7 +334,7 @@ lsp.config = setmetatable({ _configs = {} }, {
|
||||
|
||||
if not rconfig.resolved_config then
|
||||
if name == '*' then
|
||||
rconfig.resolved_config = lsp.config._configs['*'] or {}
|
||||
rconfig.resolved_config = self._configs['*'] or {}
|
||||
return rconfig.resolved_config
|
||||
end
|
||||
|
||||
@@ -355,7 +357,7 @@ lsp.config = setmetatable({ _configs = {} }, {
|
||||
|
||||
rconfig.resolved_config = vim.tbl_deep_extend(
|
||||
'force',
|
||||
lsp.config._configs['*'] or {},
|
||||
self._configs['*'] or {},
|
||||
rtp_config or {},
|
||||
self._configs[name] or {}
|
||||
)
|
||||
@@ -1449,8 +1451,10 @@ end
|
||||
---@param pattern string Pattern used to find a workspace symbol
|
||||
---@param flags string See |tag-function|
|
||||
---
|
||||
---@return table[] tags A list of matching tags
|
||||
---@return table[]|vim.NIL tags A list of matching tags, or `vim.NIL` to use the built-in tags.
|
||||
function lsp.tagfunc(pattern, flags)
|
||||
-- EmmyLua incorrectly treats function exports referenced by @module as non-callable.
|
||||
--- @diagnostic disable-next-line:call-non-callable EmmyLuaLs/emmylua-analyzer-rust#1238
|
||||
return vim.lsp._tagfunc(pattern, flags)
|
||||
end
|
||||
|
||||
|
||||
@@ -48,9 +48,11 @@ local buf_capabilities = {}
|
||||
local M = {}
|
||||
M.__index = M
|
||||
|
||||
---@generic T: vim.lsp.Capability
|
||||
---@param self T
|
||||
---@param bufnr integer
|
||||
---@return self
|
||||
function M:new(bufnr)
|
||||
---@return T
|
||||
function M.new(self, bufnr)
|
||||
-- `self` in the `new()` function refers to the concrete type (i.e., the metatable).
|
||||
-- `Class` may be a subtype of `Capability`, as it supports inheritance.
|
||||
---@type vim.lsp.Capability
|
||||
@@ -63,7 +65,7 @@ function M:new(bufnr)
|
||||
all_capabilities[Class.name] = Class
|
||||
end
|
||||
|
||||
---@type vim.lsp.Capability
|
||||
---@type T
|
||||
self = setmetatable({}, Class)
|
||||
self.bufnr = bufnr
|
||||
self.augroup = api.nvim_create_augroup(string.format('nvim.lsp.%s:%s', self.name, bufnr), {
|
||||
|
||||
@@ -387,9 +387,9 @@ function M.foldtext(lnum)
|
||||
|
||||
line = state.row_text[row] or line
|
||||
local ok, parser = pcall(function()
|
||||
local parser = vim.treesitter.get_string_parser(line, lang)
|
||||
parser:parse(true)
|
||||
return parser
|
||||
local string_parser = vim.treesitter.get_string_parser(line, lang)
|
||||
string_parser:parse(true)
|
||||
return string_parser
|
||||
end)
|
||||
if not ok then
|
||||
return line
|
||||
|
||||
@@ -89,12 +89,11 @@ M.NodeType = Type
|
||||
--- @class vim.snippet.FormatData: { capture: number, modifier?: string, if_text?: string, else_text?: string }
|
||||
--- @class vim.snippet.SnippetData: { children: vim.snippet.Node<any>[] }
|
||||
|
||||
--- @type vim.snippet.Node<any>
|
||||
local Node = {}
|
||||
|
||||
--- @param self vim.snippet.Node<any>
|
||||
--- @return string
|
||||
--- @diagnostic disable-next-line: inject-field
|
||||
function Node:__tostring()
|
||||
function Node.__tostring(self)
|
||||
local node_text = {}
|
||||
local type, data = self.type, self.data
|
||||
if type == Type.Snippet then
|
||||
|
||||
@@ -84,6 +84,9 @@ local function query_workspace_symbols(pattern)
|
||||
return results
|
||||
end
|
||||
|
||||
---@param pattern string
|
||||
---@param flags string
|
||||
---@return table[]|vim.NIL
|
||||
local function tagfunc(pattern, flags)
|
||||
-- avoid definition/symbol queries for insert completion
|
||||
if string.match(flags, 'i') then
|
||||
|
||||
@@ -796,7 +796,7 @@ function M.rename(new_name, opts)
|
||||
|
||||
if client:supports_method('textDocument/prepareRename') then
|
||||
local params = util.make_position_params(win, client.offset_encoding)
|
||||
---@param result? lsp.Range|{ range: lsp.Range, placeholder: string }
|
||||
---@param result? lsp.PrepareRenameResult
|
||||
client:request('textDocument/prepareRename', params, function(err, result)
|
||||
if err or result == nil then
|
||||
if next(clients, idx) then
|
||||
@@ -816,10 +816,8 @@ function M.rename(new_name, opts)
|
||||
|
||||
local range ---@type vim.Range?
|
||||
if result.start then
|
||||
---@cast result lsp.Range
|
||||
range = vim.range.lsp(bufnr, result, client.offset_encoding)
|
||||
elseif result.range then
|
||||
---@cast result { range: lsp.Range, placeholder: string }
|
||||
range = vim.range.lsp(bufnr, result.range, client.offset_encoding)
|
||||
end
|
||||
if range then
|
||||
@@ -841,8 +839,6 @@ function M.rename(new_name, opts)
|
||||
prompt_opts.default = result.placeholder
|
||||
elseif result.start then
|
||||
prompt_opts.default = get_text_at_range(result, client.offset_encoding)
|
||||
elseif result.range then
|
||||
prompt_opts.default = get_text_at_range(result.range, client.offset_encoding)
|
||||
else
|
||||
prompt_opts.default = cword
|
||||
end
|
||||
@@ -1273,6 +1269,8 @@ local function on_code_action_results(results, opts)
|
||||
return
|
||||
end
|
||||
|
||||
-- Work around incorrect union narrowing: EmmyLuaLs/emmylua-analyzer-rust#1239.
|
||||
---@cast action lsp.CodeAction
|
||||
if action.disabled then
|
||||
vim.notify(action.disabled.reason, vim.log.levels.ERROR)
|
||||
return
|
||||
|
||||
@@ -417,7 +417,7 @@ function Client.create(config)
|
||||
local name = get_name(id, config)
|
||||
|
||||
--- @type vim.lsp.Client
|
||||
local self = {
|
||||
local self = setmetatable({
|
||||
id = id,
|
||||
config = config,
|
||||
handlers = config.handlers or {},
|
||||
@@ -455,7 +455,7 @@ function Client.create(config)
|
||||
|
||||
--- @deprecated use client.progress instead
|
||||
messages = { name = name, messages = {}, progress = {}, status = {} },
|
||||
}
|
||||
}, Client)
|
||||
|
||||
self.capabilities =
|
||||
vim.tbl_deep_extend('force', lsp.protocol.make_client_capabilities(), self.capabilities or {})
|
||||
@@ -516,8 +516,6 @@ function Client.create(config)
|
||||
})
|
||||
end
|
||||
|
||||
setmetatable(self, Client)
|
||||
|
||||
method_wrapper(self, Client, 'request')
|
||||
method_wrapper(self, Client, 'request_sync')
|
||||
method_wrapper(self, Client, 'notify')
|
||||
@@ -768,19 +766,19 @@ function Client:request(method, params, handler, bufnr)
|
||||
local request_registered = false
|
||||
|
||||
-- NOTE: rpc.request might call an in-process (Lua) server, thus may be synchronous.
|
||||
local success, request_id = self.rpc.request(method, params, function(err, result, request_id)
|
||||
local success, request_id = self.rpc.request(method, params, function(err, result, id)
|
||||
handler(err, result, {
|
||||
method = method,
|
||||
client_id = self.id,
|
||||
request_id = request_id,
|
||||
request_id = id,
|
||||
bufnr = bufnr,
|
||||
params = params,
|
||||
version = version,
|
||||
})
|
||||
end, function(request_id)
|
||||
end, function(id)
|
||||
-- Called when the server sends a response to the request (including cancelled acknowledgment).
|
||||
if request_registered then
|
||||
self:_process_request(request_id, 'complete')
|
||||
self:_process_request(id, 'complete')
|
||||
end
|
||||
already_responded = true
|
||||
end)
|
||||
|
||||
@@ -10,12 +10,12 @@ local Capability = require('vim.lsp._capability')
|
||||
---@class (private) vim.lsp.codelens.RowLenses
|
||||
---@field lenses lsp.CodeLens[]
|
||||
---@field version? integer `TextDocument` version most recently applied to this row.
|
||||
---
|
||||
|
||||
---@class (private) vim.lsp.codelens.ClientState
|
||||
---@field row_lenses table<integer, vim.lsp.codelens.RowLenses>
|
||||
---@field namespace integer
|
||||
---@field version? integer `TextDocument` version current state corresponds to.
|
||||
---
|
||||
|
||||
---@class (private) vim.lsp.codelens.Provider : vim.lsp.Capability
|
||||
---@field active table<integer, vim.lsp.codelens.Provider>
|
||||
---
|
||||
|
||||
@@ -163,7 +163,7 @@ local function tokens_to_ranges(data, bufnr, client, request, ranges)
|
||||
|
||||
if last_insert_idx < #ranges then
|
||||
local needs_insert = true
|
||||
local idx = vim.list.bisect(ranges, { line = range.line }, {
|
||||
local idx = vim.list.bisect(ranges, range, {
|
||||
lo = last_insert_idx,
|
||||
key = function(highlight)
|
||||
return highlight.line
|
||||
|
||||
@@ -107,6 +107,7 @@ function M.request(method, url, opts, on_response)
|
||||
return (b == nil and true) or (type(b) == 'string' and not b:match('^@'))
|
||||
end, true, 'body should be string and not start with @')
|
||||
vim.validate('on_response', on_response, 'function', true)
|
||||
---@cast on_response vim.net.request.ResponseFunc?
|
||||
|
||||
local retry = opts.retry or 3
|
||||
|
||||
|
||||
@@ -953,6 +953,7 @@ local function pack_add(plug, load)
|
||||
active_plugins[plug.path] = { plug = plug, id = n_active_plugins }
|
||||
|
||||
if vim.is_callable(load) then
|
||||
---@cast load -boolean
|
||||
load({ spec = vim.deepcopy(plug.spec), path = plug.path })
|
||||
return
|
||||
end
|
||||
@@ -1389,6 +1390,7 @@ end
|
||||
|
||||
--- @class vim.pack.keyset.update
|
||||
--- @inlinedoc
|
||||
--- @field package _ex? boolean
|
||||
--- @field force? boolean Whether to skip confirmation and make updates immediately. Default `false`.
|
||||
---
|
||||
--- @field offline? boolean Whether to skip downloading new updates. Default: `false`.
|
||||
@@ -1520,6 +1522,7 @@ end
|
||||
|
||||
--- @class vim.pack.keyset.del
|
||||
--- @inlinedoc
|
||||
--- @field package _ex? boolean
|
||||
--- @field force? boolean Whether to allow deleting an active plugin. Default `false`.
|
||||
|
||||
--- Remove plugins from disk
|
||||
|
||||
@@ -345,8 +345,8 @@ function M.offset(buf, offset)
|
||||
|
||||
local lnum = vim.list.bisect(
|
||||
setmetatable({}, {
|
||||
__index = function(_, lnum)
|
||||
return api.nvim_buf_get_offset(buf, lnum - 1)
|
||||
__index = function(_, idx)
|
||||
return api.nvim_buf_get_offset(buf, idx - 1)
|
||||
end,
|
||||
}),
|
||||
offset,
|
||||
@@ -364,6 +364,6 @@ setmetatable(M, {
|
||||
return M.new(...)
|
||||
end,
|
||||
})
|
||||
---@cast M +fun(buf: integer, row: integer, col: integer): vim.Pos
|
||||
---@cast M vim.Pos & fun(buf: integer, row: integer, col: integer): vim.Pos
|
||||
|
||||
return M
|
||||
|
||||
@@ -3,6 +3,9 @@ local iswin = vim.fn.has('win32') == 1
|
||||
|
||||
local M = {}
|
||||
|
||||
---@param cmd string[]
|
||||
---@return boolean
|
||||
---@return string?
|
||||
local function cmd_ok(cmd)
|
||||
local result = vim.system(cmd, { text = true }):wait()
|
||||
return result.code == 0, result.stdout
|
||||
|
||||
@@ -465,7 +465,6 @@ setmetatable(M, {
|
||||
return M.new(...)
|
||||
end,
|
||||
})
|
||||
---@cast M +fun(start: vim.Pos, end_: vim.Pos): vim.Range
|
||||
---@cast M +fun(buf: integer, start_row: integer, start_col: integer, end_row: integer, end_col: integer): vim.Range
|
||||
---@cast M vim.Range & (fun(start: vim.Pos, end_: vim.Pos): vim.Range) & (fun(buf: integer, start_row: integer, start_col: integer, end_row: integer, end_col: integer): vim.Range)
|
||||
|
||||
return M
|
||||
|
||||
@@ -214,6 +214,7 @@ local exp = m.P{ "Exp",
|
||||
((m.V"Definition" / firstdef) * (m.V"Definition" % adddef)^0) / mm.P
|
||||
}
|
||||
|
||||
--- @type vim.lpeg.Pattern
|
||||
local pattern = S * m.Cg(m.Cc(false), "G") * exp / mm.P * (-any + patt_error)
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ local history = {
|
||||
--- @field ltree vim.treesitter.LanguageTree
|
||||
--- @field region Range4
|
||||
|
||||
local M = {}
|
||||
local M = { TEST_SWITCH_PRIORITY = false }
|
||||
|
||||
--- @param node vim.treesitter.select.node
|
||||
--- @return string
|
||||
@@ -96,10 +96,8 @@ end
|
||||
--- @param ltree vim.treesitter.LanguageTree
|
||||
--- @return vim.treesitter.select.node.top
|
||||
local function create_top_node(tree, region, ltree)
|
||||
--- @type vim.treesitter.select.node.top
|
||||
local self = {
|
||||
node = tree:root(),
|
||||
top = {} --[[@as any]],
|
||||
ltree = ltree,
|
||||
region = region,
|
||||
}
|
||||
|
||||
@@ -298,7 +298,7 @@ end
|
||||
--- @param metadata vim.treesitter.query.TSMetadata
|
||||
--- @return string?
|
||||
local function get_url(match, bufnr, capture, metadata)
|
||||
---@type string|number|nil
|
||||
---@type string|integer|nil
|
||||
local url = metadata[capture] and metadata[capture].url
|
||||
|
||||
if not url or type(url) == 'string' then
|
||||
@@ -369,7 +369,6 @@ local function on_range_impl(
|
||||
self:for_each_highlight_state(function(state)
|
||||
subtree_counter = subtree_counter + 1
|
||||
local root_node = state.tstree:root()
|
||||
---@type { [1]: integer, [2]: integer, [3]: integer, [4]: integer }
|
||||
local root_range = { root_node:range() }
|
||||
|
||||
if
|
||||
|
||||
@@ -140,7 +140,7 @@ function LanguageTree.new(source, lang, opts)
|
||||
local injections = opts.injections or {}
|
||||
|
||||
--- @type vim.treesitter.LanguageTree
|
||||
local self = {
|
||||
local self = setmetatable({
|
||||
_source = source,
|
||||
_lang = lang,
|
||||
_children = {},
|
||||
@@ -159,9 +159,7 @@ function LanguageTree.new(source, lang, opts)
|
||||
_cb_queues = {},
|
||||
_callbacks = {},
|
||||
_callbacks_rec = {},
|
||||
}
|
||||
|
||||
setmetatable(self, LanguageTree)
|
||||
}, LanguageTree)
|
||||
|
||||
if vim.g.__ts_debug and type(vim.g.__ts_debug) == 'number' then
|
||||
self:_set_logger()
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
--- 1.2 - 2.3.0 is 1.2.0 - 2.3.0
|
||||
--- ```
|
||||
|
||||
---@class (internal) vim.VersionModule
|
||||
---@operator call: vim.Version
|
||||
local M = {}
|
||||
|
||||
---@nodoc
|
||||
@@ -101,6 +103,7 @@ local function cmp_prerel(prerel1, prerel2)
|
||||
end
|
||||
end
|
||||
|
||||
---@param key string|integer
|
||||
function Version:__index(key)
|
||||
return type(key) == 'number' and ({ self.major, self.minor, self.patch })[key] or Version[key]
|
||||
end
|
||||
|
||||
@@ -261,7 +261,7 @@ local function diff_dirs_builtin(left_dir, right_dir, opt)
|
||||
-- Detect possible renames
|
||||
if opt.rename.detect then
|
||||
for left_rel, left_path in pairs(left_only) do
|
||||
---@type {similarity: number, path: string?, rel: string}
|
||||
---@type {similarity: number, path: string?, rel: string?}
|
||||
local best_match = { similarity = opt.rename.similarity, path = nil }
|
||||
|
||||
for right_rel, right_path in pairs(right_only) do
|
||||
|
||||
11
runtime/pack/dist/opt/nvim.tohtml/lua/tohtml.lua
vendored
11
runtime/pack/dist/opt/nvim.tohtml/lua/tohtml.lua
vendored
@@ -1337,16 +1337,7 @@ local styletable_funcs = {
|
||||
local function state_generate_style(state)
|
||||
vim._with({ win = state.winid }, function()
|
||||
for _, fn in ipairs(styletable_funcs) do
|
||||
--- @type string?
|
||||
local cond
|
||||
if type(fn) == 'table' then
|
||||
cond = fn[2] --[[@as string]]
|
||||
--- @type function
|
||||
fn = fn[1]
|
||||
end
|
||||
if not cond or cond(state) then
|
||||
fn(state)
|
||||
end
|
||||
fn(state)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
@@ -49,12 +49,27 @@ local function treefy(ent, _tree, _last)
|
||||
return tree
|
||||
end
|
||||
|
||||
--- @class (private) vim.undotree.graph_line
|
||||
--- @field kind 'node'|'remove'|'branch'|'remove+branch'|'nochange_remove'
|
||||
--- @class (private) vim.undotree.graph_line.base
|
||||
--- @field index integer
|
||||
--- @field node_count integer
|
||||
--- @field node integer|integer[]
|
||||
--- @field index2 integer? -- for branch-index in `remove+branch`
|
||||
|
||||
--- @class (private) vim.undotree.graph_line.node: vim.undotree.graph_line.base
|
||||
--- @field kind 'node'|'remove'|'nochange_remove'
|
||||
--- @field node integer
|
||||
|
||||
--- @class (private) vim.undotree.graph_line.branch: vim.undotree.graph_line.base
|
||||
--- @field kind 'branch'
|
||||
--- @field node integer[]
|
||||
|
||||
--- @class (private) vim.undotree.graph_line.remove_branch: vim.undotree.graph_line.base
|
||||
--- @field kind 'remove+branch'
|
||||
--- @field node integer
|
||||
--- @field index2 integer
|
||||
|
||||
--- @alias vim.undotree.graph_line
|
||||
--- | vim.undotree.graph_line.node
|
||||
--- | vim.undotree.graph_line.branch
|
||||
--- | vim.undotree.graph_line.remove_branch
|
||||
|
||||
--- @param tree vim.undotree.tree
|
||||
--- @return vim.undotree.graph_line[]
|
||||
@@ -181,13 +196,15 @@ local function buf_apply_graph_lines(tree, graph_lines, buf, meta, find_seq)
|
||||
--- @type string?
|
||||
local line
|
||||
if v.kind == 'node' then
|
||||
-- Work around tagged union narrowing: EmmyLuaLs/emmylua-analyzer-rust#1241.
|
||||
local seq = v.node --[[@as integer]]
|
||||
line = ('| '):rep(v.index - 1)
|
||||
.. '*'
|
||||
.. (' |'):rep(v.node_count - v.index)
|
||||
.. ' '
|
||||
.. v.node
|
||||
.. seq
|
||||
.. ' ('
|
||||
.. undo_fmt_time(tree[v.node].time)
|
||||
.. undo_fmt_time(tree[seq].time)
|
||||
.. ')'
|
||||
elseif v.kind == 'remove' then
|
||||
line = ('| '):rep(v.index - 1) .. (' /'):rep(v.node_count - v.index)
|
||||
|
||||
@@ -257,6 +257,11 @@ local config = {
|
||||
fun.table = nil
|
||||
end
|
||||
|
||||
-- Render the callable version module as ordinary module functions.
|
||||
if fun.class == 'vim.VersionModule' then
|
||||
fun.classvar = nil
|
||||
end
|
||||
|
||||
if fun.classvar or vim.startswith(fun.name, 'vim.') or fun.module == 'vim.iter' then
|
||||
return
|
||||
end
|
||||
@@ -345,6 +350,9 @@ local config = {
|
||||
},
|
||||
fn_xform = function(fun)
|
||||
fun.name = fun.name:gsub('result%.', '')
|
||||
if fun.module == 'vim.lsp' and fun.name == 'config' then
|
||||
fun.table = nil
|
||||
end
|
||||
if fun.module == 'vim.lsp.protocol' then
|
||||
fun.classvar = nil
|
||||
end
|
||||
@@ -674,7 +682,7 @@ local function get_class(ty, classes)
|
||||
return
|
||||
end
|
||||
|
||||
local cty = ty:gsub('%s*|%s*nil', '?'):gsub('?$', ''):gsub('%[%]$', '')
|
||||
local cty = ty:gsub('%s*|%s*nil', '?'):gsub('?$', ''):gsub('%[%]$', ''):gsub('%b<>$', '')
|
||||
|
||||
return classes[cty]
|
||||
end
|
||||
|
||||
@@ -145,14 +145,15 @@ local typedef = P({
|
||||
'typedef',
|
||||
typedef = C(v.type),
|
||||
|
||||
type = v.ty * rep_array_opt_postfix * rep(Pf('|') * v.ty * rep_array_opt_postfix),
|
||||
type = v.ty * rep_array_opt_postfix * rep(Sf('|&') * v.ty * rep_array_opt_postfix),
|
||||
ty = v.composite + paren(v.typedef),
|
||||
composite = (v.types * array_postfix)
|
||||
+ (v.types * opt_postfix)
|
||||
+ (P(ty_ident) * P('...')) -- Generic vararg
|
||||
+ v.types,
|
||||
types = v.fun + v.generics + v.kv_table + v.tuple + v.dict + v.table_literal + ty_prims,
|
||||
types = v.keyof + v.fun + v.generics + v.kv_table + v.tuple + v.dict + v.table_literal + ty_prims,
|
||||
|
||||
keyof = P('keyof') * ws * v.ty,
|
||||
tuple = Pf('[') * comma1(v.type) * Plf(']'),
|
||||
dict = Pf('{') * comma1(Pf('[') * v.type * Pf(']') * colon * v.type) * Plf('}'),
|
||||
kv_table = Pf('table') * Pf('<') * v.type * Pf(',') * v.type * Plf('>'),
|
||||
|
||||
@@ -34,6 +34,14 @@ describe('luacats grammar', function()
|
||||
desc = 'this is a description',
|
||||
})
|
||||
|
||||
test(
|
||||
'@overload fun<T, Q>(opts: vim.list.bisect.Opts<T|Q> & { key: string & keyof T & keyof Q }): integer',
|
||||
{
|
||||
kind = 'overload',
|
||||
type = 'fun<T, Q>(opts: vim.list.bisect.Opts<T|Q> & { key: string & keyof T & keyof Q }): integer',
|
||||
}
|
||||
)
|
||||
|
||||
test('@param hello vim.type?|string? this is a description', {
|
||||
kind = 'param',
|
||||
name = 'hello',
|
||||
@@ -244,6 +252,8 @@ describe('luacats grammar', function()
|
||||
{ 'number[][][]' },
|
||||
{ 'number[][]?' },
|
||||
{ 'string|integer[][]?' },
|
||||
{ 'vim.type & { key: string|function }' },
|
||||
{ '(vim.type & { key: string })|nil' },
|
||||
|
||||
-- tuples
|
||||
{ '[string]' },
|
||||
|
||||
Reference in New Issue
Block a user