fix: type fixes

Type fixes caught by emmylua
This commit is contained in:
Lewis Russell
2025-06-05 11:31:51 +01:00
committed by Lewis Russell
parent 4c333fdbb7
commit 3b6084ddf4
51 changed files with 421 additions and 355 deletions

14
.emmyrc.json Normal file
View File

@ -0,0 +1,14 @@
{
"diagnostics" : {
"disable" : [
"unnecessary-if"
]
},
"codeAction": {
"insertSpace": true
},
"strict": {
"typeCall": true,
"arrayIndex": true
}
}

View File

@ -182,3 +182,9 @@ appimage-%:
bash scripts/genappimage.sh $* bash scripts/genappimage.sh $*
.PHONY: test clean distclean nvim libnvim cmake deps install appimage checkprefix benchmark $(FORMAT) $(LINT) $(TEST) .PHONY: test clean distclean nvim libnvim cmake deps install appimage checkprefix benchmark $(FORMAT) $(LINT) $(TEST)
.PHONY: emmylua-check
emmylua-check:
-emmylua_check runtime/lua \
--config .luarc.json \
--config .emmyrc.json

View File

@ -430,6 +430,8 @@ Example: >lua
Lua module: vim.diagnostic *diagnostic-api* Lua module: vim.diagnostic *diagnostic-api*
*vim.Diagnostic* *vim.Diagnostic*
Extends: |vim.Diagnostic.Set|
*diagnostic-structure* *diagnostic-structure*
Diagnostics use the same indexing as the rest of the Nvim API (i.e. Diagnostics use the same indexing as the rest of the Nvim API (i.e.
@ -437,8 +439,6 @@ Lua module: vim.diagnostic *diagnostic-api*
Fields: ~ Fields: ~
• {bufnr} (`integer`) Buffer number • {bufnr} (`integer`) Buffer number
• {lnum} (`integer`) The starting line of the diagnostic
(0-indexed)
• {end_lnum} (`integer`) The final line of the diagnostic (0-indexed) • {end_lnum} (`integer`) The final line of the diagnostic (0-indexed)
• {col} (`integer`) The starting column of the diagnostic • {col} (`integer`) The starting column of the diagnostic
(0-indexed) (0-indexed)
@ -446,29 +446,27 @@ Lua module: vim.diagnostic *diagnostic-api*
(0-indexed) (0-indexed)
• {severity} (`vim.diagnostic.Severity`) The severity of the • {severity} (`vim.diagnostic.Severity`) The severity of the
diagnostic |vim.diagnostic.severity| diagnostic |vim.diagnostic.severity|
• {namespace}? (`integer`)
*vim.Diagnostic.Set*
Diagnostics use the same indexing as the rest of the Nvim API (i.e.
0-based rows and columns). |api-indexing|
Fields: ~
• {lnum} (`integer`) The starting line of the diagnostic
(0-indexed)
• {col}? (`integer`, default: `0`) The starting column of the
diagnostic (0-indexed)
• {end_lnum}? (`integer`, default: `lnum`) The final line of the
diagnostic (0-indexed)
• {end_col}? (`integer`, default: `col`) The final column of the
diagnostic (0-indexed)
• {severity}? (`vim.diagnostic.Severity`, default: `vim.diagnostic.severity.ERROR`)
The severity of the diagnostic |vim.diagnostic.severity|
• {message} (`string`) The diagnostic text • {message} (`string`) The diagnostic text
• {source}? (`string`) The source of the diagnostic • {source}? (`string`) The source of the diagnostic
• {code}? (`string|integer`) The diagnostic code • {code}? (`string|integer`) The diagnostic code
• {user_data}? (`any`) arbitrary data plugins can add • {user_data}? (`any`) arbitrary data plugins can add
• {namespace}? (`integer`)
*vim.Diagnostic.Set*
Extends: |vim.Diagnostic|
Fields: ~
• {bufnr} (`nil`) Do not set. Will be overridden by
`vim.diagnostic.set()`.
• {namespace} (`nil`) Do not set. Will be overridden by
`vim.diagnostic.set()`.
• {col}? (`integer`, default: `0`) The starting column of the
diagnostic in bytes (0-indexed)
• {end_lnum}? (`integer`, default: same as `lnum`) The final line of
the diagnostic (0-indexed)
• {end_col}? (`integer`, default: same as `col`) The final column of
the diagnostic (0-indexed)
• {severity}? (`vim.diagnostic.Severity`, default: `vim.diagnostic.severity.ERROR`)
The severity of the diagnostic |vim.diagnostic.severity|
*vim.diagnostic.GetOpts* *vim.diagnostic.GetOpts*
A table with the following keys: A table with the following keys:

View File

@ -1069,7 +1069,7 @@ get_client_by_id({client_id}) *vim.lsp.get_client_by_id()*
• {client_id} (`integer`) client id • {client_id} (`integer`) client id
Return: ~ Return: ~
(`vim.lsp.Client?`) client rpc object (`vim.lsp.Client?`) client rpc object. See |vim.lsp.Client|.
get_clients({filter}) *vim.lsp.get_clients()* get_clients({filter}) *vim.lsp.get_clients()*
Get active clients. Get active clients.
@ -1279,7 +1279,8 @@ Lua module: vim.lsp.client *lsp-client*
• {id} (`integer`) The id allocated to the client. • {id} (`integer`) The id allocated to the client.
• {initialized} (`true?`) • {initialized} (`true?`)
• {name} (`string`) See |vim.lsp.ClientConfig|. • {name} (`string`) See |vim.lsp.ClientConfig|.
• {offset_encoding} (`string`) See |vim.lsp.ClientConfig|. • {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'`) See
|vim.lsp.ClientConfig|.
• {progress} (`vim.lsp.Client.Progress`) A ring buffer • {progress} (`vim.lsp.Client.Progress`) A ring buffer
(|vim.ringbuf()|) containing progress messages (|vim.ringbuf()|) containing progress messages
sent by the server. See sent by the server. See
@ -2546,7 +2547,7 @@ make_workspace_params({added}, {removed})
• {removed} (`lsp.WorkspaceFolder[]`) • {removed} (`lsp.WorkspaceFolder[]`)
Return: ~ Return: ~
(`lsp.WorkspaceFoldersChangeEvent`) (`lsp.DidChangeWorkspaceFoldersParams`)
*vim.lsp.util.open_floating_preview()* *vim.lsp.util.open_floating_preview()*
open_floating_preview({contents}, {syntax}, {opts}) open_floating_preview({contents}, {syntax}, {opts})

View File

@ -626,10 +626,10 @@ vim.hl.range({bufnr}, {ns}, {higroup}, {start}, {finish}, {opts})
• {bufnr} (`integer`) Buffer number to apply highlighting to • {bufnr} (`integer`) Buffer number to apply highlighting to
• {ns} (`integer`) Namespace to add highlight to • {ns} (`integer`) Namespace to add highlight to
• {higroup} (`string`) Highlight group to use for highlighting • {higroup} (`string`) Highlight group to use for highlighting
• {start} (`integer[]|string`) Start of region as a (line, column) • {start} (`[integer,integer]|string`) Start of region as a (line,
tuple or string accepted by |getpos()| column) tuple or string accepted by |getpos()|
• {finish} (`integer[]|string`) End of region as a (line, column) • {finish} (`[integer,integer]|string`) End of region as a (line,
tuple or string accepted by |getpos()| column) tuple or string accepted by |getpos()|
• {opts} (`table?`) A table with the following fields: • {opts} (`table?`) A table with the following fields:
• {regtype}? (`string`, default: `'v'` i.e. charwise) Type • {regtype}? (`string`, default: `'v'` i.e. charwise) Type
of range. See |getregtype()| of range. See |getregtype()|
@ -4684,7 +4684,7 @@ vim.text.indent({size}, {text}, {opts}) *vim.text.indent()*
Parameters: ~ Parameters: ~
• {size} (`integer`) Number of spaces. • {size} (`integer`) Number of spaces.
• {text} (`string`) Text to indent. • {text} (`string`) Text to indent.
• {opts} (`{ expandtab?: number }?`) • {opts} (`{ expandtab?: integer }?`)
Return (multiple): ~ Return (multiple): ~
(`string`) Indented text. (`string`) Indented text.

View File

@ -3537,7 +3537,7 @@ getcurpos([{winid}]) *getcurpos()*
• {winid} (`integer?`) • {winid} (`integer?`)
Return: ~ Return: ~
(`any`) (`[integer, integer, integer, integer, integer]`)
getcursorcharpos([{winid}]) *getcursorcharpos()* getcursorcharpos([{winid}]) *getcursorcharpos()*
Same as |getcurpos()| but the column number in the returned Same as |getcurpos()| but the column number in the returned
@ -3846,7 +3846,7 @@ getmatches([{win}]) *getmatches()*
• {win} (`integer?`) • {win} (`integer?`)
Return: ~ Return: ~
(`any`) (`vim.fn.getmatches.ret.item[]`)
getmousepos() *getmousepos()* getmousepos() *getmousepos()*
Returns a |Dictionary| with the last known position of the Returns a |Dictionary| with the last known position of the
@ -3952,7 +3952,7 @@ getpos({expr}) *getpos()*
• {expr} (`string`) • {expr} (`string`)
Return: ~ Return: ~
(`integer[]`) (`[integer, integer, integer, integer]`)
getqflist([{what}]) *getqflist()* getqflist([{what}]) *getqflist()*
Returns a |List| with all the current quickfix errors. Each Returns a |List| with all the current quickfix errors. Each
@ -4181,9 +4181,9 @@ getregion({pos1}, {pos2} [, {opts}]) *getregion()*
< <
Parameters: ~ Parameters: ~
• {pos1} (`table`) • {pos1} (`[integer, integer, integer, integer]`)
• {pos2} (`table`) • {pos2} (`[integer, integer, integer, integer]`)
• {opts} (`table?`) • {opts} (`{type?:string, exclusive?:boolean}?`)
Return: ~ Return: ~
(`string[]`) (`string[]`)
@ -4221,12 +4221,13 @@ getregionpos({pos1}, {pos2} [, {opts}]) *getregionpos()*
(default: |FALSE|) (default: |FALSE|)
Parameters: ~ Parameters: ~
• {pos1} (`table`) • {pos1} (`[integer, integer, integer, integer]`)
• {pos2} (`table`) • {pos2} (`[integer, integer, integer, integer]`)
• {opts} (`table?`) • {opts}
(`{type?:string, exclusive?:boolean, eol?:boolean}?`)
Return: ~ Return: ~
(`integer[][][]`) (`[ [integer, integer, integer, integer], [integer, integer, integer, integer] ][]`)
getregtype([{regname}]) *getregtype()* getregtype([{regname}]) *getregtype()*
The result is a String, which is type of register {regname}. The result is a String, which is type of register {regname}.
@ -7852,7 +7853,7 @@ readfile({fname} [, {type} [, {max}]]) *readfile()*
• {max} (`integer?`) • {max} (`integer?`)
Return: ~ Return: ~
(`any`) (`string[]`)
reduce({object}, {func} [, {initial}]) *reduce()* *E998* reduce({object}, {func} [, {initial}]) *reduce()* *E998*
{func} is called for every item in {object}, which can be a {func} is called for every item in {object}, which can be a
@ -9063,7 +9064,7 @@ setmatches({list} [, {win}]) *setmatches()*
window ID instead of the current window. window ID instead of the current window.
Parameters: ~ Parameters: ~
• {list} (`any`) • {list} (`vim.fn.getmatches.ret.item[]`)
• {win} (`integer?`) • {win} (`integer?`)
Return: ~ Return: ~
@ -11742,7 +11743,7 @@ virtcol({expr} [, {list} [, {winid}]]) *virtcol()*
• {winid} (`integer?`) • {winid} (`integer?`)
Return: ~ Return: ~
(`any`) (`integer|[integer, integer]`)
virtcol2col({winid}, {lnum}, {col}) *virtcol2col()* virtcol2col({winid}, {lnum}, {col}) *virtcol2col()*
The result is a Number, which is the byte index of the The result is a Number, which is the byte index of the

View File

@ -48,7 +48,7 @@
--- @class (private) vim.tohtml.line --- @class (private) vim.tohtml.line
--- @field virt_lines {[integer]:[string,integer][]} --- @field virt_lines {[integer]:[string,integer][]}
--- @field pre_text string[][] --- @field pre_text [string, integer?][]
--- @field hide? boolean --- @field hide? boolean
--- @field [integer] vim.tohtml.cell? (integer: (1-index, exclusive)) --- @field [integer] vim.tohtml.cell? (integer: (1-index, exclusive))
@ -229,7 +229,7 @@ local function cterm_to_hex(colorstr)
return colorstr return colorstr
end end
assert(colorstr ~= '') assert(colorstr ~= '')
local color = tonumber(colorstr) local color = tonumber(colorstr) --[[@as integer]]
assert(color and 0 <= color and color <= 255) assert(color and 0 <= color and color <= 255)
if cterm_color_cache[color] then if cterm_color_cache[color] then
return cterm_color_cache[color] return cterm_color_cache[color]
@ -398,7 +398,7 @@ end
local function styletable_syntax(state) local function styletable_syntax(state)
for row = state.start, state.end_ do for row = state.start, state.end_ do
local prev_id = 0 local prev_id = 0
local prev_col = nil local prev_col --- @type integer?
for col = 1, #vim.fn.getline(row) + 1 do for col = 1, #vim.fn.getline(row) + 1 do
local hlid = vim.fn.synID(row, col, 1) local hlid = vim.fn.synID(row, col, 1)
hlid = hlid == 0 and 0 or assert(register_hl(state, hlid)) hlid = hlid == 0 and 0 or assert(register_hl(state, hlid))
@ -430,7 +430,7 @@ local function styletable_diff(state)
break break
end end
local prev_id = 0 local prev_id = 0
local prev_col = nil local prev_col --- @type integer?
for col = 1, #vim.fn.getline(row) do for col = 1, #vim.fn.getline(row) do
local hlid = vim.fn.diff_hlID(row, col) local hlid = vim.fn.diff_hlID(row, col)
hlid = hlid == 0 and 0 or assert(register_hl(state, hlid)) hlid = hlid == 0 and 0 or assert(register_hl(state, hlid))
@ -486,7 +486,7 @@ local function styletable_treesitter(state)
end end
--- @param state vim.tohtml.state --- @param state vim.tohtml.state
--- @param extmark [integer, integer, integer, vim.api.keyset.set_extmark|any] --- @param extmark [integer, integer, integer, vim.api.keyset.extmark_details]
--- @param namespaces table<integer,string> --- @param namespaces table<integer,string>
local function _styletable_extmarks_highlight(state, extmark, namespaces) local function _styletable_extmarks_highlight(state, extmark, namespaces)
if not extmark[4].hl_group then if not extmark[4].hl_group then
@ -548,7 +548,7 @@ local function _styletable_extmarks_virt_text(state, extmark, namespaces)
else else
style_line_insert_virt_text(styletable[row + 1], col + 1, { i[1], hlid }) style_line_insert_virt_text(styletable[row + 1], col + 1, { i[1], hlid })
end end
virt_text_len = virt_text_len + len(i[1]) virt_text_len = virt_text_len + len(assert(i[1]))
end end
if extmark[4].virt_text_pos == 'overlay' then if extmark[4].virt_text_pos == 'overlay' then
styletable_insert_range(state, row + 1, col + 1, row + 1, col + virt_text_len + 1, HIDE_ID) styletable_insert_range(state, row + 1, col + 1, row + 1, col + virt_text_len + 1, HIDE_ID)
@ -588,7 +588,7 @@ local function _styletable_extmarks_virt_lines(state, extmark)
end end
--- @param state vim.tohtml.state --- @param state vim.tohtml.state
--- @param extmark [integer, integer, integer, vim.api.keyset.set_extmark|any] --- @param extmark [integer, integer, integer, vim.api.keyset.extmark_details]
local function _styletable_extmarks_conceal(state, extmark) local function _styletable_extmarks_conceal(state, extmark)
if not extmark[4].conceal or state.opt.conceallevel == 0 then if not extmark[4].conceal or state.opt.conceallevel == 0 then
return return
@ -611,6 +611,8 @@ local function styletable_extmarks(state)
--TODO(altermo) extmarks may have col/row which is outside of the buffer, which could cause an error --TODO(altermo) extmarks may have col/row which is outside of the buffer, which could cause an error
local bufnr = state.bufnr local bufnr = state.bufnr
local extmarks = vim.api.nvim_buf_get_extmarks(bufnr, -1, 0, -1, { details = true }) local extmarks = vim.api.nvim_buf_get_extmarks(bufnr, -1, 0, -1, { details = true })
--- @cast extmarks [integer,integer,integer,vim.api.keyset.extmark_details][]
local namespaces = {} --- @type table<integer, string> local namespaces = {} --- @type table<integer, string>
for ns, ns_id in pairs(vim.api.nvim_get_namespaces()) do for ns, ns_id in pairs(vim.api.nvim_get_namespaces()) do
namespaces[ns_id] = ns namespaces[ns_id] = ns
@ -662,14 +664,14 @@ local function styletable_conceal(state)
for col = 1, line_len_exclusive do for col = 1, line_len_exclusive do
--- @type integer,string,integer --- @type integer,string,integer
local is_concealed, conceal, hlid = unpack(vim.fn.synconcealed(row, col) --[[@as table]]) local is_concealed, conceal, hlid = unpack(vim.fn.synconcealed(row, col) --[[@as table]])
if is_concealed == 0 then if is_concealed ~= 0 then
assert(true) if not conceals[hlid] then
elseif not conceals[hlid] then
conceals[hlid] = { col, math.min(col + 1, line_len_exclusive), conceal } conceals[hlid] = { col, math.min(col + 1, line_len_exclusive), conceal }
else else
conceals[hlid][2] = math.min(col + 1, line_len_exclusive) conceals[hlid][2] = math.min(col + 1, line_len_exclusive)
end end
end end
end
for _, v in pairs(conceals) do for _, v in pairs(conceals) do
styletable_insert_conceal(state, row, v[1], row, v[2], v[3], 'Conceal') styletable_insert_conceal(state, row, v[1], row, v[2], v[3], 'Conceal')
end end
@ -679,9 +681,7 @@ end
--- @param state vim.tohtml.state --- @param state vim.tohtml.state
local function styletable_match(state) local function styletable_match(state)
for _, match in for _, match in ipairs(vim.fn.getmatches(state.winid)) do
ipairs(vim.fn.getmatches(state.winid) --[[@as (table[])]])
do
local hlid = register_hl(state, match.group) local hlid = register_hl(state, match.group)
local function range(srow, scol, erow, ecol) local function range(srow, scol, erow, ecol)
if match.group == 'Conceal' and state.opt.conceallevel ~= 0 then if match.group == 'Conceal' and state.opt.conceallevel ~= 0 then
@ -692,19 +692,19 @@ local function styletable_match(state)
end end
if match.pos1 then if match.pos1 then
for key, v in for key, v in
pairs(match --[[@as (table<string,integer[]>)]]) pairs(match --[[@as table<string,[integer,integer,integer]>]])
do do
if not key:match('^pos(%d+)$') then if key:match('^pos(%d+)$') then
assert(true) if #v == 1 then
elseif #v == 1 then
range(v[1], 1, v[1], #vim.fn.getline(v[1]) + 1) range(v[1], 1, v[1], #vim.fn.getline(v[1]) + 1)
else else
range(v[1], v[2], v[1], v[3] + v[2]) range(v[1], v[2], v[1], v[3] + v[2])
end end
end end
end
else else
for _, v in for _, v in
ipairs(vim.fn.matchbufline(state.bufnr, match.pattern, 1, '$') --[[@as (table[])]]) ipairs(vim.fn.matchbufline(state.bufnr, assert(match.pattern), 1, '$') --[[@as (table[])]])
do do
range(v.lnum, v.byteidx + 1, v.lnum, v.byteidx + 1 + #v.text) range(v.lnum, v.byteidx + 1, v.lnum, v.byteidx + 1 + #v.text)
end end
@ -744,13 +744,15 @@ local function styletable_statuscolumn(state)
signcolumn = 'auto' signcolumn = 'auto'
end end
if signcolumn ~= 'no' then if signcolumn ~= 'no' then
local max = tonumber(signcolumn:match('^%w-:(%d)')) or 1 local max = tonumber(signcolumn:match('^%w-:(%d)')) --[[@as integer?]]
or 1
if signcolumn:match('^auto') then if signcolumn:match('^auto') then
--- @type table<integer,integer> --- @type table<integer,integer>
local signcount = {} local signcount = {}
for _, extmark in for _, extmark in
ipairs(vim.api.nvim_buf_get_extmarks(state.bufnr, -1, 0, -1, { details = true })) ipairs(vim.api.nvim_buf_get_extmarks(state.bufnr, -1, 0, -1, { details = true }))
do do
--- @cast extmark [integer, integer, integer, vim.api.keyset.extmark_details]
if extmark[4].sign_text then if extmark[4].sign_text then
signcount[extmark[2]] = (signcount[extmark[2]] or 0) + 1 signcount[extmark[2]] = (signcount[extmark[2]] or 0) + 1
end end
@ -770,7 +772,8 @@ local function styletable_statuscolumn(state)
local foldcolumn = state.opt.foldcolumn local foldcolumn = state.opt.foldcolumn
if foldcolumn ~= '0' then if foldcolumn ~= '0' then
if foldcolumn:match('^auto') then if foldcolumn:match('^auto') then
local max = tonumber(foldcolumn:match('^%w-:(%d)')) or 1 local max = tonumber(foldcolumn:match('^%w-:(%d)')) --[[@as integer?]]
or 1
local maxfold = 0 local maxfold = 0
vim._with({ buf = state.bufnr }, function() vim._with({ buf = state.bufnr }, function()
for row = state.start, state.end_ do for row = state.start, state.end_ do
@ -782,11 +785,11 @@ local function styletable_statuscolumn(state)
end) end)
minwidth = minwidth + math.min(maxfold, max) minwidth = minwidth + math.min(maxfold, max)
else else
minwidth = minwidth + tonumber(foldcolumn) minwidth = minwidth + tonumber(foldcolumn) --[[@as integer]]
end end
end end
--- @type table<integer,any> --- @type table<integer,vim.api.keyset.eval_statusline_ret>
local statuses = {} local statuses = {}
for row = state.start, state.end_ do for row = state.start, state.end_ do
local status = vim.api.nvim_eval_statusline( local status = vim.api.nvim_eval_statusline(
@ -798,15 +801,13 @@ local function styletable_statuscolumn(state)
minwidth = width minwidth = width
end end
table.insert(statuses, status) table.insert(statuses, status)
--- @type string
end end
for row, status in pairs(statuses) do for row, status in pairs(statuses) do
--- @type string
local str = status.str local str = status.str
--- @type table[]
local hls = status.highlights local hls = status.highlights
for k, v in ipairs(hls) do for k, v in ipairs(hls) do
local text = str:sub(v.start + 1, hls[k + 1] and hls[k + 1].start or nil) local hlsk1 = hls[k + 1]
local text = str:sub(v.start + 1, hlsk1 and hlsk1.start or nil)
if k == #hls then if k == #hls then
text = text .. (' '):rep(minwidth - len(str)) text = text .. (' '):rep(minwidth - len(str))
end end
@ -852,11 +853,9 @@ local function styletable_listchars(state)
for _, match in for _, match in
ipairs(vim.fn.matchbufline(state.bufnr, '\t', 1, '$') --[[@as (table[])]]) ipairs(vim.fn.matchbufline(state.bufnr, '\t', 1, '$') --[[@as (table[])]])
do do
--- @type integer local vcol = vim.fn.virtcol({ match.lnum, match.byteidx }, false, state.winid) --[[@as integer]]
local tablen = #state.tabstop local tablen = #state.tabstop - (vcol % #state.tabstop)
- ((vim.fn.virtcol({ match.lnum, match.byteidx }, false, state.winid)) % #state.tabstop) local text --- @type string
--- @type string?
local text
if len(listchars.tab) == 3 then if len(listchars.tab) == 3 then
if tablen == 1 then if tablen == 1 then
text = utf8_sub(listchars.tab, 3, 3) text = utf8_sub(listchars.tab, 3, 3)
@ -1142,6 +1141,7 @@ local function extend_pre(out, state)
local before = '' local before = ''
local after = '' local after = ''
--- @param row integer
local function loop(row) local function loop(row)
local inside = row <= state.end_ and row >= state.start local inside = row <= state.end_ and row >= state.start
local style_line = styletable[row] local style_line = styletable[row]
@ -1168,7 +1168,7 @@ local function extend_pre(out, state)
pairs(style_line --[[@as table<string,any>]]) pairs(style_line --[[@as table<string,any>]])
do do
if type(k) == 'number' and k > true_line_len then if type(k) == 'number' and k > true_line_len then
true_line_len = k true_line_len = k --[[@as integer]]
end end
end end
for col = 1, true_line_len do for col = 1, true_line_len do
@ -1305,7 +1305,7 @@ local function opt_to_global_state(opt, title)
-- Input: "Font,Escape\,comma, Ignore space after comma" -- Input: "Font,Escape\,comma, Ignore space after comma"
-- Output: { "Font","Escape,comma","Ignore space after comma" } -- Output: { "Font","Escape,comma","Ignore space after comma" }
local prev = '' local prev = ''
for name in vim.gsplit(vim.o.guifont:match('^[^:]+'), ',', { trimempty = true }) do for name in vim.gsplit(assert(vim.o.guifont:match('^[^:]+')), ',', { trimempty = true }) do
if vim.endswith(name, '\\') then if vim.endswith(name, '\\') then
prev = prev .. vim.trim(name:sub(1, -2) .. ',') prev = prev .. vim.trim(name:sub(1, -2) .. ',')
elseif vim.trim(name) ~= '' then elseif vim.trim(name) ~= '' then

View File

@ -37,6 +37,10 @@ function F.ok_or_nil(status, ...)
end end
-- Nil pcall. -- Nil pcall.
--- @generic T
--- @param fn fun(...):T
--- @param ... T?
--- @return T
function F.npcall(fn, ...) function F.npcall(fn, ...)
return F.ok_or_nil(pcall(fn, ...)) return F.ok_or_nil(pcall(fn, ...))
end end

View File

@ -3,7 +3,7 @@
---@field right string Right part of comment ---@field right string Right part of comment
--- Get 'commentstring' at cursor --- Get 'commentstring' at cursor
---@param ref_position integer[] ---@param ref_position [integer,integer]
---@return string ---@return string
local function get_commentstring(ref_position) local function get_commentstring(ref_position)
local buf_cs = vim.bo.commentstring local buf_cs = vim.bo.commentstring
@ -62,7 +62,7 @@ local function get_commentstring(ref_position)
end end
--- Compute comment parts from 'commentstring' --- Compute comment parts from 'commentstring'
---@param ref_position integer[] ---@param ref_position [integer,integer]
---@return vim._comment.Parts ---@return vim._comment.Parts
local function get_comment_parts(ref_position) local function get_comment_parts(ref_position)
local cs = get_commentstring(ref_position) local cs = get_commentstring(ref_position)
@ -78,6 +78,7 @@ local function get_comment_parts(ref_position)
-- Structure of 'commentstring': <left part> <%s> <right part> -- Structure of 'commentstring': <left part> <%s> <right part>
local left, right = cs:match('^(.-)%%s(.-)$') local left, right = cs:match('^(.-)%%s(.-)$')
assert(left and right)
return { left = left, right = right } return { left = left, right = right }
end end
@ -112,6 +113,7 @@ local function get_lines_info(lines, parts)
for _, l in ipairs(lines) do for _, l in ipairs(lines) do
-- Update lines indent: minimum of all indents except blank lines -- Update lines indent: minimum of all indents except blank lines
local _, indent_width_cur, indent_cur = l:find('^(%s*)') local _, indent_width_cur, indent_cur = l:find('^(%s*)')
assert(indent_width_cur and indent_cur)
-- Ignore blank lines completely when making a decision -- Ignore blank lines completely when making a decision
if indent_width_cur < l:len() then if indent_width_cur < l:len() then
@ -188,7 +190,7 @@ end
--- Comment/uncomment buffer range --- Comment/uncomment buffer range
---@param line_start integer ---@param line_start integer
---@param line_end integer ---@param line_end integer
---@param ref_position? integer[] ---@param ref_position? [integer, integer]
local function toggle_lines(line_start, line_end, ref_position) local function toggle_lines(line_start, line_end, ref_position)
ref_position = ref_position or { line_start, 0 } ref_position = ref_position or { line_start, 0 }
local parts = get_comment_parts(ref_position) local parts = get_comment_parts(ref_position)

View File

@ -26,7 +26,7 @@ do
end, { desc = 'Edit treesitter query', nargs = '?' }) end, { desc = 'Edit treesitter query', nargs = '?' })
vim.api.nvim_create_user_command('Open', function(cmd) vim.api.nvim_create_user_command('Open', function(cmd)
vim.ui.open(cmd.fargs[1]) vim.ui.open(assert(cmd.fargs[1]))
end, { end, {
desc = 'Open file with system default handler. See :help vim.ui.open()', desc = 'Open file with system default handler. See :help vim.ui.open()',
nargs = 1, nargs = 1,
@ -253,11 +253,11 @@ do
end, { desc = 'Jump to the previous diagnostic in the current buffer' }) end, { desc = 'Jump to the previous diagnostic in the current buffer' })
vim.keymap.set('n', ']D', function() vim.keymap.set('n', ']D', function()
vim.diagnostic.jump({ count = math.huge, wrap = false }) vim.diagnostic.jump({ count = vim._maxint, wrap = false })
end, { desc = 'Jump to the last diagnostic in the current buffer' }) end, { desc = 'Jump to the last diagnostic in the current buffer' })
vim.keymap.set('n', '[D', function() vim.keymap.set('n', '[D', function()
vim.diagnostic.jump({ count = -math.huge, wrap = false }) vim.diagnostic.jump({ count = -vim._maxint, wrap = false })
end, { desc = 'Jump to the first diagnostic in the current buffer' }) end, { desc = 'Jump to the first diagnostic in the current buffer' })
vim.keymap.set('n', '<C-W>d', function() vim.keymap.set('n', '<C-W>d', function()
@ -466,8 +466,8 @@ do
amenu disable PopUp.Configure\ Diagnostics amenu disable PopUp.Configure\ Diagnostics
]]) ]])
local urls = require('vim.ui')._get_urls() local url = require('vim.ui')._get_urls()[1]
if vim.startswith(urls[1], 'http') then if url and vim.startswith(url, 'http') then
vim.cmd([[amenu enable PopUp.Open\ in\ web\ browser]]) vim.cmd([[amenu enable PopUp.Open\ in\ web\ browser]])
elseif vim.lsp.get_clients({ bufnr = 0 })[1] then elseif vim.lsp.get_clients({ bufnr = 0 })[1] then
vim.cmd([[anoremenu enable PopUp.Go\ to\ definition]]) vim.cmd([[anoremenu enable PopUp.Go\ to\ definition]])
@ -595,7 +595,7 @@ do
{ limit = math.abs(count) } { limit = math.abs(count) }
) )
if #extmarks > 0 then if #extmarks > 0 then
local extmark = extmarks[math.min(#extmarks, math.abs(count))] local extmark = assert(extmarks[math.min(#extmarks, math.abs(count))])
vim.api.nvim_win_set_cursor(win, { extmark[2] + 1, extmark[3] }) vim.api.nvim_win_set_cursor(win, { extmark[2] + 1, extmark[3] })
end end
end end
@ -733,7 +733,7 @@ do
return nil return nil
end end
local max = tonumber(string.rep('f', #c), 16) local max = assert(tonumber(string.rep('f', #c), 16))
return val / max return val / max
end end
@ -876,7 +876,7 @@ do
end end
-- The returned SGR sequence should begin with 48:2 -- The returned SGR sequence should begin with 48:2
local sgr = attrs[#attrs]:match('^48:2:([%d:]+)$') local sgr = assert(attrs[#attrs]):match('^48:2:([%d:]+)$')
if not sgr then if not sgr then
return false return false
end end
@ -938,13 +938,13 @@ do
upward = true, upward = true,
limit = math.huge, limit = math.huge,
-- exrc in cwd already handled from C, thus start in parent directory. -- exrc in cwd already handled from C, thus start in parent directory.
path = vim.fs.dirname(vim.uv.cwd()), path = vim.fs.dirname((vim.uv.cwd())),
}) })
for _, file in ipairs(files) do for _, file in ipairs(files) do
local trusted = vim.secure.read(file) --[[@as string|nil]] local trusted = vim.secure.read(file) --[[@as string|nil]]
if trusted then if trusted then
if vim.endswith(file, '.lua') then if vim.endswith(file, '.lua') then
loadstring(trusted)() assert(loadstring(trusted))()
else else
vim.api.nvim_exec2(trusted, {}) vim.api.nvim_exec2(trusted, {})
end end

View File

@ -86,7 +86,7 @@ setmetatable(vim, {
}) })
--- <Docs described in |vim.empty_dict()| > --- <Docs described in |vim.empty_dict()| >
---@private ---@nodoc
--- TODO: should be in vim.shared when vim.shared always uses nvim-lua --- TODO: should be in vim.shared when vim.shared always uses nvim-lua
--- @diagnostic disable-next-line:duplicate-set-field --- @diagnostic disable-next-line:duplicate-set-field
function vim.empty_dict() function vim.empty_dict()

View File

@ -1135,7 +1135,7 @@ function vim.api.nvim_eval(expr) end
--- - use_tabline: (boolean) Evaluate tabline instead of statusline. When true, {winid} --- - use_tabline: (boolean) Evaluate tabline instead of statusline. When true, {winid}
--- is ignored. Mutually exclusive with {use_winbar}. --- is ignored. Mutually exclusive with {use_winbar}.
--- - use_statuscol_lnum: (number) Evaluate statuscolumn for this line number instead of statusline. --- - use_statuscol_lnum: (number) Evaluate statuscolumn for this line number instead of statusline.
--- @return table<string,any> # Dict containing statusline information, with these keys: --- @return vim.api.keyset.eval_statusline_ret # Dict containing statusline information, with these keys:
--- - str: (string) Characters that will be displayed on the statusline. --- - str: (string) Characters that will be displayed on the statusline.
--- - width: (number) Display width of the statusline. --- - width: (number) Display width of the statusline.
--- - highlights: Array containing highlight information of the statusline. Only included when --- - highlights: Array containing highlight information of the statusline. Only included when
@ -2538,7 +2538,7 @@ function vim.api.nvim_win_set_width(window, width) end
--- to find out how many buffer lines beyond "start_row" take --- to find out how many buffer lines beyond "start_row" take
--- up a certain number of logical lines (returned in --- up a certain number of logical lines (returned in
--- "end_row" and "end_vcol"). --- "end_row" and "end_vcol").
--- @return table<string,any> # Dict containing text height information, with these keys: --- @return vim.api.keyset.win_text_height_ret # Dict containing text height information, with these keys:
--- - all: The total number of screen lines occupied by the range. --- - all: The total number of screen lines occupied by the range.
--- - fill: The number of diff filler or virtual lines among them. --- - fill: The number of diff filler or virtual lines among them.
--- - end_row: The row on which the returned height is reached (first row of --- - end_row: The row on which the returned height is reached (first row of

View File

@ -20,7 +20,7 @@ error('Cannot require a meta file')
--- @field hl_group? string --- @field hl_group? string
--- @field hl_eol? boolean --- @field hl_eol? boolean
--- ---
--- @field conceal? boolean --- @field conceal? string
--- @field spell? boolean --- @field spell? boolean
--- @field ui_watched? boolean --- @field ui_watched? boolean
--- @field url? string --- @field url? string
@ -246,3 +246,19 @@ error('Cannot require a meta file')
--- @field range? integer[] --- @field range? integer[]
--- @field count? integer --- @field count? integer
--- @field reg? string --- @field reg? string
--- @class vim.api.keyset.eval_statusline_ret.highlight
--- @field start integer
--- @field group string
--- @field groups string[]
--- @class vim.api.keyset.eval_statusline_ret
--- @field str string
--- @field width integer
--- @field highlights vim.api.keyset.eval_statusline_ret.highlight[]
--- @class vim.api.keyset.win_text_height_ret
--- @field all integer
--- @field fill integer
--- @field end_row integer
--- @field end_vcol integer

View File

@ -1,5 +1,7 @@
--- @meta --- @meta
vim.base64 = {}
--- Encode {str} using Base64. --- Encode {str} using Base64.
--- ---
--- @param str string String to encode --- @param str string String to encode

View File

@ -39,6 +39,14 @@
--- @field pos [integer, integer, integer, integer] --- @field pos [integer, integer, integer, integer]
--- @field file string --- @field file string
--- @class vim.fn.getmatches.ret.item
--- @field id integer
--- @field group string
--- @field pattern? string
--- @field priority integer
--- @field conceal? string
--- @field [string] [integer, integer, integer] all strings of format 'pos%d'
--- @class vim.fn.getmousepos.ret --- @class vim.fn.getmousepos.ret
--- @field screenrow integer --- @field screenrow integer
--- @field screencol integer --- @field screencol integer

View File

@ -3175,7 +3175,7 @@ function vim.fn.getcompletion(pat, type, filtered) end
--- |winrestview()| for restoring more state. --- |winrestview()| for restoring more state.
--- ---
--- @param winid? integer --- @param winid? integer
--- @return any --- @return [integer, integer, integer, integer, integer]
function vim.fn.getcurpos(winid) end function vim.fn.getcurpos(winid) end
--- Same as |getcurpos()| but the column number in the returned --- Same as |getcurpos()| but the column number in the returned
@ -3450,7 +3450,7 @@ function vim.fn.getmarklist(buf) end
--- < --- <
--- ---
--- @param win? integer --- @param win? integer
--- @return any --- @return vim.fn.getmatches.ret.item[]
function vim.fn.getmatches(win) end function vim.fn.getmatches(win) end
--- Returns a |Dictionary| with the last known position of the --- Returns a |Dictionary| with the last known position of the
@ -3551,7 +3551,7 @@ function vim.fn.getpid() end
--- Also see |getcharpos()|, |getcurpos()| and |setpos()|. --- Also see |getcharpos()|, |getcurpos()| and |setpos()|.
--- ---
--- @param expr string --- @param expr string
--- @return integer[] --- @return [integer, integer, integer, integer]
function vim.fn.getpos(expr) end function vim.fn.getpos(expr) end
--- Returns a |List| with all the current quickfix errors. Each --- Returns a |List| with all the current quickfix errors. Each
@ -3776,9 +3776,9 @@ function vim.fn.getreginfo(regname) end
--- \ getpos('v'), getpos('.'), #{ type: mode() })<CR> --- \ getpos('v'), getpos('.'), #{ type: mode() })<CR>
--- < --- <
--- ---
--- @param pos1 table --- @param pos1 [integer, integer, integer, integer]
--- @param pos2 table --- @param pos2 [integer, integer, integer, integer]
--- @param opts? table --- @param opts? {type?:string, exclusive?:boolean}
--- @return string[] --- @return string[]
function vim.fn.getregion(pos1, pos2, opts) end function vim.fn.getregion(pos1, pos2, opts) end
@ -3813,10 +3813,10 @@ function vim.fn.getregion(pos1, pos2, opts) end
--- value of 0 is used for both positions. --- value of 0 is used for both positions.
--- (default: |FALSE|) --- (default: |FALSE|)
--- ---
--- @param pos1 table --- @param pos1 [integer, integer, integer, integer]
--- @param pos2 table --- @param pos2 [integer, integer, integer, integer]
--- @param opts? table --- @param opts? {type?:string, exclusive?:boolean, eol?:boolean}
--- @return integer[][][] --- @return [ [integer, integer, integer, integer], [integer, integer, integer, integer] ][]
function vim.fn.getregionpos(pos1, pos2, opts) end function vim.fn.getregionpos(pos1, pos2, opts) end
--- The result is a String, which is type of register {regname}. --- The result is a String, which is type of register {regname}.
@ -7133,7 +7133,7 @@ function vim.fn.readdir(directory, expr) end
--- @param fname string --- @param fname string
--- @param type? string --- @param type? string
--- @param max? integer --- @param max? integer
--- @return any --- @return string[]
function vim.fn.readfile(fname, type, max) end function vim.fn.readfile(fname, type, max) end
--- {func} is called for every item in {object}, which can be a --- {func} is called for every item in {object}, which can be a
@ -8256,7 +8256,7 @@ function vim.fn.setloclist(nr, list, action, what) end
--- If {win} is specified, use the window with this number or --- If {win} is specified, use the window with this number or
--- window ID instead of the current window. --- window ID instead of the current window.
--- ---
--- @param list any --- @param list vim.fn.getmatches.ret.item[]
--- @param win? integer --- @param win? integer
--- @return any --- @return any
function vim.fn.setmatches(list, win) end function vim.fn.setmatches(list, win) end
@ -10693,7 +10693,7 @@ function vim.fn.values(dict) end
--- @param expr string|any[] --- @param expr string|any[]
--- @param list? boolean --- @param list? boolean
--- @param winid? integer --- @param winid? integer
--- @return any --- @return integer|[integer, integer]
function vim.fn.virtcol(expr, list, winid) end function vim.fn.virtcol(expr, list, winid) end
--- The result is a Number, which is the byte index of the --- The result is a Number, which is the byte index of the

View File

@ -79,22 +79,19 @@ function SystemObj:_timeout(signal)
self:kill(signal or SIG.TERM) self:kill(signal or SIG.TERM)
end end
-- Use max 32-bit signed int value to avoid overflow on 32-bit systems. #31633
local MAX_TIMEOUT = 2 ^ 31 - 1
--- @param timeout? integer --- @param timeout? integer
--- @return vim.SystemCompleted --- @return vim.SystemCompleted
function SystemObj:wait(timeout) function SystemObj:wait(timeout)
local state = self._state local state = self._state
local done = vim.wait(timeout or state.timeout or MAX_TIMEOUT, function() local done = vim.wait(timeout or state.timeout or vim._maxint, function()
return state.result ~= nil return state.result ~= nil
end, nil, true) end, nil, true)
if not done then if not done then
-- Send sigkill since this cannot be caught -- Send sigkill since this cannot be caught
self:_timeout(SIG.KILL) self:_timeout(SIG.KILL)
vim.wait(timeout or state.timeout or MAX_TIMEOUT, function() vim.wait(timeout or state.timeout or vim._maxint, function()
return state.result ~= nil return state.result ~= nil
end, nil, true) end, nil, true)
end end

View File

@ -16,29 +16,28 @@ local function get_qf_id_for_title(title)
return nil return nil
end end
--- [diagnostic-structure]()
---
--- Diagnostics use the same indexing as the rest of the Nvim API (i.e. 0-based --- Diagnostics use the same indexing as the rest of the Nvim API (i.e. 0-based
--- rows and columns). |api-indexing| --- rows and columns). |api-indexing|
--- @class vim.Diagnostic --- @class vim.Diagnostic.Set
---
--- Buffer number
--- @field bufnr integer
--- ---
--- The starting line of the diagnostic (0-indexed) --- The starting line of the diagnostic (0-indexed)
--- @field lnum integer --- @field lnum integer
--- ---
--- The final line of the diagnostic (0-indexed)
--- @field end_lnum integer
---
--- The starting column of the diagnostic (0-indexed) --- The starting column of the diagnostic (0-indexed)
--- @field col integer --- (default: `0`)
--- @field col? integer
---
--- The final line of the diagnostic (0-indexed)
--- (default: `lnum`)
--- @field end_lnum? integer
--- ---
--- The final column of the diagnostic (0-indexed) --- The final column of the diagnostic (0-indexed)
--- @field end_col integer --- (default: `col`)
--- @field end_col? integer
--- ---
--- The severity of the diagnostic |vim.diagnostic.severity| --- The severity of the diagnostic |vim.diagnostic.severity|
--- @field severity vim.diagnostic.Severity --- (default: `vim.diagnostic.severity.ERROR`)
--- @field severity? vim.diagnostic.Severity
--- ---
--- The diagnostic text --- The diagnostic text
--- @field message string --- @field message string
@ -53,32 +52,18 @@ end
--- ---
--- Arbitrary data plugins or users can add --- Arbitrary data plugins or users can add
--- @field user_data? any arbitrary data plugins can add --- @field user_data? any arbitrary data plugins can add
---
--- @field namespace? integer
--- @class vim.Diagnostic.Set : vim.Diagnostic --- [diagnostic-structure]()
--- ---
--- Do not set. Will be overridden by `vim.diagnostic.set()`. --- Diagnostics use the same indexing as the rest of the Nvim API (i.e. 0-based
--- @field bufnr nil --- rows and columns). |api-indexing|
--- --- @class vim.Diagnostic : vim.Diagnostic.Set
--- Do not set. Will be overridden by `vim.diagnostic.set()`. --- @field bufnr integer Buffer number
--- @field namespace nil --- @field end_lnum integer The final line of the diagnostic (0-indexed)
--- --- @field col integer The starting column of the diagnostic (0-indexed)
--- The starting column of the diagnostic in bytes (0-indexed) --- @field end_col integer The final column of the diagnostic (0-indexed)
--- (default: `0`) --- @field severity vim.diagnostic.Severity The severity of the diagnostic |vim.diagnostic.severity|
--- @field col? integer --- @field namespace? integer
---
--- The final line of the diagnostic (0-indexed)
--- (default: same as `lnum`)
--- @field end_lnum? integer
---
--- The final column of the diagnostic (0-indexed)
--- (default: same as `col`)
--- @field end_col? integer
---
--- The severity of the diagnostic |vim.diagnostic.severity|
--- (default: `vim.diagnostic.severity.ERROR`)
--- @field severity? vim.diagnostic.Severity
--- Many of the configuration options below accept one of the following: --- Many of the configuration options below accept one of the following:
--- - `false`: Disable this feature --- - `false`: Disable this feature

View File

@ -40,7 +40,6 @@ local function starsetf(ft, priority)
} }
end end
---@private
--- Get a line range from the buffer. --- Get a line range from the buffer.
---@param bufnr integer The buffer to get the lines from ---@param bufnr integer The buffer to get the lines from
---@param start_lnum integer|nil The line number of the first line (inclusive, 1-based) ---@param start_lnum integer|nil The line number of the first line (inclusive, 1-based)
@ -55,7 +54,6 @@ function M._getlines(bufnr, start_lnum, end_lnum)
return api.nvim_buf_get_lines(bufnr, 0, -1, false) return api.nvim_buf_get_lines(bufnr, 0, -1, false)
end end
---@private
--- Get a single line from the buffer. --- Get a single line from the buffer.
---@param bufnr integer The buffer to get the lines from ---@param bufnr integer The buffer to get the lines from
---@param start_lnum integer The line number of the first line (inclusive, 1-based) ---@param start_lnum integer The line number of the first line (inclusive, 1-based)
@ -65,7 +63,6 @@ function M._getline(bufnr, start_lnum)
return api.nvim_buf_get_lines(bufnr, start_lnum - 1, start_lnum, false)[1] or '' return api.nvim_buf_get_lines(bufnr, start_lnum - 1, start_lnum, false)[1] or ''
end end
---@private
--- Check whether a string matches any of the given Lua patterns. --- Check whether a string matches any of the given Lua patterns.
--- ---
---@param s string? The string to check ---@param s string? The string to check
@ -83,7 +80,6 @@ function M._findany(s, patterns)
return false return false
end end
---@private
--- Get the next non-whitespace line in the buffer. --- Get the next non-whitespace line in the buffer.
--- ---
---@param bufnr integer The buffer to get the line from ---@param bufnr integer The buffer to get the line from
@ -102,7 +98,6 @@ do
--- @type table<string,vim.regex> --- @type table<string,vim.regex>
local regex_cache = {} local regex_cache = {}
---@private
--- Check whether the given string matches the Vim regex pattern. --- Check whether the given string matches the Vim regex pattern.
--- @param s string? --- @param s string?
--- @param pattern string --- @param pattern string
@ -215,7 +210,7 @@ local extension = {
art = 'art', art = 'art',
asciidoc = 'asciidoc', asciidoc = 'asciidoc',
adoc = 'asciidoc', adoc = 'asciidoc',
asa = function(path, bufnr) asa = function(_path, _bufnr)
if vim.g.filetype_asa then if vim.g.filetype_asa then
return vim.g.filetype_asa return vim.g.filetype_asa
end end
@ -266,7 +261,7 @@ local extension = {
bsd = 'bsdl', bsd = 'bsdl',
bsdl = 'bsdl', bsdl = 'bsdl',
bst = 'bst', bst = 'bst',
btm = function(path, bufnr) btm = function(_path, _bufnr)
return (vim.g.dosbatch_syntax_for_btm and vim.g.dosbatch_syntax_for_btm ~= 0) and 'dosbatch' return (vim.g.dosbatch_syntax_for_btm and vim.g.dosbatch_syntax_for_btm ~= 0) and 'dosbatch'
or 'btm' or 'btm'
end, end,
@ -319,7 +314,7 @@ local extension = {
atg = 'coco', atg = 'coco',
recipe = 'conaryrecipe', recipe = 'conaryrecipe',
ctags = 'conf', ctags = 'conf',
hook = function(path, bufnr) hook = function(_path, bufnr)
return M._getline(bufnr, 1) == '[Trigger]' and 'confini' or nil return M._getline(bufnr, 1) == '[Trigger]' and 'confini' or nil
end, end,
nmconnection = 'confini', nmconnection = 'confini',
@ -735,7 +730,7 @@ local extension = {
at = 'm4', at = 'm4',
mc = detect.mc, mc = detect.mc,
quake = 'm3quake', quake = 'm3quake',
m4 = function(path, bufnr) m4 = function(path, _bufnr)
local pathl = path:lower() local pathl = path:lower()
return not (pathl:find('html%.m4$') or pathl:find('fvwm2rc')) and 'm4' or nil return not (pathl:find('html%.m4$') or pathl:find('fvwm2rc')) and 'm4' or nil
end, end,
@ -1783,12 +1778,12 @@ local filename = {
['/etc/pinforc'] = 'pinfo', ['/etc/pinforc'] = 'pinfo',
['/.pinforc'] = 'pinfo', ['/.pinforc'] = 'pinfo',
['.povrayrc'] = 'povini', ['.povrayrc'] = 'povini',
printcap = function(path, bufnr) printcap = function(_path, _bufnr)
return 'ptcap', function(b) return 'ptcap', function(b)
vim.b[b].ptcap_type = 'print' vim.b[b].ptcap_type = 'print'
end end
end, end,
termcap = function(path, bufnr) termcap = function(_path, _bufnr)
return 'ptcap', function(b) return 'ptcap', function(b)
vim.b[b].ptcap_type = 'term' vim.b[b].ptcap_type = 'term'
end end
@ -2029,7 +2024,7 @@ local pattern = {
['/etc/modprobe%.'] = starsetf('modconf'), ['/etc/modprobe%.'] = starsetf('modconf'),
['/etc/modules%.conf$'] = 'modconf', ['/etc/modules%.conf$'] = 'modconf',
['/etc/modules$'] = 'modconf', ['/etc/modules$'] = 'modconf',
['/etc/modutils/'] = starsetf(function(path, bufnr) ['/etc/modutils/'] = starsetf(function(path, _bufnr)
if fn.executable(fn.expand(path)) ~= 1 then if fn.executable(fn.expand(path)) ~= 1 then
return 'modconf' return 'modconf'
end end
@ -2508,17 +2503,17 @@ local pattern = {
['/octave/history$'] = 'octave', ['/octave/history$'] = 'octave',
['%.opam%.locked$'] = 'opam', ['%.opam%.locked$'] = 'opam',
['%.opam%.template$'] = 'opam', ['%.opam%.template$'] = 'opam',
['^pacman%.log'] = starsetf(function(path, bufnr) ['^pacman%.log'] = starsetf(function(path, _bufnr)
return vim.uv.fs_stat(path) and 'pacmanlog' or nil return vim.uv.fs_stat(path) and 'pacmanlog' or nil
end), end),
['printcap'] = starsetf(function(path, bufnr) ['printcap'] = starsetf(function(_path, _bufnr)
return require('vim.filetype.detect').printcap('print') return require('vim.filetype.detect').printcap('print')
end), end),
['/queries/.*%.scm$'] = 'query', -- treesitter queries (Neovim only) ['/queries/.*%.scm$'] = 'query', -- treesitter queries (Neovim only)
[',v$'] = 'rcs', [',v$'] = 'rcs',
['^svn%-commit.*%.tmp$'] = 'svn', ['^svn%-commit.*%.tmp$'] = 'svn',
['%.swift%.gyb$'] = 'swiftgyb', ['%.swift%.gyb$'] = 'swiftgyb',
['termcap'] = starsetf(function(path, bufnr) ['termcap'] = starsetf(function(_path, _bufnr)
return require('vim.filetype.detect').printcap('term') return require('vim.filetype.detect').printcap('term')
end), end),
['%.t%.html$'] = 'tilde', ['%.t%.html$'] = 'tilde',
@ -2928,51 +2923,56 @@ function M.match(args)
name = api.nvim_buf_get_name(bufnr) name = api.nvim_buf_get_name(bufnr)
end end
--- @type string?, fun(b: integer)?
local ft, on_detect
if name then if name then
name = normalize_path(name) name = normalize_path(name)
-- First check for the simple case where the full path exists as a key
local path = abspath(name) local path = abspath(name)
ft, on_detect = dispatch(filename[path], path, bufnr) do -- First check for the simple case where the full path exists as a key
local ft, on_detect = dispatch(filename[path], path, bufnr)
if ft then if ft then
return ft, on_detect return ft, on_detect
end end
end
-- Next check against just the file name
local tail = fn.fnamemodify(name, ':t') local tail = fn.fnamemodify(name, ':t')
ft, on_detect = dispatch(filename[tail], path, bufnr)
do -- Next check against just the file name
local ft, on_detect = dispatch(filename[tail], path, bufnr)
if ft then if ft then
return ft, on_detect return ft, on_detect
end end
end
-- Next, check the file path against available patterns with non-negative priority -- Next, check the file path against available patterns with non-negative priority
-- Cache match results of all parent patterns to improve performance -- Cache match results of all parent patterns to improve performance
local parent_matches = {} local parent_matches = {}
ft, on_detect = do
local ft, on_detect =
match_pattern_sorted(name, path, tail, pattern_sorted_pos, parent_matches, bufnr) match_pattern_sorted(name, path, tail, pattern_sorted_pos, parent_matches, bufnr)
if ft then if ft then
return ft, on_detect return ft, on_detect
end end
end
-- Next, check file extension -- Next, check file extension
-- Don't use fnamemodify() with :e modifier here, -- Don't use fnamemodify() with :e modifier here,
-- as that's empty when there is only an extension. -- as that's empty when there is only an extension.
do
local ext = name:match('%.([^.]-)$') or '' local ext = name:match('%.([^.]-)$') or ''
ft, on_detect = dispatch(extension[ext], path, bufnr) local ft, on_detect = dispatch(extension[ext], path, bufnr)
if ft then if ft then
return ft, on_detect return ft, on_detect
end end
end
-- Next, check patterns with negative priority do -- Next, check patterns with negative priority
ft, on_detect = local ft, on_detect =
match_pattern_sorted(name, path, tail, pattern_sorted_neg, parent_matches, bufnr) match_pattern_sorted(name, path, tail, pattern_sorted_neg, parent_matches, bufnr)
if ft then if ft then
return ft, on_detect return ft, on_detect
end end
end end
end
-- Finally, check file contents -- Finally, check file contents
if contents or bufnr then if contents or bufnr then
@ -2992,8 +2992,7 @@ function M.match(args)
-- If name is nil, catch any errors from the contents filetype detection function. -- If name is nil, catch any errors from the contents filetype detection function.
-- If the function tries to use the filename that is nil then it will fail, -- If the function tries to use the filename that is nil then it will fail,
-- but this enables checks which do not need a filename to still work. -- but this enables checks which do not need a filename to still work.
local ok local ok, ft, on_detect = pcall(
ok, ft, on_detect = pcall(
require('vim.filetype.detect').match_contents, require('vim.filetype.detect').match_contents,
contents, contents,
name, name,

View File

@ -1013,7 +1013,7 @@ local function m4(contents)
return 'm4' return 'm4'
end end
end end
if vim.env.TERM == 'amiga' and findany(contents[1]:lower(), { '^;', '^%.bra' }) then if vim.env.TERM == 'amiga' and findany(assert(contents[1]):lower(), { '^;', '^%.bra' }) then
-- AmigaDos scripts -- AmigaDos scripts
return 'amiga' return 'amiga'
end end
@ -1429,10 +1429,10 @@ function M.rules(path)
return 'javascript' return 'javascript'
else else
local ok, config_lines = pcall(fn.readfile, '/etc/udev/udev.conf') local ok, config_lines = pcall(fn.readfile, '/etc/udev/udev.conf')
--- @cast config_lines +string[]
if not ok then if not ok then
return 'hog' return 'hog'
end end
--- @cast config_lines -string
local dir = fn.fnamemodify(path, ':h') local dir = fn.fnamemodify(path, ':h')
for _, line in ipairs(config_lines) do for _, line in ipairs(config_lines) do
local match = line:match(udev_rules_pattern) local match = line:match(udev_rules_pattern)
@ -1678,7 +1678,7 @@ end
--- @type vim.filetype.mapfn --- @type vim.filetype.mapfn
function M.tex(path, bufnr) function M.tex(path, bufnr)
local matched, _, format = getline(bufnr, 1):find('^%%&%s*(%a+)') local matched, _, format = getline(bufnr, 1):find('^%%&%s*(%a+)')
if matched then if matched and format then
--- @type string --- @type string
format = format:lower():gsub('pdf', '', 1) format = format:lower():gsub('pdf', '', 1)
elseif path:lower():find('tex/context/.*/.*%.tex') then elseif path:lower():find('tex/context/.*/.*%.tex') then
@ -1954,7 +1954,7 @@ local patterns_hashbang = {
--- @return string? --- @return string?
--- @return fun(b: integer)? --- @return fun(b: integer)?
local function match_from_hashbang(contents, path, dispatch_extension) local function match_from_hashbang(contents, path, dispatch_extension)
local first_line = contents[1] local first_line = assert(contents[1])
-- Check for a line like "#!/usr/bin/env {options} bash". Turn it into -- Check for a line like "#!/usr/bin/env {options} bash". Turn it into
-- "#!/usr/bin/bash" to make matching easier. -- "#!/usr/bin/bash" to make matching easier.
-- Recognize only a few {options} that are commonly used. -- Recognize only a few {options} that are commonly used.
@ -2012,6 +2012,13 @@ local function match_from_hashbang(contents, path, dispatch_extension)
return dispatch_extension(name) return dispatch_extension(name)
end end
--- @class vim.filetype.detect.PatternOpts
--- @field vim_regex? true? use Vim regexes instead of Lua patterns.
--- @field start_lnum? integer? Start line number for matching, defaults to 1.
--- @field end_lnum? integer? End line number for matching, defaults to -1 (last line).
--- @field ignore_case? true ignore case when matching.
-- TODO(lewis6991): split this table into two tables, one for patterns and one for functions.
local patterns_text = { local patterns_text = {
['^#compdef\\>'] = { 'zsh', { vim_regex = true } }, ['^#compdef\\>'] = { 'zsh', { vim_regex = true } },
['^#autoload\\>'] = { 'zsh', { vim_regex = true } }, ['^#autoload\\>'] = { 'zsh', { vim_regex = true } },
@ -2144,7 +2151,7 @@ local patterns_text = {
--- @return string? --- @return string?
--- @return fun(b: integer)? --- @return fun(b: integer)?
local function match_from_text(contents, path) local function match_from_text(contents, path)
if contents[1]:find('^:$') then if assert(contents[1]):find('^:$') then
-- Bourne-like shell scripts: sh ksh bash bash2 -- Bourne-like shell scripts: sh ksh bash bash2
return sh(path, contents) return sh(path, contents)
elseif elseif
@ -2160,7 +2167,7 @@ local function match_from_text(contents, path)
for k, v in pairs(patterns_text) do for k, v in pairs(patterns_text) do
if type(v) == 'string' then if type(v) == 'string' then
-- Check the first line only -- Check the first line only
if contents[1]:find(k) then if assert(contents[1]):find(k) then
return v return v
end end
elseif type(v) == 'function' then elseif type(v) == 'function' then
@ -2172,22 +2179,25 @@ local function match_from_text(contents, path)
else else
--- @cast k string --- @cast k string
local opts = type(v) == 'table' and v[2] or {} local opts = type(v) == 'table' and v[2] or {}
--- @cast opts vim.filetype.detect.PatternOpts
if opts.start_lnum and opts.end_lnum then if opts.start_lnum and opts.end_lnum then
assert( assert(
not opts.ignore_case, not opts.ignore_case,
'ignore_case=true is ignored when start_lnum is also present, needs refactor' 'ignore_case=true is ignored when start_lnum is also present, needs refactor'
) )
for i = opts.start_lnum, opts.end_lnum do for i = opts.start_lnum, opts.end_lnum do
if not contents[i] then local line = contents[i]
if not line then
break break
elseif contents[i]:find(k) then elseif line:find(k) then
return v[1] return v[1]
end end
end end
else else
local line_nr = opts.start_lnum == -1 and #contents or opts.start_lnum or 1 local line_nr = opts.start_lnum == -1 and #contents or opts.start_lnum or 1
if contents[line_nr] then local contents_line_nr = contents[line_nr]
local line = opts.ignore_case and contents[line_nr]:lower() or contents[line_nr] if contents_line_nr then
local line = opts.ignore_case and contents_line_nr:lower() or contents_line_nr
if opts.vim_regex and matchregex(line, k) or line:find(k) then if opts.vim_regex and matchregex(line, k) or line:find(k) then
return v[1] return v[1]
end end
@ -2204,7 +2214,7 @@ end
--- @return string? --- @return string?
--- @return fun(b: integer)? --- @return fun(b: integer)?
function M.match_contents(contents, path, dispatch_extension) function M.match_contents(contents, path, dispatch_extension)
local first_line = contents[1] local first_line = assert(contents[1])
if first_line:find('^#!') then if first_line:find('^#!') then
return match_from_hashbang(contents, path, dispatch_extension) return match_from_hashbang(contents, path, dispatch_extension)
else else

View File

@ -70,7 +70,7 @@ local function update_ft_option_cache(filetype)
end end
end end
--- @private --- @nodoc
--- @param filetype string Filetype --- @param filetype string Filetype
--- @param option string Option name --- @param option string Option name
--- @return string|integer|boolean --- @return string|integer|boolean

View File

@ -41,8 +41,8 @@ M.priorities = {
---@param bufnr integer Buffer number to apply highlighting to ---@param bufnr integer Buffer number to apply highlighting to
---@param ns integer Namespace to add highlight to ---@param ns integer Namespace to add highlight to
---@param higroup string Highlight group to use for highlighting ---@param higroup string Highlight group to use for highlighting
---@param start integer[]|string Start of region as a (line, column) tuple or string accepted by |getpos()| ---@param start [integer,integer]|string Start of region as a (line, column) tuple or string accepted by |getpos()|
---@param finish integer[]|string End of region as a (line, column) tuple or string accepted by |getpos()| ---@param finish [integer,integer]|string End of region as a (line, column) tuple or string accepted by |getpos()|
---@param opts? vim.hl.range.Opts ---@param opts? vim.hl.range.Opts
--- @return uv.uv_timer_t? range_timer A timer which manages how much time the --- @return uv.uv_timer_t? range_timer A timer which manages how much time the
--- highlight has left --- highlight has left
@ -98,14 +98,16 @@ function M.range(bufnr, ns, higroup, start, finish, opts)
}) })
-- For non-blockwise selection, use a single extmark. -- For non-blockwise selection, use a single extmark.
if regtype == 'v' or regtype == 'V' then if regtype == 'v' or regtype == 'V' then
region = { { region[1][1], region[#region][2] } } --- @type [ [integer, integer, integer, integer], [integer, integer, integer, integer]][]
region = { { assert(region[1])[1], assert(region[#region])[2] } }
local region1 = assert(region[1])
if if
regtype == 'V' regtype == 'V'
or region[1][2][2] == pos1[2] and pos1[3] == v_maxcol or region1[2][2] == pos1[2] and pos1[3] == v_maxcol
or region[1][2][2] == pos2[2] and pos2[3] == v_maxcol or region1[2][2] == pos2[2] and pos2[3] == v_maxcol
then then
region[1][2][2] = region[1][2][2] + 1 region1[2][2] = region1[2][2] + 1
region[1][2][3] = 0 region1[2][3] = 0
end end
end end

View File

@ -66,7 +66,7 @@ local indexed = {}
--- @return uv.fs_stat.result? --- @return uv.fs_stat.result?
local function fs_stat_cached(path) local function fs_stat_cached(path)
if not fs_stat_cache then if not fs_stat_cache then
return uv.fs_stat(path) return (uv.fs_stat(path))
end end
if not fs_stat_cache[path] then if not fs_stat_cache[path] then

View File

@ -41,7 +41,6 @@ lsp._resolve_to_request = {
-- TODO improve handling of scratch buffers with LSP attached. -- TODO improve handling of scratch buffers with LSP attached.
---@private
--- Called by the client when trying to call a method that's not --- Called by the client when trying to call a method that's not
--- supported in any of the servers registered for the current buffer. --- supported in any of the servers registered for the current buffer.
---@param method (vim.lsp.protocol.Method.ClientToServer) name of the method ---@param method (vim.lsp.protocol.Method.ClientToServer) name of the method
@ -54,7 +53,6 @@ function lsp._unsupported_method(method)
return msg return msg
end end
---@private
---@param workspace_folders string|lsp.WorkspaceFolder[]? ---@param workspace_folders string|lsp.WorkspaceFolder[]?
---@return lsp.WorkspaceFolder[]? ---@return lsp.WorkspaceFolder[]?
function lsp._get_workspace_folders(workspace_folders) function lsp._get_workspace_folders(workspace_folders)
@ -78,8 +76,7 @@ local format_line_ending = {
['mac'] = '\r', ['mac'] = '\r',
} }
---@private ---@param bufnr integer
---@param bufnr (number)
---@return string ---@return string
function lsp._buf_get_line_ending(bufnr) function lsp._buf_get_line_ending(bufnr)
return format_line_ending[vim.bo[bufnr].fileformat] or '\n' return format_line_ending[vim.bo[bufnr].fileformat] or '\n'
@ -110,10 +107,9 @@ lsp.client_errors = vim.tbl_extend(
client_error('ON_EXIT_CALLBACK_ERROR') client_error('ON_EXIT_CALLBACK_ERROR')
) )
---@private
--- Returns full text of buffer {bufnr} as a string. --- Returns full text of buffer {bufnr} as a string.
--- ---
---@param bufnr (number) Buffer handle, or 0 for current. ---@param bufnr integer Buffer handle, or 0 for current.
---@return string # Buffer text as string. ---@return string # Buffer text as string.
function lsp._buf_get_full_text(bufnr) function lsp._buf_get_full_text(bufnr)
local line_ending = lsp._buf_get_line_ending(bufnr) local line_ending = lsp._buf_get_line_ending(bufnr)
@ -284,7 +280,7 @@ end
--- ---
--- Predicate which decides if a client should be re-used. Used on all running clients. The default --- Predicate which decides if a client should be re-used. Used on all running clients. The default
--- implementation re-uses a client if name and root_dir matches. --- implementation re-uses a client if name and root_dir matches.
--- @field reuse_client? fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean --- @field reuse_client? fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean #
--- ---
--- [lsp-root_dir()]() --- [lsp-root_dir()]()
--- Decides the workspace root: the directory where the LSP server will base its workspaceFolders, --- Decides the workspace root: the directory where the LSP server will base its workspaceFolders,
@ -832,7 +828,6 @@ local function is_empty_or_default(bufnr, option)
return vim.startswith(scriptinfo[1].name, vim.fn.expand('$VIMRUNTIME')) return vim.startswith(scriptinfo[1].name, vim.fn.expand('$VIMRUNTIME'))
end end
---@private
---@param client vim.lsp.Client ---@param client vim.lsp.Client
---@param bufnr integer ---@param bufnr integer
function lsp._set_defaults(client, bufnr) function lsp._set_defaults(client, bufnr)
@ -1101,8 +1096,8 @@ end
--- Checks if a buffer is attached for a particular client. --- Checks if a buffer is attached for a particular client.
--- ---
---@param bufnr (integer) Buffer handle, or 0 for current ---@param bufnr integer Buffer handle, or 0 for current
---@param client_id (integer) the client id ---@param client_id integer the client id
function lsp.buf_is_attached(bufnr, client_id) function lsp.buf_is_attached(bufnr, client_id)
return lsp.get_clients({ bufnr = bufnr, id = client_id, _uninitialized = true })[1] ~= nil return lsp.get_clients({ bufnr = bufnr, id = client_id, _uninitialized = true })[1] ~= nil
end end
@ -1112,7 +1107,7 @@ end
--- ---
---@param client_id integer client id ---@param client_id integer client id
--- ---
---@return (nil|vim.lsp.Client) client rpc object ---@return vim.lsp.Client? client rpc object
function lsp.get_client_by_id(client_id) function lsp.get_client_by_id(client_id)
return all_clients[client_id] return all_clients[client_id]
end end
@ -1207,7 +1202,6 @@ function lsp.get_clients(filter)
return clients return clients
end end
---@private
---@deprecated ---@deprecated
function lsp.get_active_clients(filter) function lsp.get_active_clients(filter)
vim.deprecate('vim.lsp.get_active_clients()', 'vim.lsp.get_clients()', '0.12') vim.deprecate('vim.lsp.get_active_clients()', 'vim.lsp.get_clients()', '0.12')
@ -1263,7 +1257,7 @@ api.nvim_create_autocmd('VimLeavePre', {
end, end,
}) })
---@private ---@nodoc
--- Sends an async request for all active clients attached to the --- Sends an async request for all active clients attached to the
--- buffer. --- buffer.
--- ---
@ -1401,9 +1395,9 @@ end
--- ---
---@since 7 ---@since 7
--- ---
---@param bufnr (integer|nil) The number of the buffer ---@param bufnr integer? The number of the buffer
---@param method (vim.lsp.protocol.Method.ClientToServer.Notification) Name of the request method ---@param method vim.lsp.protocol.Method.ClientToServer.Notification Name of the request method
---@param params (any) Arguments to send to the server ---@param params any Arguments to send to the server
--- ---
---@return boolean success true if any client returns true; false otherwise ---@return boolean success true if any client returns true; false otherwise
function lsp.buf_notify(bufnr, method, params) function lsp.buf_notify(bufnr, method, params)
@ -1573,7 +1567,7 @@ end
---@deprecated Use |vim.lsp.get_client_by_id()| instead. ---@deprecated Use |vim.lsp.get_client_by_id()| instead.
---Checks whether a client is stopped. ---Checks whether a client is stopped.
--- ---
---@param client_id (integer) ---@param client_id integer
---@return boolean stopped true if client is stopped, false otherwise. ---@return boolean stopped true if client is stopped, false otherwise.
function lsp.client_is_stopped(client_id) function lsp.client_is_stopped(client_id)
vim.deprecate('vim.lsp.client_is_stopped()', 'vim.lsp.get_client_by_id()', '0.14') vim.deprecate('vim.lsp.client_is_stopped()', 'vim.lsp.get_client_by_id()', '0.14')
@ -1584,7 +1578,7 @@ end
--- Gets a map of client_id:client pairs for the given buffer, where each value --- Gets a map of client_id:client pairs for the given buffer, where each value
--- is a |vim.lsp.Client| object. --- is a |vim.lsp.Client| object.
--- ---
---@param bufnr (integer|nil): Buffer handle, or 0 for current ---@param bufnr integer? Buffer handle, or 0 for current
---@return table result is table of (client_id, client) pairs ---@return table result is table of (client_id, client) pairs
---@deprecated Use |vim.lsp.get_clients()| instead. ---@deprecated Use |vim.lsp.get_clients()| instead.
function lsp.buf_get_clients(bufnr) function lsp.buf_get_clients(bufnr)
@ -1630,7 +1624,7 @@ function lsp.get_log_path()
return log.get_filename() return log.get_filename()
end end
---@private ---@nodoc
--- Invokes a function for each LSP client attached to a buffer. --- Invokes a function for each LSP client attached to a buffer.
--- ---
---@param bufnr integer Buffer number ---@param bufnr integer Buffer number

View File

@ -6,7 +6,7 @@ local ms = lsp.protocol.Methods
---@param name string ---@param name string
---@param range lsp.Range ---@param range lsp.Range
---@param uri string ---@param uri string
---@param position_encoding string ---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
---@return {name: string, filename: string, cmd: string, kind?: string} ---@return {name: string, filename: string, cmd: string, kind?: string}
local function mk_tag_item(name, range, uri, position_encoding) local function mk_tag_item(name, range, uri, position_encoding)
local bufnr = vim.uri_to_bufnr(uri) local bufnr = vim.uri_to_bufnr(uri)
@ -32,7 +32,7 @@ local function query_definition(pattern)
--- @param range lsp.Range --- @param range lsp.Range
--- @param uri string --- @param uri string
--- @param position_encoding string ---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
local add = function(range, uri, position_encoding) local add = function(range, uri, position_encoding)
table.insert(results, mk_tag_item(pattern, range, uri, position_encoding)) table.insert(results, mk_tag_item(pattern, range, uri, position_encoding))
end end

View File

@ -545,7 +545,7 @@ function M.format(opts)
end end
local passed_multiple_ranges = (range and #range ~= 0 and type(range[1]) == 'table') local passed_multiple_ranges = (range and #range ~= 0 and type(range[1]) == 'table')
local method ---@type string local method ---@type vim.lsp.protocol.Method.ClientToServer
if passed_multiple_ranges then if passed_multiple_ranges then
method = ms.textDocument_rangesFormatting method = ms.textDocument_rangesFormatting
elseif range then elseif range then
@ -579,10 +579,11 @@ function M.format(opts)
local ret = params --[[@as lsp.DocumentFormattingParams|lsp.DocumentRangeFormattingParams|lsp.DocumentRangesFormattingParams]] local ret = params --[[@as lsp.DocumentFormattingParams|lsp.DocumentRangeFormattingParams|lsp.DocumentRangesFormattingParams]]
if passed_multiple_ranges then if passed_multiple_ranges then
--- @cast range {start:[integer,integer],end:[integer, integer]}[]
ret = params --[[@as lsp.DocumentRangesFormattingParams]] ret = params --[[@as lsp.DocumentRangesFormattingParams]]
--- @cast range {start:[integer,integer],end:[integer, integer]}
ret.ranges = vim.tbl_map(to_lsp_range, range) ret.ranges = vim.tbl_map(to_lsp_range, range)
elseif range then elseif range then
--- @cast range {start:[integer,integer],end:[integer, integer]}
ret = params --[[@as lsp.DocumentRangeFormattingParams]] ret = params --[[@as lsp.DocumentRangeFormattingParams]]
ret.range = to_lsp_range(range) ret.range = to_lsp_range(range)
end end
@ -660,7 +661,7 @@ function M.rename(new_name, opts)
local cword = vim.fn.expand('<cword>') local cword = vim.fn.expand('<cword>')
--- @param range lsp.Range --- @param range lsp.Range
--- @param position_encoding string --- @param position_encoding 'utf-8'|'utf-16'|'utf-32'
local function get_text_at_range(range, position_encoding) local function get_text_at_range(range, position_encoding)
return api.nvim_buf_get_text( return api.nvim_buf_get_text(
bufnr, bufnr,
@ -1199,7 +1200,7 @@ local function on_code_action_results(results, opts)
return title return title
end end
local source = lsp.get_client_by_id(item.ctx.client_id).name local source = assert(lsp.get_client_by_id(item.ctx.client_id)).name
return ('%s [%s]'):format(title, source) return ('%s [%s]'):format(title, source)
end end

View File

@ -176,7 +176,7 @@ local validate = vim.validate
--- @field name string --- @field name string
--- ---
--- See [vim.lsp.ClientConfig]. --- See [vim.lsp.ClientConfig].
--- @field offset_encoding string --- @field offset_encoding 'utf-8'|'utf-16'|'utf-32'
--- ---
--- A ring buffer (|vim.ringbuf()|) containing progress messages --- A ring buffer (|vim.ringbuf()|) containing progress messages
--- sent by the server. --- sent by the server.
@ -440,16 +440,16 @@ function Client.create(config)
--- @type vim.lsp.rpc.Dispatchers --- @type vim.lsp.rpc.Dispatchers
local dispatchers = { local dispatchers = {
notification = function(...) notification = function(...)
return self:_notification(...) self:_notification(...)
end, end,
server_request = function(...) server_request = function(...)
return self:_server_request(...) return self:_server_request(...)
end, end,
on_error = function(...) on_error = function(...)
return self:_on_error(...) self:_on_error(...)
end, end,
on_exit = function(...) on_exit = function(...)
return self:_on_exit(...) self:_on_exit(...)
end, end,
} }
@ -597,7 +597,7 @@ end
--- @private --- @private
--- @param id integer --- @param id integer
--- @param req_type 'pending'|'complete'|'cancel'| --- @param req_type 'pending'|'complete'|'cancel'
--- @param bufnr? integer (only required for req_type='pending') --- @param bufnr? integer (only required for req_type='pending')
--- @param method? string (only required for req_type='pending') --- @param method? string (only required for req_type='pending')
function Client:_process_request(id, req_type, bufnr, method) function Client:_process_request(id, req_type, bufnr, method)

View File

@ -258,20 +258,22 @@ end
---@param result lsp.CodeLens[] ---@param result lsp.CodeLens[]
---@param ctx lsp.HandlerContext ---@param ctx lsp.HandlerContext
function M.on_codelens(err, result, ctx) function M.on_codelens(err, result, ctx)
local bufnr = assert(ctx.bufnr)
if err then if err then
active_refreshes[assert(ctx.bufnr)] = nil active_refreshes[bufnr] = nil
log.error('codelens', err) log.error('codelens', err)
return return
end end
M.save(result, ctx.bufnr, ctx.client_id) M.save(result, bufnr, ctx.client_id)
-- Eager display for any resolved (and unresolved) lenses and refresh them -- Eager display for any resolved (and unresolved) lenses and refresh them
-- once resolved. -- once resolved.
M.display(result, ctx.bufnr, ctx.client_id) M.display(result, bufnr, ctx.client_id)
resolve_lenses(result, ctx.bufnr, ctx.client_id, function() resolve_lenses(result, bufnr, ctx.client_id, function()
active_refreshes[assert(ctx.bufnr)] = nil active_refreshes[bufnr] = nil
M.display(result, ctx.bufnr, ctx.client_id) M.display(result, bufnr, ctx.client_id)
end) end)
end end

View File

@ -38,7 +38,7 @@ local lsp = vim.lsp
local protocol = lsp.protocol local protocol = lsp.protocol
local ms = protocol.Methods local ms = protocol.Methods
local rtt_ms = 50 local rtt_ms = 50.0
local ns_to_ms = 0.000001 local ns_to_ms = 0.000001
--- @alias vim.lsp.CompletionResult lsp.CompletionList | lsp.CompletionItem[] --- @alias vim.lsp.CompletionResult lsp.CompletionList | lsp.CompletionItem[]
@ -92,7 +92,7 @@ local completion_timer = nil
--- @return uv.uv_timer_t --- @return uv.uv_timer_t
local function new_timer() local function new_timer()
return assert(vim.uv.new_timer()) return (assert(vim.uv.new_timer()))
end end
local function reset_timer() local function reset_timer()
@ -110,7 +110,7 @@ end
local function exp_avg(window, warmup) local function exp_avg(window, warmup)
local count = 0 local count = 0
local sum = 0 local sum = 0
local value = 0 local value = 0.0
return function(sample) return function(sample)
if count < warmup then if count < warmup then
@ -278,7 +278,6 @@ end
--- Turns the result of a `textDocument/completion` request into vim-compatible --- Turns the result of a `textDocument/completion` request into vim-compatible
--- |complete-items|. --- |complete-items|.
--- ---
--- @private
--- @param result vim.lsp.CompletionResult Result of `textDocument/completion` --- @param result vim.lsp.CompletionResult Result of `textDocument/completion`
--- @param prefix string prefix to filter the completion items --- @param prefix string prefix to filter the completion items
--- @param client_id integer? Client ID --- @param client_id integer? Client ID
@ -365,7 +364,7 @@ end
--- @param lnum integer 0-indexed --- @param lnum integer 0-indexed
--- @param line string --- @param line string
--- @param items lsp.CompletionItem[] --- @param items lsp.CompletionItem[]
--- @param encoding string --- @param encoding 'utf-8'|'utf-16'|'utf-32'
--- @return integer? --- @return integer?
local function adjust_start_col(lnum, line, items, encoding) local function adjust_start_col(lnum, line, items, encoding)
local min_start_char = nil local min_start_char = nil
@ -384,7 +383,6 @@ local function adjust_start_col(lnum, line, items, encoding)
end end
end end
--- @private
--- @param line string line content --- @param line string line content
--- @param lnum integer 0-indexed line number --- @param lnum integer 0-indexed line number
--- @param cursor_col integer --- @param cursor_col integer
@ -392,7 +390,7 @@ end
--- @param client_start_boundary integer 0-indexed word boundary --- @param client_start_boundary integer 0-indexed word boundary
--- @param server_start_boundary? integer 0-indexed word boundary, based on textEdit.range.start.character --- @param server_start_boundary? integer 0-indexed word boundary, based on textEdit.range.start.character
--- @param result vim.lsp.CompletionResult --- @param result vim.lsp.CompletionResult
--- @param encoding string --- @param encoding 'utf-8'|'utf-16'|'utf-32'
--- @return table[] matches --- @return table[] matches
--- @return integer? server_start_boundary --- @return integer? server_start_boundary
function M._convert_results( function M._convert_results(
@ -487,7 +485,7 @@ local function trigger(bufnr, clients, ctx)
local line = api.nvim_get_current_line() local line = api.nvim_get_current_line()
local line_to_cursor = line:sub(1, cursor_col) local line_to_cursor = line:sub(1, cursor_col)
local word_boundary = vim.fn.match(line_to_cursor, '\\k*$') local word_boundary = vim.fn.match(line_to_cursor, '\\k*$')
local start_time = vim.uv.hrtime() local start_time = vim.uv.hrtime() --[[@as integer]]
Context.last_request_time = start_time Context.last_request_time = start_time
local cancel_request = request(clients, bufnr, win, ctx, function(responses) local cancel_request = request(clients, bufnr, win, ctx, function(responses)
@ -557,7 +555,7 @@ local function on_insert_char_pre(handle)
else else
completion_timer = new_timer() completion_timer = new_timer()
completion_timer:start( completion_timer:start(
debounce_ms, math.floor(debounce_ms),
0, 0,
vim.schedule_wrap(function() vim.schedule_wrap(function()
M.get({ ctx = ctx }) M.get({ ctx = ctx })

View File

@ -11,25 +11,28 @@ local augroup = api.nvim_create_augroup('nvim.lsp.diagnostic', {})
---@class (private) vim.lsp.diagnostic.BufState ---@class (private) vim.lsp.diagnostic.BufState
---@field enabled boolean Whether diagnostics are enabled for this buffer ---@field enabled boolean Whether diagnostics are enabled for this buffer
---@field client_result_id table<integer, string?> Latest responded `resultId` ---@field client_result_id table<integer, string?> Latest responded `resultId`
---@type table<integer, vim.lsp.diagnostic.BufState?>
---@type table<integer,vim.lsp.diagnostic.BufState>
local bufstates = {} local bufstates = {}
local DEFAULT_CLIENT_ID = -1 local DEFAULT_CLIENT_ID = -1
---@param severity lsp.DiagnosticSeverity ---@param severity lsp.DiagnosticSeverity
---@return vim.diagnostic.Severity
local function severity_lsp_to_vim(severity) local function severity_lsp_to_vim(severity)
if type(severity) == 'string' then if type(severity) == 'string' then
severity = protocol.DiagnosticSeverity[severity] --- @type integer return protocol.DiagnosticSeverity[severity] --[[@as vim.diagnostic.Severity]]
end end
return severity return severity
end end
---@param severity vim.diagnostic.Severity|vim.diagnostic.SeverityName
---@return lsp.DiagnosticSeverity ---@return lsp.DiagnosticSeverity
local function severity_vim_to_lsp(severity) local function severity_vim_to_lsp(severity)
if type(severity) == 'string' then if type(severity) == 'string' then
severity = vim.diagnostic.severity[severity] --- @type integer return vim.diagnostic.severity[severity]
end end
return severity return severity --[[@as lsp.DiagnosticSeverity]]
end end
---@param bufnr integer ---@param bufnr integer
@ -186,10 +189,9 @@ function M.get_namespace(client_id, is_pull)
local client = vim.lsp.get_client_by_id(client_id) local client = vim.lsp.get_client_by_id(client_id)
if is_pull then if is_pull then
local server_id = local server_id =
vim.tbl_get((client or {}).server_capabilities, 'diagnosticProvider', 'identifier') vim.tbl_get((client or {}).server_capabilities or {}, 'diagnosticProvider', 'identifier')
local key = string.format('%d:%s', client_id, server_id or 'nil') local key = ('%d:%s'):format(client_id, server_id or 'nil')
local name = string.format( local name = ('nvim.lsp.%s.%d.%s'):format(
'nvim.lsp.%s.%d.%s',
client and client.name or 'unknown', client and client.name or 'unknown',
client_id, client_id,
server_id or 'nil' server_id or 'nil'
@ -200,15 +202,15 @@ function M.get_namespace(client_id, is_pull)
_client_pull_namespaces[key] = ns _client_pull_namespaces[key] = ns
end end
return ns return ns
else end
local name = string.format('nvim.lsp.%s.%d', client and client.name or 'unknown', client_id)
local ns = _client_push_namespaces[client_id] local ns = _client_push_namespaces[client_id]
if not ns then if not ns then
local name = ('nvim.lsp.%s.%d'):format(client and client.name or 'unknown', client_id)
ns = api.nvim_create_namespace(name) ns = api.nvim_create_namespace(name)
_client_push_namespaces[client_id] = ns _client_push_namespaces[client_id] = ns
end end
return ns return ns
end
end end
--- @param uri string --- @param uri string
@ -227,9 +229,7 @@ local function handle_diagnostics(uri, client_id, diagnostics, is_pull)
return return
end end
if client_id == nil then client_id = client_id or DEFAULT_CLIENT_ID
client_id = DEFAULT_CLIENT_ID
end
local namespace = M.get_namespace(client_id, is_pull) local namespace = M.get_namespace(client_id, is_pull)
@ -380,7 +380,6 @@ end
--- Enable pull diagnostics for a buffer --- Enable pull diagnostics for a buffer
---@param bufnr (integer) Buffer handle, or 0 for current ---@param bufnr (integer) Buffer handle, or 0 for current
---@private
function M._enable(bufnr) function M._enable(bufnr)
bufnr = vim._resolve_bufnr(bufnr) bufnr = vim._resolve_bufnr(bufnr)

View File

@ -40,7 +40,13 @@ local document_color_opts = { style = 'background' }
--- @param color string --- @param color string
local function get_contrast_color(color) local function get_contrast_color(color)
local r_s, g_s, b_s = color:match('^#(%x%x)(%x%x)(%x%x)$') local r_s, g_s, b_s = color:match('^#(%x%x)(%x%x)(%x%x)$')
if not (r_s and g_s and b_s) then
error('Invalid color format: ' .. color)
end
local r, g, b = tonumber(r_s, 16), tonumber(g_s, 16), tonumber(b_s, 16) local r, g, b = tonumber(r_s, 16), tonumber(g_s, 16), tonumber(b_s, 16)
if not (r and g and b) then
error('Invalid color format: ' .. color)
end
-- Source: https://www.w3.org/TR/WCAG21/#dfn-relative-luminance -- Source: https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
-- Using power 2.2 is a close approximation to full piecewise transform -- Using power 2.2 is a close approximation to full piecewise transform
@ -185,7 +191,7 @@ local function buf_enable(bufnr)
api.nvim_buf_attach(bufnr, false, { api.nvim_buf_attach(bufnr, false, {
on_reload = function(_, buf) on_reload = function(_, buf)
buf_clear(buf) buf_clear(buf)
if bufstates[buf].enabled then if assert(bufstates[buf]).enabled then
M._buf_refresh(buf) M._buf_refresh(buf)
end end
end, end,
@ -203,7 +209,7 @@ local function buf_enable(bufnr)
if if
(method == ms.textDocument_didChange or method == ms.textDocument_didOpen) (method == ms.textDocument_didChange or method == ms.textDocument_didOpen)
and bufstates[args.buf].enabled and assert(bufstates[args.buf]).enabled
then then
M._buf_refresh(args.buf, args.data.client_id) M._buf_refresh(args.buf, args.data.client_id)
end end
@ -254,7 +260,7 @@ function M.is_enabled(bufnr)
reset_bufstate(bufnr, false) reset_bufstate(bufnr, false)
end end
return bufstates[bufnr].enabled return assert(bufstates[bufnr]).enabled
end end
--- Enables document highlighting from the given language client in the given buffer. --- Enables document highlighting from the given language client in the given buffer.

View File

@ -241,7 +241,7 @@ end
--- ---
--- The returned function has an optional {config} parameter that accepts |vim.lsp.ListOpts| --- The returned function has an optional {config} parameter that accepts |vim.lsp.ListOpts|
--- ---
---@param map_result fun(resp, bufnr: integer, position_encoding: 'utf-8'|'utf-16'|'utf-32'): table to convert the response ---@param map_result fun(resp: any, bufnr: integer, position_encoding: 'utf-8'|'utf-16'|'utf-32'): table to convert the response
---@param entity string name of the resource used in a `not found` error message ---@param entity string name of the resource used in a `not found` error message
---@param title_fn fun(ctx: lsp.HandlerContext): string Function to call to generate list title ---@param title_fn fun(ctx: lsp.HandlerContext): string Function to call to generate list title
---@return lsp.Handler ---@return lsp.Handler

View File

@ -15,6 +15,7 @@ local globalstate = {
---@field version? integer ---@field version? integer
---@field client_hints? table<integer, table<integer, lsp.InlayHint[]>> client_id -> (lnum -> hints) ---@field client_hints? table<integer, table<integer, lsp.InlayHint[]>> client_id -> (lnum -> hints)
---@field applied table<integer, integer> Last version of hints applied to this line ---@field applied table<integer, integer> Last version of hints applied to this line
---@type table<integer, vim.lsp.inlay_hint.bufstate> ---@type table<integer, vim.lsp.inlay_hint.bufstate>
local bufstates = vim.defaulttable(function(_) local bufstates = vim.defaulttable(function(_)
return setmetatable({ applied = {} }, { return setmetatable({ applied = {} }, {

View File

@ -36,6 +36,7 @@ end
local M = {} local M = {}
--- Mapping of error codes used by the client --- Mapping of error codes used by the client
--- @enum vim.lsp.rpc.ClientErrors
local client_errors = { local client_errors = {
INVALID_SERVER_MESSAGE = 1, INVALID_SERVER_MESSAGE = 1,
INVALID_SERVER_JSON = 2, INVALID_SERVER_JSON = 2,
@ -150,6 +151,7 @@ local default_dispatchers = {
local strbuffer = require('vim._stringbuffer') local strbuffer = require('vim._stringbuffer')
--- @async
local function request_parser_loop() local function request_parser_loop()
local buf = strbuffer.new() local buf = strbuffer.new()
while true do while true do
@ -279,7 +281,7 @@ function Client:request(method, params, callback, notify_reply_callback)
end end
---@package ---@package
---@param errkind integer ---@param errkind vim.lsp.rpc.ClientErrors
---@param ... any ---@param ... any
function Client:on_error(errkind, ...) function Client:on_error(errkind, ...)
assert(M.client_errors[errkind]) assert(M.client_errors[errkind])
@ -375,7 +377,7 @@ function Client:handle_body(body)
-- This works because we are expecting vim.NIL here -- This works because we are expecting vim.NIL here
elseif decoded.id and (decoded.result ~= vim.NIL or decoded.error ~= vim.NIL) then elseif decoded.id and (decoded.result ~= vim.NIL or decoded.error ~= vim.NIL) then
-- We sent a number, so we expect a number. -- We sent a number, so we expect a number.
local result_id = assert(tonumber(decoded.id), 'response id must be a number') local result_id = assert(tonumber(decoded.id), 'response id must be a number') --[[@as integer]]
-- Notify the user that a response was received for the request -- Notify the user that a response was received for the request
local notify_reply_callback = self.notify_reply_callbacks[result_id] local notify_reply_callback = self.notify_reply_callbacks[result_id]

View File

@ -90,6 +90,7 @@ end
--- Converts a raw token list to a list of highlight ranges used by the on_win callback --- Converts a raw token list to a list of highlight ranges used by the on_win callback
--- ---
---@async
---@param data integer[] ---@param data integer[]
---@param bufnr integer ---@param bufnr integer
---@param client vim.lsp.Client ---@param client vim.lsp.Client
@ -326,6 +327,7 @@ end
--- Finally, a redraw command is issued to force nvim to redraw the screen to --- Finally, a redraw command is issued to force nvim to redraw the screen to
--- pick up changed highlight tokens. --- pick up changed highlight tokens.
--- ---
---@async
---@param response lsp.SemanticTokens|lsp.SemanticTokensDelta ---@param response lsp.SemanticTokens|lsp.SemanticTokensDelta
---@private ---@private
function STHighlighter:process_response(response, client, version) function STHighlighter:process_response(response, client, version)
@ -491,7 +493,7 @@ function STHighlighter:on_win(topline, botline)
local is_folded, foldend local is_folded, foldend
for i = first, last do for i = first, last do
local token = highlights[i] local token = assert(highlights[i])
is_folded, foldend = check_fold(token.line + 1, foldend) is_folded, foldend = check_fold(token.line + 1, foldend)

View File

@ -52,10 +52,11 @@ local str_utf_end = vim.str_utf_end
-- utf-8 index and either the utf-16, or utf-32 index. -- utf-8 index and either the utf-16, or utf-32 index.
---@param line string the line to index into ---@param line string the line to index into
---@param byte integer the byte idx ---@param byte integer the byte idx
---@param position_encoding string utf-8|utf-16|utf-32|nil (default: utf-8) ---@param position_encoding 'utf-8'|'utf-16'|'utf-32'? (default: utf-8)
---@return integer byte_idx of first change position ---@return integer byte_idx of first change position
---@return integer char_idx of first change position ---@return integer char_idx of first change position
local function align_end_position(line, byte, position_encoding) local function align_end_position(line, byte, position_encoding)
position_encoding = position_encoding or 'utf-8'
local char --- @type integer local char --- @type integer
-- If on the first byte, or an empty string: the trivial case -- If on the first byte, or an empty string: the trivial case
if byte == 1 or #line == 0 then if byte == 1 or #line == 0 then
@ -93,7 +94,7 @@ end
---@param firstline integer firstline from on_lines, adjusted to 1-index ---@param firstline integer firstline from on_lines, adjusted to 1-index
---@param lastline integer lastline from on_lines, adjusted to 1-index ---@param lastline integer lastline from on_lines, adjusted to 1-index
---@param new_lastline integer new_lastline from on_lines, adjusted to 1-index ---@param new_lastline integer new_lastline from on_lines, adjusted to 1-index
---@param position_encoding string utf-8|utf-16|utf-32|nil (fallback to utf-8) ---@param position_encoding 'utf-8'|'utf-16'|'utf-32'? (default: utf-8)
---@return vim.lsp.sync.Range result table include line_idx, byte_idx, and char_idx of first change position ---@return vim.lsp.sync.Range result table include line_idx, byte_idx, and char_idx of first change position
local function compute_start_range( local function compute_start_range(
prev_lines, prev_lines,
@ -103,6 +104,8 @@ local function compute_start_range(
new_lastline, new_lastline,
position_encoding position_encoding
) )
position_encoding = position_encoding or 'utf-8'
local char_idx --- @type integer? local char_idx --- @type integer?
local byte_idx --- @type integer? local byte_idx --- @type integer?
-- If firstline == lastline, no existing text is changed. All edit operations -- If firstline == lastline, no existing text is changed. All edit operations
@ -130,8 +133,8 @@ local function compute_start_range(
return { line_idx = firstline, byte_idx = 1, char_idx = 1 } return { line_idx = firstline, byte_idx = 1, char_idx = 1 }
end end
local prev_line = prev_lines[firstline] local prev_line = assert(prev_lines[firstline])
local curr_line = curr_lines[firstline] local curr_line = assert(curr_lines[firstline])
-- Iterate across previous and current line containing first change -- Iterate across previous and current line containing first change
-- to find the first different byte. -- to find the first different byte.
@ -174,7 +177,7 @@ end
---@param firstline integer ---@param firstline integer
---@param lastline integer ---@param lastline integer
---@param new_lastline integer ---@param new_lastline integer
---@param position_encoding string ---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
---@return vim.lsp.sync.Range prev_end_range ---@return vim.lsp.sync.Range prev_end_range
---@return vim.lsp.sync.Range curr_end_range ---@return vim.lsp.sync.Range curr_end_range
local function compute_end_range( local function compute_end_range(
@ -189,7 +192,7 @@ local function compute_end_range(
-- A special case for the following `firstline == new_lastline` case where lines are deleted. -- A special case for the following `firstline == new_lastline` case where lines are deleted.
-- Even if the buffer has become empty, nvim behaves as if it has an empty line with eol. -- Even if the buffer has become empty, nvim behaves as if it has an empty line with eol.
if #curr_lines == 1 and curr_lines[1] == '' then if #curr_lines == 1 and curr_lines[1] == '' then
local prev_line = prev_lines[lastline - 1] local prev_line = assert(prev_lines[lastline - 1])
return { return {
line_idx = lastline - 1, line_idx = lastline - 1,
byte_idx = #prev_line + 1, byte_idx = #prev_line + 1,
@ -219,8 +222,8 @@ local function compute_end_range(
local prev_line_idx = lastline - 1 local prev_line_idx = lastline - 1
local curr_line_idx = new_lastline - 1 local curr_line_idx = new_lastline - 1
local prev_line = prev_lines[lastline - 1] local prev_line = assert(prev_lines[lastline - 1])
local curr_line = curr_lines[new_lastline - 1] local curr_line = assert(curr_lines[new_lastline - 1])
local prev_line_length = #prev_line local prev_line_length = #prev_line
local curr_line_length = #curr_line local curr_line_length = #curr_line
@ -284,8 +287,8 @@ end
--- Get the text of the range defined by start and end line/column --- Get the text of the range defined by start and end line/column
---@param lines table list of lines ---@param lines table list of lines
---@param start_range table table returned by first_difference ---@param start_range vim.lsp.sync.Range table returned by first_difference
---@param end_range table new_end_range returned by last_difference ---@param end_range vim.lsp.sync.Range new_end_range returned by last_difference
---@return string text extracted from defined region ---@return string text extracted from defined region
local function extract_text(lines, start_range, end_range, line_ending) local function extract_text(lines, start_range, end_range, line_ending)
if not lines[start_range.line_idx] then if not lines[start_range.line_idx] then
@ -326,7 +329,7 @@ end
---@param lines string[] ---@param lines string[]
---@param start_range vim.lsp.sync.Range ---@param start_range vim.lsp.sync.Range
---@param end_range vim.lsp.sync.Range ---@param end_range vim.lsp.sync.Range
---@param position_encoding string ---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
---@param line_ending string ---@param line_ending string
---@return integer ---@return integer
local function compute_range_length(lines, start_range, end_range, position_encoding, line_ending) local function compute_range_length(lines, start_range, end_range, position_encoding, line_ending)
@ -352,7 +355,9 @@ local function compute_range_length(lines, start_range, end_range, position_enco
for idx = start_range.line_idx + 1, end_range.line_idx - 1 do for idx = start_range.line_idx + 1, end_range.line_idx - 1 do
-- Length full line plus newline character -- Length full line plus newline character
if #lines[idx] > 0 then if #lines[idx] > 0 then
range_length = range_length + str_utfindex(lines[idx], position_encoding) + #line_ending range_length = range_length
+ str_utfindex(assert(lines[idx]), position_encoding)
+ #line_ending
else else
range_length = range_length + line_ending_length range_length = range_length + line_ending_length
end end
@ -372,7 +377,7 @@ end
---@param firstline integer line to begin search for first difference ---@param firstline integer line to begin search for first difference
---@param lastline integer line to begin search in old_lines for last difference ---@param lastline integer line to begin search in old_lines for last difference
---@param new_lastline integer line to begin search in new_lines for last difference ---@param new_lastline integer line to begin search in new_lines for last difference
---@param position_encoding string encoding requested by language server ---@param position_encoding 'utf-8'|'utf-16'|'utf-32' encoding requested by language server
---@param line_ending string ---@param line_ending string
---@return lsp.TextDocumentContentChangeEvent : see https://microsoft.github.io/language-server-protocol/specification/#textDocumentContentChangeEvent ---@return lsp.TextDocumentContentChangeEvent : see https://microsoft.github.io/language-server-protocol/specification/#textDocumentContentChangeEvent
function M.compute_diff( function M.compute_diff(

View File

@ -68,6 +68,7 @@ local function get_border_size(opts)
end end
--- @param e string --- @param e string
--- @return integer
local function border_height(e) local function border_height(e)
return #e > 0 and 1 or 0 return #e > 0 and 1 or 0
end end
@ -133,9 +134,9 @@ function M.set_lines(lines, A, B, new_lines)
error('Invalid range: ' .. vim.inspect({ A = A, B = B, #lines, new_lines })) error('Invalid range: ' .. vim.inspect({ A = A, B = B, #lines, new_lines }))
end end
local prefix = '' local prefix = ''
local suffix = lines[i_n]:sub(B[2] + 1) local suffix = assert(lines[i_n]):sub(B[2] + 1)
if A[2] > 0 then if A[2] > 0 then
prefix = lines[i_0]:sub(1, A[2]) prefix = assert(lines[i_0]):sub(1, A[2])
end end
local n = i_n - i_0 + 1 local n = i_n - i_0 + 1
if n ~= #new_lines then if n ~= #new_lines then
@ -181,7 +182,7 @@ end
--- ---
---@param bufnr integer bufnr to get the lines from ---@param bufnr integer bufnr to get the lines from
---@param rows integer[] zero-indexed line numbers ---@param rows integer[] zero-indexed line numbers
---@return table<integer, string>|string a table mapping rows to lines ---@return table<integer, string> # a table mapping rows to lines
local function get_lines(bufnr, rows) local function get_lines(bufnr, rows)
--- @type integer[] --- @type integer[]
rows = type(rows) == 'table' and rows or { rows } rows = type(rows) == 'table' and rows or { rows }
@ -219,7 +220,7 @@ local function get_lines(bufnr, rows)
-- get the data from the file -- get the data from the file
local fd = uv.fs_open(filename, 'r', 438) local fd = uv.fs_open(filename, 'r', 438)
if not fd then if not fd then
return '' return {}
end end
local stat = assert(uv.fs_fstat(fd)) local stat = assert(uv.fs_fstat(fd))
local data = assert(uv.fs_read(fd, stat.size, 0)) local data = assert(uv.fs_read(fd, stat.size, 0))
@ -322,6 +323,8 @@ function M.apply_text_edits(text_edits, bufnr, position_encoding)
end end
end end
--- @cast text_edits (lsp.TextEdit|{_index: integer})[]
-- Sort text_edits -- Sort text_edits
---@param a lsp.TextEdit | { _index: integer } ---@param a lsp.TextEdit | { _index: integer }
---@param b lsp.TextEdit | { _index: integer } ---@param b lsp.TextEdit | { _index: integer }
@ -1298,7 +1301,6 @@ end
--- 2. Successive empty lines are collapsed into a single empty line --- 2. Successive empty lines are collapsed into a single empty line
--- 3. Thematic breaks are expanded to the given width --- 3. Thematic breaks are expanded to the given width
--- ---
---@private
---@param contents string[] ---@param contents string[]
---@param opts? vim.lsp.util._normalize_markdown.Opts ---@param opts? vim.lsp.util._normalize_markdown.Opts
---@return string[] table of lines containing normalized Markdown ---@return string[] table of lines containing normalized Markdown
@ -1369,7 +1371,6 @@ local function close_preview_autocmd(events, winnr, bufnrs)
end end
end end
---@private
--- Computes size of float needed to show contents (with optional wrapping) --- Computes size of float needed to show contents (with optional wrapping)
--- ---
---@param contents string[] of lines to show in window ---@param contents string[] of lines to show in window
@ -1796,7 +1797,7 @@ function M.symbols_to_items(symbols, bufnr, position_encoding)
'symbols_to_items must be called with valid position encoding', 'symbols_to_items must be called with valid position encoding',
vim.log.levels.WARN vim.log.levels.WARN
) )
position_encoding = vim.lsp.get_clients({ bufnr = bufnr })[1].offset_encoding position_encoding = assert(vim.lsp.get_clients({ bufnr = bufnr })[1]).offset_encoding
end end
local items = {} --- @type vim.quickfix.entry[] local items = {} --- @type vim.quickfix.entry[]
@ -1874,11 +1875,11 @@ end
---@return string filetype or "markdown" if it was unchanged. ---@return string filetype or "markdown" if it was unchanged.
function M.try_trim_markdown_code_blocks(lines) function M.try_trim_markdown_code_blocks(lines)
vim.deprecate('vim.lsp.util.try_trim_markdown_code_blocks()', 'nil', '0.12') vim.deprecate('vim.lsp.util.try_trim_markdown_code_blocks()', 'nil', '0.12')
local language_id = lines[1]:match('^```(.*)') local language_id = assert(lines[1]):match('^```(.*)')
if language_id then if language_id then
local has_inner_code_fence = false local has_inner_code_fence = false
for i = 2, (#lines - 1) do for i = 2, (#lines - 1) do
local line = lines[i] local line = lines[i] --[[@as string]]
if line:sub(1, 3) == '```' then if line:sub(1, 3) == '```' then
has_inner_code_fence = true has_inner_code_fence = true
break break
@ -1937,7 +1938,7 @@ end
--- Utility function for getting the encoding of the first LSP client on the given buffer. --- Utility function for getting the encoding of the first LSP client on the given buffer.
---@deprecated ---@deprecated
---@param bufnr integer buffer handle or 0 for current, defaults to current ---@param bufnr integer buffer handle or 0 for current, defaults to current
---@return string encoding first client if there is one, nil otherwise ---@return 'utf-8'|'utf-16'|'utf-32' encoding first client if there is one, nil otherwise
function M._get_offset_encoding(bufnr) function M._get_offset_encoding(bufnr)
validate('bufnr', bufnr, 'number', true) validate('bufnr', bufnr, 'number', true)
@ -1963,6 +1964,7 @@ function M._get_offset_encoding(bufnr)
) )
end end
end end
--- @cast offset_encoding -? hack - not safe
return offset_encoding return offset_encoding
end end
@ -2056,7 +2058,7 @@ end
--- Create the workspace params --- Create the workspace params
---@param added lsp.WorkspaceFolder[] ---@param added lsp.WorkspaceFolder[]
---@param removed lsp.WorkspaceFolder[] ---@param removed lsp.WorkspaceFolder[]
---@return lsp.WorkspaceFoldersChangeEvent ---@return lsp.DidChangeWorkspaceFoldersParams
function M.make_workspace_params(added, removed) function M.make_workspace_params(added, removed)
return { event = { added = added, removed = removed } } return { event = { added = added, removed = removed } }
end end
@ -2105,7 +2107,7 @@ function M.character_offset(buf, row, col, offset_encoding)
'character_offset must be called with valid offset encoding', 'character_offset must be called with valid offset encoding',
vim.log.levels.WARN vim.log.levels.WARN
) )
offset_encoding = vim.lsp.get_clients({ bufnr = buf })[1].offset_encoding offset_encoding = assert(vim.lsp.get_clients({ bufnr = buf })[1]).offset_encoding
end end
return vim.str_utfindex(line, offset_encoding, col, false) return vim.str_utfindex(line, offset_encoding, col, false)
end end
@ -2168,7 +2170,6 @@ end
---@field method? vim.lsp.protocol.Method.ClientToServer.Request ---@field method? vim.lsp.protocol.Method.ClientToServer.Request
---@field type? string ---@field type? string
---@private
--- Cancel all {filter}ed requests. --- Cancel all {filter}ed requests.
--- ---
---@param filter? vim.lsp.util._cancel_requests.Filter ---@param filter? vim.lsp.util._cancel_requests.Filter
@ -2203,10 +2204,9 @@ end
---@field client_id? integer Client ID to refresh (default: all clients) ---@field client_id? integer Client ID to refresh (default: all clients)
---@field handler? lsp.Handler ---@field handler? lsp.Handler
---@private
--- Request updated LSP information for a buffer. --- Request updated LSP information for a buffer.
--- ---
---@param method string LSP method to call ---@param method vim.lsp.protocol.Method.ClientToServer.Request LSP method to call
---@param opts? vim.lsp.util._refresh.Opts Options table ---@param opts? vim.lsp.util._refresh.Opts Options table
function M._refresh(method, opts) function M._refresh(method, opts)
opts = opts or {} opts = opts or {}

View File

@ -27,8 +27,8 @@ end
--- If {fullpath} is a directory, then nothing is read from the filesystem, and --- If {fullpath} is a directory, then nothing is read from the filesystem, and
--- `contents = true` and `hash = "directory"` is returned instead. --- `contents = true` and `hash = "directory"` is returned instead.
--- ---
---@param fullpath (string) Path to a file or directory to read. ---@param fullpath string Path to a file or directory to read.
---@param bufnr (number?) The number of the buffer. ---@param bufnr integer? The number of the buffer.
---@return string|boolean? contents the contents of the file, or true if it's a directory ---@return string|boolean? contents the contents of the file, or true if it's a directory
---@return string? hash the hash of the contents, or "directory" if it's a directory ---@return string? hash the hash of the contents, or "directory" if it's a directory
local function compute_hash(fullpath, bufnr) local function compute_hash(fullpath, bufnr)

View File

@ -105,7 +105,7 @@ end
--- @return fun():string? : Iterator over the split components --- @return fun():string? : Iterator over the split components
function vim.gsplit(s, sep, opts) function vim.gsplit(s, sep, opts)
local plain --- @type boolean? local plain --- @type boolean?
local trimempty = false local trimempty = false --- @type boolean?
if type(opts) == 'boolean' then if type(opts) == 'boolean' then
plain = opts -- For backwards compatibility. plain = opts -- For backwards compatibility.
else else
@ -616,7 +616,7 @@ function vim.spairs(t)
--- @cast t table<any,any> --- @cast t table<any,any>
-- collect the keys -- collect the keys
local keys = {} local keys = {} --- @type string[]
for k in pairs(t) do for k in pairs(t) do
table.insert(keys, k) table.insert(keys, k)
end end
@ -1027,7 +1027,7 @@ do
--- ---
--- @param name string Argument name --- @param name string Argument name
--- @param value any Argument value --- @param value any Argument value
--- @param validator vim.validate.Validator --- @param validator vim.validate.Validator :
--- - (`string|string[]`): Any value that can be returned from |lua-type()| in addition to --- - (`string|string[]`): Any value that can be returned from |lua-type()| in addition to
--- `'callable'`: `'boolean'`, `'callable'`, `'function'`, `'nil'`, `'number'`, `'string'`, `'table'`, --- `'callable'`: `'boolean'`, `'callable'`, `'function'`, `'nil'`, `'number'`, `'string'`, `'table'`,
--- `'thread'`, `'userdata'`. --- `'thread'`, `'userdata'`.
@ -1194,7 +1194,6 @@ do
end end
end end
--- @private
--- @generic T --- @generic T
--- @param root string --- @param root string
--- @param mod T --- @param mod T
@ -1214,7 +1213,6 @@ function vim._defer_require(root, mod)
}) })
end end
--- @private
--- Creates a module alias/shim that lazy-loads a target module. --- Creates a module alias/shim that lazy-loads a target module.
--- ---
--- Unlike `vim.defaulttable()` this also: --- Unlike `vim.defaulttable()` this also:
@ -1423,7 +1421,7 @@ function vim._resolve_bufnr(bufnr)
end end
--- @generic T --- @generic T
--- @param x elem_or_list<T>? --- @param x T|T[]
--- @return T[] --- @return T[]
function vim._ensure_list(x) function vim._ensure_list(x)
if type(x) == 'table' then if type(x) == 'table' then
@ -1432,4 +1430,7 @@ function vim._ensure_list(x)
return { x } return { x }
end end
-- Use max 32-bit signed int value to avoid overflow on 32-bit systems. #31633
vim._maxint = 2 ^ 32 - 1
return vim return vim

View File

@ -79,7 +79,7 @@ end
--- ---
--- @param size integer Number of spaces. --- @param size integer Number of spaces.
--- @param text string Text to indent. --- @param text string Text to indent.
--- @param opts? { expandtab?: number } --- @param opts? { expandtab?: integer }
--- @return string # Indented text. --- @return string # Indented text.
--- @return integer # Indent size _before_ modification. --- @return integer # Indent size _before_ modification.
function M.indent(size, text, opts) function M.indent(size, text, opts)
@ -91,7 +91,7 @@ function M.indent(size, text, opts)
local tabspaces = opts.expandtab and (' '):rep(opts.expandtab) or nil local tabspaces = opts.expandtab and (' '):rep(opts.expandtab) or nil
--- Minimum common indent shared by all lines. --- Minimum common indent shared by all lines.
local old_indent --[[@type number?]] local old_indent --- @type integer?
local prefix = tabspaces and ' ' or nil -- Indent char (space or tab). local prefix = tabspaces and ' ' or nil -- Indent char (space or tab).
--- Check all non-empty lines, capturing leading whitespace (if any). --- Check all non-empty lines, capturing leading whitespace (if any).
--- @diagnostic disable-next-line: no-unknown --- @diagnostic disable-next-line: no-unknown
@ -106,7 +106,7 @@ function M.indent(size, text, opts)
end end
prefix = prefix and prefix or line_ws:sub(1, 1) prefix = prefix and prefix or line_ws:sub(1, 1)
local _, end_ = line_ws:find('^[' .. prefix .. ']+') local _, end_ = line_ws:find('^[' .. prefix .. ']+')
old_indent = math.min(old_indent or math.huge, end_ or 0) old_indent = math.min(old_indent or math.huge, end_ or 0) --[[@as integer?]]
end end
-- Default to 0 if all lines are empty. -- Default to 0 if all lines are empty.
old_indent = old_indent or 0 old_indent = old_indent or 0

View File

@ -280,18 +280,19 @@ function M.get_captures_at_pos(bufnr, row, col)
end end
local q = buf_highlighter:get_query(tree:lang()) local q = buf_highlighter:get_query(tree:lang())
local query = q:query()
-- Some injected languages may not have highlight queries. -- Some injected languages may not have highlight queries.
if not q:query() then if not query then
return return
end end
local iter = q:query():iter_captures(root, buf_highlighter.bufnr, row, row + 1) local iter = query:iter_captures(root, buf_highlighter.bufnr, row, row + 1)
for id, node, metadata, match in iter do for id, node, metadata, match in iter do
if M.is_in_node_range(node, row, col) then if M.is_in_node_range(node, row, col) then
---@diagnostic disable-next-line: invisible ---@diagnostic disable-next-line: invisible
local capture = q._query.captures[id] -- name of the capture in the query local capture = query.captures[id] -- name of the capture in the query
if capture ~= nil then if capture ~= nil then
local _, pattern_id = match:info() local _, pattern_id = match:info()
table.insert(matches, { table.insert(matches, {

View File

@ -154,7 +154,6 @@ local function lint_match(buf, match, query, lang_context, diagnostics)
end end
end end
--- @private
--- @param buf integer Buffer to lint --- @param buf integer Buffer to lint
--- @param opts vim.treesitter.query.lint.Opts|QueryLinterNormalizedOpts|nil Options for linting --- @param opts vim.treesitter.query.lint.Opts|QueryLinterNormalizedOpts|nil Options for linting
function M.lint(buf, opts) function M.lint(buf, opts)
@ -193,13 +192,11 @@ function M.lint(buf, opts)
vim.diagnostic.set(namespace, buf, diagnostics) vim.diagnostic.set(namespace, buf, diagnostics)
end end
--- @private
--- @param buf integer --- @param buf integer
function M.clear(buf) function M.clear(buf)
vim.diagnostic.reset(namespace, buf) vim.diagnostic.reset(namespace, buf)
end end
--- @private
--- @param findstart 0|1 --- @param findstart 0|1
--- @param base string --- @param base string
function M.omnifunc(findstart, base) function M.omnifunc(findstart, base)

View File

@ -72,7 +72,6 @@ M.cmp_pos = {
setmetatable(M.cmp_pos, { __call = cmp_pos }) setmetatable(M.cmp_pos, { __call = cmp_pos })
---@private
---Check if a variable is a valid range object ---Check if a variable is a valid range object
---@param r any ---@param r any
---@return boolean ---@return boolean
@ -92,7 +91,6 @@ function M.validate(r)
return true return true
end end
---@private
---@param r1 Range ---@param r1 Range
---@param r2 Range ---@param r2 Range
---@return boolean ---@return boolean
@ -113,7 +111,6 @@ function M.intercepts(r1, r2)
return true return true
end end
---@private
---@param r1 Range6 ---@param r1 Range6
---@param r2 Range6 ---@param r2 Range6
---@return Range6? ---@return Range6?
@ -126,7 +123,6 @@ function M.intersection(r1, r2)
return { rs[1], rs[2], rs[3], re[4], re[5], re[6] } return { rs[1], rs[2], rs[3], re[4], re[5], re[6] }
end end
---@private
---@param r Range ---@param r Range
---@return integer, integer, integer, integer ---@return integer, integer, integer, integer
function M.unpack4(r) function M.unpack4(r)
@ -137,14 +133,12 @@ function M.unpack4(r)
return r[1], r[2], r[3 + off_1], r[4 + off_1] return r[1], r[2], r[3 + off_1], r[4 + off_1]
end end
---@private
---@param r Range6 ---@param r Range6
---@return integer, integer, integer, integer, integer, integer ---@return integer, integer, integer, integer, integer, integer
function M.unpack6(r) function M.unpack6(r)
return r[1], r[2], r[3], r[4], r[5], r[6] return r[1], r[2], r[3], r[4], r[5], r[6]
end end
---@private
---@param r1 Range ---@param r1 Range
---@param r2 Range ---@param r2 Range
---@return boolean whether r1 contains r2 ---@return boolean whether r1 contains r2
@ -188,7 +182,6 @@ local function get_offset(source, index)
return byte return byte
end end
---@private
---@param source integer|string ---@param source integer|string
---@param range Range ---@param range Range
---@return Range6 ---@return Range6

View File

@ -15,7 +15,7 @@ local TSTreeView = {}
---@class (private) vim.treesitter.dev.TSTreeViewOpts ---@class (private) vim.treesitter.dev.TSTreeViewOpts
---@field anon boolean If true, display anonymous nodes. ---@field anon boolean If true, display anonymous nodes.
---@field lang boolean If true, display the language alongside each node. ---@field lang boolean If true, display the language alongside each node.
---@field indent number Number of spaces to indent nested lines. ---@field indent integer Number of spaces to indent nested lines.
---@class (private) vim.treesitter.dev.Node ---@class (private) vim.treesitter.dev.Node
---@field node TSNode Treesitter node ---@field node TSNode Treesitter node
@ -290,7 +290,7 @@ end
--- The node number is dependent on whether or not anonymous nodes are displayed. --- The node number is dependent on whether or not anonymous nodes are displayed.
--- ---
---@param i integer Node number to get ---@param i integer Node number to get
---@return vim.treesitter.dev.Node ---@return vim.treesitter.dev.Node?
---@package ---@package
function TSTreeView:get(i) function TSTreeView:get(i)
local t = self.opts.anon and self.nodes or self.named local t = self.opts.anon and self.nodes or self.named
@ -329,8 +329,7 @@ end
--- source buffer as its only argument and should return a string. --- source buffer as its only argument and should return a string.
--- @field title (string|fun(bufnr:integer):string|nil) --- @field title (string|fun(bufnr:integer):string|nil)
--- @private --- @nodoc
---
--- @param opts vim.treesitter.dev.inspect_tree.Opts? --- @param opts vim.treesitter.dev.inspect_tree.Opts?
function M.inspect_tree(opts) function M.inspect_tree(opts)
vim.validate('opts', opts, 'table', true) vim.validate('opts', opts, 'table', true)
@ -401,7 +400,7 @@ function M.inspect_tree(opts)
-- update source window if original was closed -- update source window if original was closed
if not api.nvim_win_is_valid(win) then if not api.nvim_win_is_valid(win) then
win = vim.fn.win_findbuf(buf)[1] win = assert(vim.fn.win_findbuf(buf)[1])
end end
api.nvim_set_current_win(win) api.nvim_set_current_win(win)
@ -475,7 +474,7 @@ function M.inspect_tree(opts)
-- update source window if original was closed -- update source window if original was closed
if not api.nvim_win_is_valid(win) then if not api.nvim_win_is_valid(win) then
win = vim.fn.win_findbuf(buf)[1] win = assert(vim.fn.win_findbuf(buf)[1])
end end
local topline, botline = vim.fn.line('w0', win), vim.fn.line('w$', win) local topline, botline = vim.fn.line('w0', win), vim.fn.line('w$', win)
@ -599,7 +598,7 @@ local function update_editor_highlights(query_win, base_win, lang)
end end
end end
--- @private --- @nodoc
--- @param lang? string language to open the query editor for. --- @param lang? string language to open the query editor for.
--- @return boolean? `true` on success, `nil` on failure --- @return boolean? `true` on success, `nil` on failure
--- @return string? error message, if applicable --- @return string? error message, if applicable

View File

@ -41,7 +41,7 @@ function M.get_lang(filetype)
return ft_to_lang[filetype] return ft_to_lang[filetype]
end end
-- for subfiletypes like html.glimmer use only "main" filetype -- for subfiletypes like html.glimmer use only "main" filetype
filetype = vim.split(filetype, '.', { plain = true })[1] filetype = assert(vim.split(filetype, '.', { plain = true })[1])
return ft_to_lang[filetype] or filetype return ft_to_lang[filetype] or filetype
end end

View File

@ -49,7 +49,10 @@ local hrtime = vim.uv.hrtime
local default_parse_timeout_ns = 3 * 1000000 local default_parse_timeout_ns = 3 * 1000000
---@type Range2 ---@type Range2
local entire_document_range = { 0, math.huge } local entire_document_range = {
0,
math.huge --[[@as integer]],
}
---@alias TSCallbackName ---@alias TSCallbackName
---| 'changedtree' ---| 'changedtree'

View File

@ -193,7 +193,7 @@ function M.get_files(lang, query_name, is_included)
local langlist = modeline:match(MODELINE_FORMAT) local langlist = modeline:match(MODELINE_FORMAT)
if langlist then if langlist then
---@diagnostic disable-next-line:param-type-mismatch ---@diagnostic disable-next-line:param-type-mismatch
for _, incllang in ipairs(vim.split(langlist, ',', true)) do for _, incllang in ipairs(vim.split(langlist, ',')) do
local is_optional = incllang:match('%(.*%)') local is_optional = incllang:match('%(.*%)')
if is_optional then if is_optional then
@ -778,7 +778,7 @@ local directive_handlers = {
--- Adds a new predicate to be used in queries --- Adds a new predicate to be used in queries
--- ---
---@param name string Name of the predicate, without leading # ---@param name string Name of the predicate, without leading #
---@param handler fun(match: table<integer,TSNode[]>, pattern: integer, source: integer|string, predicate: any[], metadata: vim.treesitter.query.TSMetadata): boolean? ---@param handler fun(match: table<integer,TSNode[]>, pattern: integer, source: integer|string, predicate: any[], metadata: vim.treesitter.query.TSMetadata): boolean? #
--- - see |vim.treesitter.query.add_directive()| for argument meanings --- - see |vim.treesitter.query.add_directive()| for argument meanings
---@param opts? vim.treesitter.query.add_predicate.Opts ---@param opts? vim.treesitter.query.add_predicate.Opts
function M.add_predicate(name, handler, opts) function M.add_predicate(name, handler, opts)
@ -818,7 +818,7 @@ end
--- metadata table `metadata[capture_id].key = value` --- metadata table `metadata[capture_id].key = value`
--- ---
---@param name string Name of the directive, without leading # ---@param name string Name of the directive, without leading #
---@param handler fun(match: table<integer,TSNode[]>, pattern: integer, source: integer|string, predicate: any[], metadata: vim.treesitter.query.TSMetadata) ---@param handler fun(match: table<integer,TSNode[]>, pattern: integer, source: integer|string, predicate: any[], metadata: vim.treesitter.query.TSMetadata) #
--- - match: A table mapping capture IDs to a list of captured nodes --- - match: A table mapping capture IDs to a list of captured nodes
--- - pattern: the index of the matching pattern in the query file --- - pattern: the index of the matching pattern in the query file
--- - predicate: list of strings containing the full directive being called, e.g. --- - predicate: list of strings containing the full directive being called, e.g.

View File

@ -22,7 +22,7 @@ end
function M.paste(reg) function M.paste(reg)
local clipboard = reg == '+' and 'c' or 'p' local clipboard = reg == '+' and 'c' or 'p'
return function() return function()
local contents = nil local contents = nil --- @type string?
local id = vim.api.nvim_create_autocmd('TermResponse', { local id = vim.api.nvim_create_autocmd('TermResponse', {
callback = function(args) callback = function(args)
local resp = args.data.sequence ---@type string local resp = args.data.sequence ---@type string

View File

@ -32,6 +32,7 @@ local LUA_API_RETURN_OVERRIDES = {
nvim_get_command = 'table<string,vim.api.keyset.command_info>', nvim_get_command = 'table<string,vim.api.keyset.command_info>',
nvim_get_keymap = 'vim.api.keyset.get_keymap[]', nvim_get_keymap = 'vim.api.keyset.get_keymap[]',
nvim_get_mark = 'vim.api.keyset.get_mark', nvim_get_mark = 'vim.api.keyset.get_mark',
nvim_eval_statusline = 'vim.api.keyset.eval_statusline_ret',
-- Can also return table<string,vim.api.keyset.get_hl_info>, however we need to -- Can also return table<string,vim.api.keyset.get_hl_info>, however we need to
-- pick one to get some benefit. -- pick one to get some benefit.
@ -45,6 +46,7 @@ local LUA_API_RETURN_OVERRIDES = {
nvim_get_option_info2 = 'vim.api.keyset.get_option_info', nvim_get_option_info2 = 'vim.api.keyset.get_option_info',
nvim_parse_cmd = 'vim.api.keyset.parse_cmd', nvim_parse_cmd = 'vim.api.keyset.parse_cmd',
nvim_win_get_config = 'vim.api.keyset.win_config', nvim_win_get_config = 'vim.api.keyset.win_config',
nvim_win_text_height = 'vim.api.keyset.win_text_height_ret',
} }
local LUA_API_KEYSET_OVERRIDES = { local LUA_API_KEYSET_OVERRIDES = {

View File

@ -147,6 +147,9 @@ local function process_doc_line(line, state)
cur_obj.fields = {} cur_obj.fields = {}
elseif kind == 'field' then elseif kind == 'field' then
--- @cast parsed nvim.luacats.Field --- @cast parsed nvim.luacats.Field
if parsed.desc == '' then
parsed.desc = nil
end
parsed.desc = parsed.desc or state.doc_lines and table.concat(state.doc_lines, '\n') or nil parsed.desc = parsed.desc or state.doc_lines and table.concat(state.doc_lines, '\n') or nil
if parsed.desc then if parsed.desc then
parsed.desc = vim.trim(parsed.desc) parsed.desc = vim.trim(parsed.desc)

View File

@ -3970,6 +3970,7 @@ M.funcs = {
]=], ]=],
name = 'getcurpos', name = 'getcurpos',
params = { { 'winid', 'integer' } }, params = { { 'winid', 'integer' } },
returns = '[integer, integer, integer, integer, integer]',
signature = 'getcurpos([{winid}])', signature = 'getcurpos([{winid}])',
}, },
getcursorcharpos = { getcursorcharpos = {
@ -4313,6 +4314,7 @@ M.funcs = {
]=], ]=],
name = 'getmatches', name = 'getmatches',
params = { { 'win', 'integer' } }, params = { { 'win', 'integer' } },
returns = 'vim.fn.getmatches.ret.item[]',
signature = 'getmatches([{win}])', signature = 'getmatches([{win}])',
}, },
getmousepos = { getmousepos = {
@ -4428,7 +4430,7 @@ M.funcs = {
]=], ]=],
name = 'getpos', name = 'getpos',
params = { { 'expr', 'string' } }, params = { { 'expr', 'string' } },
returns = 'integer[]', returns = '[integer, integer, integer, integer]',
signature = 'getpos({expr})', signature = 'getpos({expr})',
}, },
getqflist = { getqflist = {
@ -4672,7 +4674,11 @@ M.funcs = {
< <
]=], ]=],
name = 'getregion', name = 'getregion',
params = { { 'pos1', 'table' }, { 'pos2', 'table' }, { 'opts', 'table' } }, params = {
{ 'pos1', '[integer, integer, integer, integer]' },
{ 'pos2', '[integer, integer, integer, integer]' },
{ 'opts', '{type?:string, exclusive?:boolean}' },
},
returns = 'string[]', returns = 'string[]',
signature = 'getregion({pos1}, {pos2} [, {opts}])', signature = 'getregion({pos1}, {pos2} [, {opts}])',
}, },
@ -4712,8 +4718,12 @@ M.funcs = {
(default: |FALSE|) (default: |FALSE|)
]=], ]=],
name = 'getregionpos', name = 'getregionpos',
params = { { 'pos1', 'table' }, { 'pos2', 'table' }, { 'opts', 'table' } }, params = {
returns = 'integer[][][]', { 'pos1', '[integer, integer, integer, integer]' },
{ 'pos2', '[integer, integer, integer, integer]' },
{ 'opts', '{type?:string, exclusive?:boolean, eol?:boolean}' },
},
returns = '[ [integer, integer, integer, integer], [integer, integer, integer, integer] ][]',
signature = 'getregionpos({pos1}, {pos2} [, {opts}])', signature = 'getregionpos({pos1}, {pos2} [, {opts}])',
}, },
getregtype = { getregtype = {
@ -8648,6 +8658,7 @@ M.funcs = {
]=], ]=],
name = 'readfile', name = 'readfile',
params = { { 'fname', 'string' }, { 'type', 'string' }, { 'max', 'integer' } }, params = { { 'fname', 'string' }, { 'type', 'string' }, { 'max', 'integer' } },
returns = 'string[]',
signature = 'readfile({fname} [, {type} [, {max}]])', signature = 'readfile({fname} [, {type} [, {max}]])',
}, },
reduce = { reduce = {
@ -9998,7 +10009,7 @@ M.funcs = {
]=], ]=],
name = 'setmatches', name = 'setmatches',
params = { { 'list', 'any' }, { 'win', 'integer' } }, params = { { 'list', 'vim.fn.getmatches.ret.item[]' }, { 'win', 'integer' } },
signature = 'setmatches({list} [, {win}])', signature = 'setmatches({list} [, {win}])',
}, },
setpos = { setpos = {
@ -12924,6 +12935,7 @@ M.funcs = {
]=], ]=],
name = 'virtcol', name = 'virtcol',
params = { { 'expr', 'string|any[]' }, { 'list', 'boolean' }, { 'winid', 'integer' } }, params = { { 'expr', 'string|any[]' }, { 'list', 'boolean' }, { 'winid', 'integer' } },
returns = 'integer|[integer, integer]',
signature = 'virtcol({expr} [, {list} [, {winid}]])', signature = 'virtcol({expr} [, {list} [, {winid}]])',
}, },
virtcol2col = { virtcol2col = {