commit 533cc0ab354dbe3a0e5a3c8261f80a821a01fbea
parent 9641ad9369f66c9e30114a57914672eb2ca96d51
Author: Lewis Russell <lewis6991@gmail.com>
Date: Mon, 2 Jun 2025 13:44:00 +0100
fix(vim.diagnostic): improve typing
Problem:
`vim.diagnostic.set()` doesn't actually accept a list of
`vim.Diagnostic` as internally `vim.diagnostic.set()` normalizes the
diagnostics and this normalization is assumed throughout the module.
Solution:
- Add a new type `vim.Diagnostic.Set` which is the input to `vim.diagnostic.set()`
- `col` is now an optional field and defaults to `0` to be consistent
with `vim.diagnostic.match()`.
- Change `table.insert(t, x)` to `table[#table + 1] = x` for improved
type checking.
Diffstat:
4 files changed, 171 insertions(+), 95 deletions(-)
diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt
@@ -436,15 +436,15 @@ Lua module: vim.diagnostic *diagnostic-api*
0-based rows and columns). |api-indexing|
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
(0-indexed)
- • {end_col}? (`integer`) The final column of the diagnostic
+ • {end_col} (`integer`) The final column of the diagnostic
(0-indexed)
- • {severity}? (`vim.diagnostic.Severity`) The severity of the
+ • {severity} (`vim.diagnostic.Severity`) The severity of the
diagnostic |vim.diagnostic.severity|
• {message} (`string`) The diagnostic text
• {source}? (`string`) The source of the diagnostic
@@ -452,6 +452,24 @@ Lua module: vim.diagnostic *diagnostic-api*
• {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*
A table with the following keys:
@@ -930,7 +948,7 @@ set({namespace}, {bufnr}, {diagnostics}, {opts}) *vim.diagnostic.set()*
Parameters: ~
• {namespace} (`integer`) The diagnostic namespace
• {bufnr} (`integer`) Buffer number
- • {diagnostics} (`vim.Diagnostic[]`) See |vim.Diagnostic|.
+ • {diagnostics} (`vim.Diagnostic.Set[]`) See |vim.Diagnostic.Set|.
• {opts} (`vim.diagnostic.Opts?`) Display options to pass to
|vim.diagnostic.show()|. See |vim.diagnostic.Opts|.
diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua
@@ -23,22 +23,22 @@ end
--- @class vim.Diagnostic
---
--- Buffer number
---- @field bufnr? integer
+--- @field bufnr integer
---
--- The starting line of the diagnostic (0-indexed)
--- @field lnum integer
---
--- The final line of the diagnostic (0-indexed)
---- @field end_lnum? integer
+--- @field end_lnum integer
---
--- The starting column of the diagnostic (0-indexed)
--- @field col integer
---
--- The final column of the diagnostic (0-indexed)
---- @field end_col? integer
+--- @field end_col integer
---
--- The severity of the diagnostic |vim.diagnostic.severity|
---- @field severity? vim.diagnostic.Severity
+--- @field severity vim.diagnostic.Severity
---
--- The diagnostic text
--- @field message string
@@ -56,6 +56,30 @@ end
---
--- @field namespace? integer
+--- @class vim.Diagnostic.Set : vim.Diagnostic
+---
+--- Do not set. Will be overridden by `vim.diagnostic.set()`.
+--- @field bufnr nil
+---
+--- Do not set. Will be overridden by `vim.diagnostic.set()`.
+--- @field namespace nil
+---
+--- The starting column of the diagnostic in bytes (0-indexed)
+--- (default: `0`)
+--- @field col? 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:
--- - `false`: Disable this feature
--- - `true`: Enable this feature, use default settings.
@@ -319,21 +343,36 @@ M.severity = {
WARN = 2,
INFO = 3,
HINT = 4,
+}
+
+--- @enum vim.diagnostic.SeverityName
+local severity_invert = {
[1] = 'ERROR',
[2] = 'WARN',
[3] = 'INFO',
[4] = 'HINT',
- --- Mappings from qflist/loclist error types to severities
- E = 1,
- W = 2,
- I = 3,
- N = 4,
}
---- @alias vim.diagnostic.SeverityInt 1|2|3|4
+do
+ --- Set extra fields through table alias to hide from analysis tools
+ local s = M.severity --- @type table<any,any>
+
+ for i, name in ipairs(severity_invert) do
+ s[i] = name
+ end
+
+ --- Mappings from qflist/loclist error types to severities
+ s.E = 1
+ s.W = 2
+ s.I = 3
+ s.N = 4
+end
--- See |diagnostic-severity| and |vim.diagnostic.get()|
---- @alias vim.diagnostic.SeverityFilter vim.diagnostic.Severity|vim.diagnostic.Severity[]|{min:vim.diagnostic.Severity,max:vim.diagnostic.Severity}
+--- @alias vim.diagnostic.SeverityFilter
+--- | vim.diagnostic.Severity
+--- | vim.diagnostic.Severity[]
+--- | {min:vim.diagnostic.Severity,max:vim.diagnostic.Severity}
--- @type vim.diagnostic.Opts
local global_diagnostic_options = {
@@ -400,11 +439,11 @@ do
})
end
---- @class (private) vim.diagnostic._extmark
---- @field [1] integer id
---- @field [2] integer start
---- @field [3] integer end
---- @field [4] table details
+--- @class (private) vim.diagnostic._extmark : vim.api.keyset.get_extmark_item
+--- @field [1] integer extmark_id
+--- @field [2] integer row
+--- @field [3] integer col
+--- @field [4] vim.api.keyset.extmark_details
--- @type table<integer,table<integer,vim.diagnostic._extmark[]>>
local diagnostic_cache_extmarks = setmetatable({}, bufnr_and_namespace_cacher_mt)
@@ -427,26 +466,30 @@ local bufs_waiting_to_update = setmetatable({}, bufnr_and_namespace_cacher_mt)
--- @type table<integer,vim.diagnostic.NS>
local all_namespaces = {}
----@param severity string|vim.diagnostic.Severity
+---@param severity string|vim.diagnostic.Severity?
---@return vim.diagnostic.Severity?
local function to_severity(severity)
if type(severity) == 'string' then
- assert(M.severity[string.upper(severity)], string.format('Invalid severity: %s', severity))
- return M.severity[string.upper(severity)]
+ local ret = M.severity[severity:upper()] --[[@as vim.diagnostic.Severity?]]
+ if not ret then
+ error(('Invalid severity: %s'):format(severity))
+ end
+ return ret
end
- return severity
+ return severity --[[@as vim.diagnostic.Severity?]]
end
--- @param severity vim.diagnostic.SeverityFilter
---- @return fun(vim.Diagnostic):boolean
+--- @return fun(d: vim.Diagnostic):boolean
local function severity_predicate(severity)
if type(severity) ~= 'table' then
- severity = assert(to_severity(severity))
+ local severity0 = to_severity(severity)
---@param d vim.Diagnostic
return function(d)
- return d.severity == severity
+ return d.severity == severity0
end
end
+ --- @diagnostic disable-next-line: undefined-field
if severity.min or severity.max then
--- @cast severity {min:vim.diagnostic.Severity,max:vim.diagnostic.Severity}
local min_severity = to_severity(severity.min) or M.severity.HINT
@@ -512,7 +555,7 @@ local function prefix_source(diagnostics)
end, diagnostics)
end
---- @param format fun(vim.Diagnostic): string?
+--- @param format fun(diagnostic: vim.Diagnostic): string?
--- @param diagnostics vim.Diagnostic[]
--- @return vim.Diagnostic[]
local function reformat_diagnostics(format, diagnostics)
@@ -584,7 +627,7 @@ local function get_resolved_options(opts, namespace, bufnr)
resolved[k] = resolve_optional_value(k, resolved[k], namespace, bufnr)
end
end
- return resolved
+ return resolved --[[@as vim.diagnostic.OptsResolved]]
end
-- Default diagnostic highlights
@@ -597,20 +640,17 @@ local diagnostic_severities = {
--- Make a map from vim.diagnostic.Severity -> Highlight Name
--- @param base_name string
---- @return table<vim.diagnostic.SeverityInt,string>
+--- @return table<vim.diagnostic.Severity,string>
local function make_highlight_map(base_name)
- local result = {} --- @type table<vim.diagnostic.SeverityInt,string>
+ local result = {} --- @type table<vim.diagnostic.Severity,string>
for k in pairs(diagnostic_severities) do
- local name = M.severity[k]
- name = name:sub(1, 1) .. name:sub(2):lower()
- result[k] = 'Diagnostic' .. base_name .. name
+ local name = severity_invert[k]
+ result[k] = ('Diagnostic%s%s%s'):format(base_name, name:sub(1, 1), name:sub(2):lower())
end
return result
end
--- TODO(lewis6991): these highlight maps can only be indexed with an integer, however there usage
--- implies they can be indexed with any vim.diagnostic.Severity
local virtual_text_highlight_map = make_highlight_map('VirtualText')
local virtual_lines_highlight_map = make_highlight_map('VirtualLines')
local underline_highlight_map = make_highlight_map('Underline')
@@ -658,17 +698,24 @@ end
--- @param namespace integer
--- @param bufnr integer
---- @param diagnostics vim.Diagnostic[]
+--- @param d vim.Diagnostic.Set
+local function norm_diag(bufnr, namespace, d)
+ vim.validate('diagnostic.lnum', d.lnum, 'number')
+ local d1 = d --[[@as vim.Diagnostic]]
+ d1.severity = d.severity and to_severity(d.severity) or M.severity.ERROR
+ d1.end_lnum = d.end_lnum or d.lnum
+ d1.col = d.col or 0
+ d1.end_col = d.end_col or d.col or 0
+ d1.namespace = namespace
+ d1.bufnr = bufnr
+end
+
+--- @param namespace integer
+--- @param bufnr integer
+--- @param diagnostics vim.Diagnostic.Set[]
local function set_diagnostic_cache(namespace, bufnr, diagnostics)
for _, diagnostic in ipairs(diagnostics) do
- assert(diagnostic.lnum, 'Diagnostic line number is required')
- assert(diagnostic.col, 'Diagnostic column is required')
- diagnostic.severity = diagnostic.severity and to_severity(diagnostic.severity)
- or M.severity.ERROR
- diagnostic.end_lnum = diagnostic.end_lnum or diagnostic.lnum
- diagnostic.end_col = diagnostic.end_col or diagnostic.col
- diagnostic.namespace = namespace
- diagnostic.bufnr = bufnr
+ norm_diag(bufnr, namespace, diagnostic)
end
diagnostic_cache[bufnr][namespace] = diagnostics
end
@@ -689,6 +736,7 @@ local function restore_extmarks(bufnr, last)
for _, extmark in ipairs(extmarks) do
if not found[extmark[1]] then
local opts = extmark[4]
+ --- @diagnostic disable-next-line: inject-field
opts.id = extmark[1]
pcall(api.nvim_buf_set_extmark, bufnr, ns, extmark[2], extmark[3], opts)
end
@@ -764,7 +812,7 @@ local insert_leave_auto_cmds = { 'InsertLeave', 'CursorHoldI' }
--- @param namespace integer
--- @param bufnr integer
---- @param args any[]
+--- @param args vim.diagnostic.OptsResolved
local function schedule_display(namespace, bufnr, args)
bufs_waiting_to_update[bufnr][namespace] = args
@@ -809,6 +857,7 @@ local function get_diagnostics(bufnr, opts, clamp)
---@cast namespace integer[]
+ --- @type vim.Diagnostic[]
local diagnostics = {}
-- Memoized results of buf_line_count per bufnr
@@ -860,7 +909,7 @@ local function get_diagnostics(bufnr, opts, clamp)
then
d = vim.deepcopy(d, true)
d.lnum = math.max(math.min(d.lnum, line_count), 0)
- d.end_lnum = math.max(math.min(assert(d.end_lnum), line_count), 0)
+ d.end_lnum = math.max(math.min(d.end_lnum, line_count), 0)
d.col = math.max(d.col, 0)
d.end_col = math.max(d.end_col, 0)
end
@@ -877,13 +926,13 @@ local function get_diagnostics(bufnr, opts, clamp)
end
end
- if namespace == nil and bufnr == nil then
- for b, t in pairs(diagnostic_cache) do
- for _, v in pairs(t) do
- add_all_diags(b, v)
+ if not namespace and not bufnr then
+ for buf, ns_diags in pairs(diagnostic_cache) do
+ for _, diags in pairs(ns_diags) do
+ add_all_diags(buf, diags)
end
end
- elseif namespace == nil then
+ elseif not namespace then
bufnr = vim._resolve_bufnr(bufnr)
for iter_namespace in pairs(diagnostic_cache[bufnr]) do
add_all_diags(bufnr, diagnostic_cache[bufnr][iter_namespace])
@@ -981,6 +1030,7 @@ end
--- @return vim.Diagnostic?
local function next_diagnostic(search_forward, opts)
opts = opts or {}
+ --- @cast opts vim.diagnostic.JumpOpts1
-- Support deprecated win_id alias
if opts.win_id then
@@ -1069,6 +1119,7 @@ local function goto_diagnostic(diagnostic, opts)
end
opts = opts or {}
+ --- @cast opts vim.diagnostic.JumpOpts1
-- Support deprecated win_id alias
if opts.win_id then
@@ -1089,7 +1140,7 @@ local function goto_diagnostic(diagnostic, opts)
if opts.float then
vim.deprecate('opts.float', 'opts.on_jump', '0.14')
- local float_opts = opts.float ---@type table|boolean
+ local float_opts = opts.float
float_opts = type(float_opts) == 'table' and float_opts or {}
opts.on_jump = function(_, bufnr)
@@ -1154,10 +1205,11 @@ function M.config(opts, namespace)
return vim.deepcopy(t, true)
end
- if opts.jump and opts.jump.float ~= nil then ---@diagnostic disable-line
+ local jump_opts = opts.jump --[[@as vim.diagnostic.JumpOpts1]]
+ if jump_opts and jump_opts.float ~= nil then ---@diagnostic disable-line
vim.deprecate('opts.jump.float', 'opts.jump.on_jump', '0.14')
- local float_opts = opts.jump.float ---@type table|boolean
+ local float_opts = jump_opts.float
if float_opts then
float_opts = type(float_opts) == 'table' and float_opts or {}
@@ -1198,7 +1250,7 @@ end
---
---@param namespace integer The diagnostic namespace
---@param bufnr integer Buffer number
----@param diagnostics vim.Diagnostic[]
+---@param diagnostics vim.Diagnostic.Set[]
---@param opts? vim.diagnostic.Opts Display options to pass to |vim.diagnostic.show()|
function M.set(namespace, bufnr, diagnostics, opts)
vim.validate('namespace', namespace, 'number')
@@ -1220,7 +1272,7 @@ function M.set(namespace, bufnr, diagnostics, opts)
modeline = false,
buffer = bufnr,
-- TODO(lewis6991): should this be deepcopy()'d like they are in vim.diagnostic.get()
- data = { diagnostics = diagnostics },
+ data = { diagnostics = diagnostic_cache[bufnr][namespace] },
})
end
@@ -1287,9 +1339,8 @@ function M.count(bufnr, opts)
local diagnostics = get_diagnostics(bufnr, opts, false)
local count = {} --- @type table<integer,integer>
- for i = 1, #diagnostics do
- local severity = diagnostics[i].severity --[[@as integer]]
- count[severity] = (count[severity] or 0) + 1
+ for _, d in ipairs(diagnostics) do
+ count[d.severity] = (count[d.severity] or 0) + 1
end
return count
end
@@ -1415,6 +1466,12 @@ end
--- (default: `0`)
--- @field winid? integer
+--- @nodoc
+--- @class vim.diagnostic.JumpOpts1 : vim.diagnostic.JumpOpts
+--- @field win_id? integer (deprecated) use winid
+--- @field cursor_position? [integer, integer] (deprecated) use pos
+--- @field float? table|boolean (deprecated) use on_jump
+
--- Move to a diagnostic.
---
--- @param opts vim.diagnostic.JumpOpts
@@ -1430,6 +1487,7 @@ function M.jump(opts)
-- Apply configuration options from vim.diagnostic.config()
opts = vim.tbl_deep_extend('keep', opts, global_diagnostic_options.jump)
+ --- @cast opts vim.diagnostic.JumpOpts1
if opts.diagnostic then
goto_diagnostic(opts.diagnostic, opts)
@@ -1511,7 +1569,7 @@ M.handlers.signs = {
if opts.signs.text and opts.signs.text[k] then
text[k] = opts.signs.text[k]
elseif type(k) == 'string' and not text[k] then
- text[k] = string.sub(k, 1, 1):upper()
+ text[k] = k:sub(1, 1):upper()
end
end
@@ -1567,9 +1625,7 @@ M.handlers.underline = {
local get_priority = severity_to_extmark_priority(vim.hl.priorities.diagnostics, opts)
for _, diagnostic in ipairs(diagnostics) do
- -- Default to error if we don't have a highlight associated
- local higroup = underline_highlight_map[assert(diagnostic.severity)]
- or underline_highlight_map[vim.diagnostic.severity.ERROR]
+ local higroup = underline_highlight_map[diagnostic.severity]
if diagnostic._tags then
-- TODO(lewis6991): we should be able to stack these.
@@ -1749,7 +1805,8 @@ local function render_virtual_lines(namespace, bufnr, diagnostics)
-- This loop reads each line, putting them into stacks with some extra data since
-- rendering each line requires understanding what is beneath it.
local ElementType = { Space = 1, Diagnostic = 2, Overlap = 3, Blank = 4 } ---@enum ElementType
- local line_stacks = {} ---@type table<integer, {[1]:ElementType, [2]:string|vim.diagnostic.Severity|vim.Diagnostic}[]>
+ ---@type table<integer, [ElementType, string|vim.diagnostic.Severity|vim.Diagnostic][]>
+ local line_stacks = {}
local prev_lnum = -1
local prev_col = 0
for _, diag in ipairs(diagnostics) do
@@ -1802,7 +1859,7 @@ local function render_virtual_lines(namespace, bufnr, diagnostics)
for i = #stack, 1, -1 do
if stack[i][1] == ElementType.Diagnostic then
local diagnostic = stack[i][2]
- local left = {} ---@type {[1]:string, [2]:string}
+ local left = {} ---@type [string, string]
local overlap = false
local multi = false
@@ -2124,13 +2181,13 @@ function M.show(namespace, bufnr, diagnostics, opts)
clear_scheduled_display(namespace, bufnr)
else
local mode = api.nvim_get_mode()
- if string.sub(mode.mode, 1, 1) == 'i' then
+ if mode.mode:sub(1, 1) == 'i' then
schedule_display(namespace, bufnr, opts_res)
return
end
end
- if if_nil(opts_res.severity_sort, false) then
+ if opts_res.severity_sort then
if type(opts_res.severity_sort) == 'table' and opts_res.severity_sort.reverse then
table.sort(diagnostics, function(a, b)
return a.severity < b.severity
@@ -2237,19 +2294,19 @@ function M.open_float(opts, ...)
end
local lines = {} --- @type string[]
- local highlights = {} --- @type table[]
+ local highlights = {} --- @type { hlname: string, prefix?: { length: integer, hlname: string? }, suffix?: { length: integer, hlname: string? } }[]
local header = if_nil(opts.header, 'Diagnostics:')
if header then
vim.validate('header', header, { 'string', 'table' }, "'string' or 'table'")
if type(header) == 'table' then
-- Don't insert any lines for an empty string
- if string.len(if_nil(header[1], '')) > 0 then
- table.insert(lines, header[1])
- table.insert(highlights, { hlname = header[2] or 'Bold' })
+ if #(header[1] or '') > 0 then
+ lines[#lines + 1] = header[1]
+ highlights[#highlights + 1] = { hlname = header[2] or 'Bold' }
end
elseif #header > 0 then
- table.insert(lines, header)
- table.insert(highlights, { hlname = 'Bold' })
+ lines[#lines + 1] = header
+ highlights[#highlights + 1] = { hlname = 'Bold' }
end
end
@@ -2261,10 +2318,11 @@ function M.open_float(opts, ...)
diagnostics = prefix_source(diagnostics)
end
- local prefix_opt =
- if_nil(opts.prefix, (scope == 'cursor' and #diagnostics <= 1) and '' or function(_, i)
+ local prefix_opt = opts.prefix
+ or (scope == 'cursor' and #diagnostics <= 1) and ''
+ or function(_, i)
return string.format('%d. ', i)
- end)
+ end
local prefix, prefix_hl_group --- @type string?, string?
if prefix_opt then
@@ -2281,9 +2339,10 @@ function M.open_float(opts, ...)
end
end
- local suffix_opt = if_nil(opts.suffix, function(diagnostic)
- return diagnostic.code and string.format(' [%s]', diagnostic.code) or ''
- end)
+ local suffix_opt = opts.suffix
+ or function(diagnostic)
+ return diagnostic.code and string.format(' [%s]', diagnostic.code) or ''
+ end
local suffix, suffix_hl_group --- @type string?, string?
if suffix_opt then
@@ -2311,14 +2370,13 @@ function M.open_float(opts, ...)
local suffix0, suffix_hl_group0 = suffix_opt(diagnostic, i, #diagnostics)
suffix, suffix_hl_group = suffix0 or '', suffix_hl_group0 or 'NormalFloat'
end
- --- @type string?
- local hiname = floating_highlight_map[assert(diagnostic.severity)]
+ local hiname = floating_highlight_map[diagnostic.severity]
local message_lines = vim.split(diagnostic.message, '\n')
for j = 1, #message_lines do
local pre = j == 1 and prefix or string.rep(' ', #prefix)
local suf = j == #message_lines and suffix or ''
- table.insert(lines, pre .. message_lines[j] .. suf)
- table.insert(highlights, {
+ lines[#lines + 1] = pre .. message_lines[j] .. suf
+ highlights[#highlights + 1] = {
hlname = hiname,
prefix = {
length = j == 1 and #prefix or 0,
@@ -2328,7 +2386,7 @@ function M.open_float(opts, ...)
length = j == #message_lines and #suffix or 0,
hlname = suffix_hl_group,
},
- })
+ }
end
end
@@ -2479,6 +2537,7 @@ function M.enable(enable, filter)
if not bufnr then
if not ns_id then
+ --- @type table<integer,true|table<integer,true>>
diagnostic_disabled = (
enable
-- Enable everything by setting diagnostic_disabled to an empty table.
@@ -2503,9 +2562,8 @@ function M.enable(enable, filter)
if type(diagnostic_disabled[bufnr]) ~= 'table' then
if enable then
return
- else
- diagnostic_disabled[bufnr] = {}
end
+ diagnostic_disabled[bufnr] = {}
end
diagnostic_disabled[bufnr][ns_id] = (not enable) and true or nil
end
@@ -2560,7 +2618,7 @@ function M.match(str, pat, groups, severity_map, defaults)
return
end
- local diagnostic = {} --- @type type<string,any>
+ local diagnostic = {}
for i, match in ipairs(matches) do
local field = groups[i]
diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua
@@ -80,13 +80,13 @@ end
---@param diagnostics lsp.Diagnostic[]
---@param bufnr integer
---@param client_id integer
----@return vim.Diagnostic[]
+---@return vim.Diagnostic.Set[]
local function diagnostic_lsp_to_vim(diagnostics, bufnr, client_id)
local buf_lines = get_buf_lines(bufnr)
local client = vim.lsp.get_client_by_id(client_id)
local position_encoding = client and client.offset_encoding or 'utf-16'
--- @param diagnostic lsp.Diagnostic
- --- @return vim.Diagnostic
+ --- @return vim.Diagnostic.Set
return vim.tbl_map(function(diagnostic)
local start = diagnostic.range.start
local _end = diagnostic.range['end']
@@ -104,7 +104,7 @@ local function diagnostic_lsp_to_vim(diagnostics, bufnr, client_id)
if _end.line > start.line then
end_line = buf_lines and buf_lines[_end.line + 1] or ''
end
- --- @type vim.Diagnostic
+ --- @type vim.Diagnostic.Set
return {
lnum = start.line,
col = vim.str_byteindex(line, position_encoding, start.character, false),
diff --git a/runtime/lua/vim/treesitter/_query_linter.lua b/runtime/lua/vim/treesitter/_query_linter.lua
@@ -17,7 +17,7 @@ local M = {}
--- @field is_first_lang boolean Whether this is the first language of a linter run checking queries for multiple `langs`
--- Adds a diagnostic for node in the query buffer
---- @param diagnostics vim.Diagnostic[]
+--- @param diagnostics vim.Diagnostic.Set[]
--- @param range Range4
--- @param lint string
--- @param lang string?
@@ -126,7 +126,7 @@ end)
--- @param match table<integer,TSNode[]>
--- @param query vim.treesitter.Query
--- @param lang_context QueryLinterLanguageContext
---- @param diagnostics vim.Diagnostic[]
+--- @param diagnostics vim.Diagnostic.Set[]
local function lint_match(buf, match, query, lang_context, diagnostics)
local lang = lang_context.lang
local parser_info = lang_context.parser_info
@@ -162,7 +162,7 @@ function M.lint(buf, opts)
buf = api.nvim_get_current_buf()
end
- local diagnostics = {}
+ local diagnostics = {} --- @type vim.Diagnostic.Set[]
local query = vim.treesitter.query.parse('query', lint_query)
opts = normalize_opts(buf, opts)