From 8122470f8310ae34bcd5e436e8474f9255eb16f2 Mon Sep 17 00:00:00 2001 From: Raphael Date: Wed, 13 Dec 2023 22:19:53 +0800 Subject: refactor(diagnostic): set sign by using extmark (#26193) after sign implementation refactor by using extmark, we can use `nvim_buf_set_extmark` to set diagnostic sign instead use `sign_define` --- runtime/lua/vim/diagnostic.lua | 61 +++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 34 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 99448982b4..729156584f 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -221,30 +221,6 @@ local underline_highlight_map = make_highlight_map('Underline') local floating_highlight_map = make_highlight_map('Floating') local sign_highlight_map = make_highlight_map('Sign') ----@private -local define_default_signs = (function() - local signs_defined = false - return function() - if signs_defined then - return - end - - for severity, sign_hl_name in pairs(sign_highlight_map) do - if vim.tbl_isempty(vim.fn.sign_getdefined(sign_hl_name)) then - local severity_name = M.severity[severity] - vim.fn.sign_define(sign_hl_name, { - text = (severity_name or 'U'):sub(1, 1), - texthl = sign_hl_name, - linehl = '', - numhl = '', - }) - end - end - - signs_defined = true - end -end)() - local function get_bufnr(bufnr) if not bufnr or bufnr == 0 then return api.nvim_get_current_buf() @@ -618,6 +594,14 @@ end --- * priority: (number, default 10) Base priority to use for signs. When --- {severity_sort} is used, the priority of a sign is adjusted based on --- its severity. Otherwise, all signs use the same priority. +--- * text: (table) A table mapping |diagnostic-severity| to the sign text +--- to display in the sign column. The default is to use "E", "W", "I", and "H" +--- for errors, warnings, information, and hints, respectively. Example: +---
lua
+---                     vim.diagnostic.config({
+---                       sign = { text = { [vim.diagnostic.severity.ERROR] = 'E', ... } }
+---                     })
+---                   
--- - float: Options for floating windows. See |vim.diagnostic.open_float()|. --- - update_in_insert: (default false) Update diagnostics in Insert mode (if false, --- diagnostics are updated on InsertLeave) @@ -868,8 +852,6 @@ M.handlers.signs = { diagnostics = filter_by_severity(opts.signs.severity, diagnostics) end - define_default_signs() - -- 10 is the default sign priority when none is explicitly specified local priority = opts.signs and opts.signs.priority or 10 local get_priority @@ -890,22 +872,33 @@ M.handlers.signs = { end local ns = M.get_namespace(namespace) - if not ns.user_data.sign_group then - ns.user_data.sign_group = string.format('vim.diagnostic.%s', ns.name) + if not ns.user_data.sign_ns then + ns.user_data.sign_ns = api.nvim_create_namespace('') + end + + local text = {} + for k in pairs(M.severity) do + 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() + end end - local sign_group = ns.user_data.sign_group for _, diagnostic in ipairs(diagnostics) do - vim.fn.sign_place(0, sign_group, sign_highlight_map[diagnostic.severity], bufnr, { - priority = get_priority(diagnostic.severity), - lnum = diagnostic.lnum + 1, - }) + if api.nvim_buf_is_loaded(diagnostic.bufnr) then + api.nvim_buf_set_extmark(bufnr, ns.user_data.sign_ns, diagnostic.lnum, 0, { + sign_text = text[diagnostic.severity] or text[M.severity[diagnostic.severity]] or 'U', + sign_hl_group = sign_highlight_map[diagnostic.severity], + priority = get_priority(diagnostic.severity), + }) + end end end, hide = function(namespace, bufnr) local ns = M.get_namespace(namespace) if ns.user_data.sign_group and api.nvim_buf_is_valid(bufnr) then - vim.fn.sign_unplace(ns.user_data.sign_group, { buffer = bufnr }) + api.nvim_buf_clear_namespace(bufnr, ns.user_data.sign_ns, 0, -1) end end, } -- cgit From 29d5ff6ac4eade7996d14eec60a31ec6328a165d Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Wed, 13 Dec 2023 09:26:39 -0600 Subject: fix(diagnostic): check for sign namespace instead of sign group --- runtime/lua/vim/diagnostic.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 729156584f..d6db530bb0 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -897,7 +897,7 @@ M.handlers.signs = { end, hide = function(namespace, bufnr) local ns = M.get_namespace(namespace) - if ns.user_data.sign_group and api.nvim_buf_is_valid(bufnr) then + if ns.user_data.sign_ns and api.nvim_buf_is_valid(bufnr) then api.nvim_buf_clear_namespace(bufnr, ns.user_data.sign_ns, 0, -1) end end, -- cgit From 39112c72dd3722cd4a0770fc23c9d7269a9c2283 Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Wed, 13 Dec 2023 09:43:27 -0600 Subject: docs(diagnostic): fix typo in example --- runtime/lua/vim/diagnostic.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index d6db530bb0..1d76d1d7a0 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -598,9 +598,9 @@ end --- to display in the sign column. The default is to use "E", "W", "I", and "H" --- for errors, warnings, information, and hints, respectively. Example: ---
lua
----                     vim.diagnostic.config({
----                       sign = { text = { [vim.diagnostic.severity.ERROR] = 'E', ... } }
----                     })
+---                       vim.diagnostic.config({
+---                         signs = { text = { [vim.diagnostic.severity.ERROR] = 'E', ... } }
+---                       })
 ---                   
--- - float: Options for floating windows. See |vim.diagnostic.open_float()|. --- - update_in_insert: (default false) Update diagnostics in Insert mode (if false, -- cgit From a3b39784744f330b922117655811542202fcd85b Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Wed, 13 Dec 2023 09:54:04 -0600 Subject: feat(diagnostics): support numhl and linehl for diagnostic signs --- runtime/lua/vim/diagnostic.lua | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 1d76d1d7a0..0eb1ac7f15 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -602,6 +602,10 @@ end --- signs = { text = { [vim.diagnostic.severity.ERROR] = 'E', ... } } --- }) --- +--- * numhl: (table) A table mapping |diagnostic-severity| to the highlight +--- group used for the line number where the sign is placed. +--- * linehl: (table) A table mapping |diagnostic-severity| to the highlight group +--- used for the whole line the sign is placed in. --- - float: Options for floating windows. See |vim.diagnostic.open_float()|. --- - update_in_insert: (default false) Update diagnostics in Insert mode (if false, --- diagnostics are updated on InsertLeave) @@ -885,11 +889,16 @@ M.handlers.signs = { end end + local numhl = opts.signs.numhl or {} + local linehl = opts.signs.linehl or {} + for _, diagnostic in ipairs(diagnostics) do if api.nvim_buf_is_loaded(diagnostic.bufnr) then api.nvim_buf_set_extmark(bufnr, ns.user_data.sign_ns, diagnostic.lnum, 0, { sign_text = text[diagnostic.severity] or text[M.severity[diagnostic.severity]] or 'U', sign_hl_group = sign_highlight_map[diagnostic.severity], + number_hl_group = numhl[diagnostic.severity], + line_hl_group = linehl[diagnostic.severity], priority = get_priority(diagnostic.severity), }) end -- cgit From ef38fdfdc6c84abd8ce7be02eaf8edc91ebc7917 Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Thu, 14 Dec 2023 09:19:33 -0600 Subject: refactor(diagnostic): use named namespaces (#26568) Anonymous namespaces are more difficult to extend or hook into since they do not appear in the output of nvim_get_namespaces(). Use named namespaces instead. --- runtime/lua/vim/diagnostic.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 0eb1ac7f15..2171ae14e6 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -877,7 +877,8 @@ M.handlers.signs = { local ns = M.get_namespace(namespace) if not ns.user_data.sign_ns then - ns.user_data.sign_ns = api.nvim_create_namespace('') + ns.user_data.sign_ns = + api.nvim_create_namespace(string.format('%s/diagnostic/signs', ns.name)) end local text = {} @@ -938,7 +939,8 @@ M.handlers.underline = { local ns = M.get_namespace(namespace) if not ns.user_data.underline_ns then - ns.user_data.underline_ns = api.nvim_create_namespace('') + ns.user_data.underline_ns = + api.nvim_create_namespace(string.format('%s/diagnostic/underline', ns.name)) end local underline_ns = ns.user_data.underline_ns @@ -1020,7 +1022,8 @@ M.handlers.virtual_text = { local ns = M.get_namespace(namespace) if not ns.user_data.virt_text_ns then - ns.user_data.virt_text_ns = api.nvim_create_namespace('') + ns.user_data.virt_text_ns = + api.nvim_create_namespace(string.format('%s/diagnostic/virtual_text', ns.name)) end local virt_text_ns = ns.user_data.virt_text_ns -- cgit From e164f4c2715c97b48607bb6339eac3aff7106c47 Mon Sep 17 00:00:00 2001 From: Yi Ming Date: Mon, 18 Dec 2023 08:11:47 +0800 Subject: docs(diagnostic): add return value of `vim.diagnostic.config()` (#26615) --- runtime/lua/vim/diagnostic.lua | 2 ++ 1 file changed, 2 insertions(+) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 2171ae14e6..e4f694b8a2 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -617,6 +617,8 @@ end --- ---@param namespace integer|nil Update the options for the given namespace. When omitted, update the --- global diagnostic options. +--- +---@return table|nil table of current diagnostic config if `opts` is omitted. function M.config(opts, namespace) vim.validate({ opts = { opts, 't', true }, -- cgit From 3a4aa3fc58f87a295a075fe457bc78805eef7c4d Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:04:44 -0600 Subject: refactor: soft-deprecate diagnostic signs configured with :sign-define (#26618) Diagnostic signs should now be configured with vim.diagnostic.config(), but "legacy" sign definitions should go through the standard deprecation process to minimize the impact from breaking changes. --- runtime/lua/vim/diagnostic.lua | 49 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index e4f694b8a2..6d2c212dfc 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -588,7 +588,7 @@ end --- return diagnostic.message --- end --- ---- - signs: (default true) Use signs for diagnostics. Options: +--- - signs: (default true) Use signs for diagnostics |diagnostic-signs|. Options: --- * severity: Only show signs for diagnostics matching the given --- severity |diagnostic-severity| --- * priority: (number, default 10) Base priority to use for signs. When @@ -883,7 +883,52 @@ M.handlers.signs = { api.nvim_create_namespace(string.format('%s/diagnostic/signs', ns.name)) end - local text = {} + --- Handle legacy diagnostic sign definitions + --- These were deprecated in 0.10 and will be removed in 0.12 + if opts.signs and not opts.signs.text and not opts.signs.numhl and not opts.signs.texthl then + for _, v in ipairs({ 'Error', 'Warn', 'Info', 'Hint' }) do + local name = string.format('DiagnosticSign%s', v) + local sign = vim.fn.sign_getdefined(name)[1] + if sign then + local severity = M.severity[v:upper()] + if vim.fn.has('nvim-0.11') == 1 then + vim.deprecate( + 'Defining diagnostic signs with :sign-define or sign_define()', + 'vim.diagnostic.config()', + '0.12', + nil, + false + ) + end + + if not opts.signs.text then + opts.signs.text = {} + end + + if not opts.signs.numhl then + opts.signs.numhl = {} + end + + if not opts.signs.linehl then + opts.signs.linehl = {} + end + + if opts.signs.text[severity] == nil then + opts.signs.text[severity] = sign.text or '' + end + + if opts.signs.numhl[severity] == nil then + opts.signs.numhl[severity] = sign.numhl + end + + if opts.signs.linehl[severity] == nil then + opts.signs.linehl[severity] = sign.linehl + end + end + end + end + + local text = {} ---@type table for k in pairs(M.severity) do if opts.signs.text and opts.signs.text[k] then text[k] = opts.signs.text[k] -- cgit From 5f9d4d8afeb5dc3d5df4965c24cbb4c6e01694f7 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 25 Dec 2023 21:28:28 +0100 Subject: refactor: use vim.deprecate on all deprecated functions --- runtime/lua/vim/diagnostic.lua | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 6d2c212dfc..a82a61eeb7 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -891,15 +891,13 @@ M.handlers.signs = { local sign = vim.fn.sign_getdefined(name)[1] if sign then local severity = M.severity[v:upper()] - if vim.fn.has('nvim-0.11') == 1 then - vim.deprecate( - 'Defining diagnostic signs with :sign-define or sign_define()', - 'vim.diagnostic.config()', - '0.12', - nil, - false - ) - end + vim.deprecate( + 'Defining diagnostic signs with :sign-define or sign_define()', + 'vim.diagnostic.config()', + '0.12', + nil, + false + ) if not opts.signs.text then opts.signs.text = {} -- cgit From d51b6157473c4830313b566116aa3ad38dc97412 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Wed, 13 Dec 2023 14:04:24 +0100 Subject: refactor: fix luals warnings --- runtime/lua/vim/diagnostic.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index a82a61eeb7..ad40723737 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -108,6 +108,7 @@ local function filter_by_severity(severity, diagnostics) severities[to_severity(s)] = true end + --- @param t table return vim.tbl_filter(function(t) return severities[t.severity] end, diagnostics) -- cgit From 4ee656e4f35766bef4e27c5afbfa8e3d8d74a76c Mon Sep 17 00:00:00 2001 From: Evgeni Chasnovski Date: Mon, 1 Jan 2024 23:03:50 +0200 Subject: feature(diagnostic): add `vim.diagnostic.count()` (#26807) feat(diagnostic): add `vim.diagnostic.count()` Problem: Getting diagnostic count based on the output of `vim.diagnostic.get()` might become costly as number of diagnostic entries grows. This is because it returns a copy of diagnostic cache entries (so as to not allow users to change them in place). Getting information about diagnostic count is frequently used in statusline, so it is important to be as fast as reasonbly possible. Solution: Add `vim.diagnostic.count()` which computes severity counts without making copies. --- runtime/lua/vim/diagnostic.lua | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index ad40723737..a447463dff 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -363,7 +363,6 @@ local function get_diagnostics(bufnr, opts, clamp) local function add(b, d) if not opts.lnum or d.lnum == opts.lnum then - d = vim.deepcopy(d) if clamp and api.nvim_buf_is_loaded(b) then local line_count = buf_line_count[b] - 1 if @@ -374,6 +373,7 @@ local function get_diagnostics(bufnr, opts, clamp) or d.col < 0 or d.end_col < 0 then + d = vim.deepcopy(d) d.lnum = math.max(math.min(d.lnum, line_count), 0) d.end_lnum = math.max(math.min(d.end_lnum, line_count), 0) d.col = math.max(d.col, 0) @@ -756,7 +756,31 @@ function M.get(bufnr, opts) opts = { opts, 't', true }, }) - return get_diagnostics(bufnr, opts, false) + return vim.deepcopy(get_diagnostics(bufnr, opts, false)) +end + +--- Get current diagnostics count. +--- +---@param bufnr integer|nil Buffer number to get diagnostics from. Use 0 for +--- current buffer or nil for all buffers. +---@param opts table|nil A table with the following keys: +--- - namespace: (number) Limit diagnostics to the given namespace. +--- - lnum: (number) Limit diagnostics to the given line number. +--- - severity: See |diagnostic-severity|. +---@return table A table with actually present severity values as keys (see |diagnostic-severity|) and integer counts as values. +function M.count(bufnr, opts) + vim.validate({ + bufnr = { bufnr, 'n', true }, + opts = { opts, 't', true }, + }) + + local diagnostics = get_diagnostics(bufnr, opts, false) + local count = {} + for i = 1, #diagnostics do + local severity = diagnostics[i].severity + count[severity] = (count[severity] or 0) + 1 + end + return count end --- Get the previous diagnostic closest to the cursor position. -- cgit From 3734519e3b4ba1bf19ca772104170b0ef776be46 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Tue, 2 Jan 2024 15:47:55 +0000 Subject: feat(lua): add noref to deepcopy Problem: Currently `deepcopy` hashes every single tables it copies so it can be reused. For tables of mostly unique items that are non recursive, this hashing is unnecessarily expensive Solution: Port the `noref` argument from Vimscripts `deepcopy()`. The below benchmark demonstrates the results for two extreme cases of tables of different sizes. One table that uses the same table lots of times and one with all unique tables. | test | `noref=false` (ms) | `noref=true` (ms) | | -------------------- | ------------------ | ----------------- | | unique tables (50) | 6.59 | 2.62 | | shared tables (50) | 3.24 | 6.40 | | unique tables (2000) | 23381.48 | 2884.53 | | shared tables (2000) | 3505.54 | 14038.80 | The results are basically the inverse of each other where `noref` is much more performance on tables with unique fields, and `not noref` is more performant on tables that reuse fields. --- runtime/lua/vim/diagnostic.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index a447463dff..897837a5ce 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -134,7 +134,7 @@ local function prefix_source(diagnostics) return d end - local t = vim.deepcopy(d) + local t = vim.deepcopy(d, true) t.message = string.format('%s: %s', d.source, d.message) return t end, diagnostics) @@ -146,7 +146,7 @@ local function reformat_diagnostics(format, diagnostics) diagnostics = { diagnostics, 't' }, }) - local formatted = vim.deepcopy(diagnostics) + local formatted = vim.deepcopy(diagnostics, true) for _, diagnostic in ipairs(formatted) do diagnostic.message = format(diagnostic) end @@ -373,7 +373,7 @@ local function get_diagnostics(bufnr, opts, clamp) or d.col < 0 or d.end_col < 0 then - d = vim.deepcopy(d) + d = vim.deepcopy(d, true) d.lnum = math.max(math.min(d.lnum, line_count), 0) d.end_lnum = math.max(math.min(d.end_lnum, line_count), 0) d.col = math.max(d.col, 0) @@ -636,7 +636,7 @@ function M.config(opts, namespace) if not opts then -- Return current config - return vim.deepcopy(t) + return vim.deepcopy(t, true) end for k, v in pairs(opts) do @@ -723,7 +723,7 @@ end --- ---@return table A list of active diagnostic namespaces |vim.diagnostic|. function M.get_namespaces() - return vim.deepcopy(all_namespaces) + return vim.deepcopy(all_namespaces, true) end ---@class Diagnostic @@ -756,7 +756,7 @@ function M.get(bufnr, opts) opts = { opts, 't', true }, }) - return vim.deepcopy(get_diagnostics(bufnr, opts, false)) + return vim.deepcopy(get_diagnostics(bufnr, opts, false), true) end --- Get current diagnostics count. -- cgit From 50284d07b6f020c819aeb07bfb30d88453e63b6d Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Tue, 9 Jan 2024 12:47:57 +0000 Subject: fix(diagnostic): typing --- runtime/lua/vim/diagnostic.lua | 521 +++++++++++++++++++++++++++++------------ 1 file changed, 365 insertions(+), 156 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 897837a5ce..c7a1e8ebd3 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -2,15 +2,87 @@ local api, if_nil = vim.api, vim.F.if_nil local M = {} ----@enum DiagnosticSeverity +--- @class vim.Diagnostic +--- @field bufnr? integer +--- @field lnum integer 0-indexed +--- @field end_lnum? integer 0-indexed +--- @field col integer 0-indexed +--- @field end_col? integer 0-indexed +--- @field severity? vim.diagnostic.Severity +--- @field message string +--- @field source? string +--- @field code? string +--- @field _tags? { deprecated: boolean, unnecessary: boolean} +--- @field user_data? any arbitrary data plugins can add +--- @field namespace? integer + +--- @class vim.diagnostic.Opts +--- @field float? boolean|vim.diagnostic.Opts.Float +--- @field update_in_insert? boolean +--- @field underline? boolean|vim.diagnostic.Opts.Underline +--- @field virtual_text? boolean|vim.diagnostic.Opts.VirtualText +--- @field signs? boolean|vim.diagnostic.Opts.Signs +--- @field severity_sort? boolean|{reverse?:boolean} + +--- @class vim.diagnostic.OptsResolved +--- @field float vim.diagnostic.Opts.Float +--- @field update_in_insert boolean +--- @field underline vim.diagnostic.Opts.Underline +--- @field virtual_text vim.diagnostic.Opts.VirtualText +--- @field signs vim.diagnostic.Opts.Signs +--- @field severity_sort {reverse?:boolean} + +--- @class vim.diagnostic.Opts.Float +--- @field bufnr? integer +--- @field namespace? integer +--- @field scope? 'line'|'buffer'|'cursor'|'c'|'l'|'b' +--- @field pos? integer|{[1]:integer,[2]:integer} +--- @field severity_sort? boolean|{reverse?:boolean} +--- @field severity? vim.diagnostic.Severity +--- @field header? string|{[1]:string,[2]:any} +--- @field source? boolean|string +--- @field format? fun(diagnostic:vim.Diagnostic): string +--- @field prefix? string|table|(fun(diagnostic:vim.Diagnostic,i:integer,total:integer): string, string) +--- @field suffix? string|table|(fun(diagnostic:vim.Diagnostic,i:integer,total:integer): string, string) +--- @field focus_id? string + +--- @class vim.diagnostic.Opts.Underline +--- @field severity? vim.diagnostic.Severity + +--- @class vim.diagnostic.Opts.VirtualText +--- @field severity? vim.diagnostic.Severity +--- @field source? boolean|string +--- @field prefix? string|function +--- @field suffix? string|function +--- @field spacing? integer +--- @field format? function +--- @field hl_mode? 'replace'|'combine'|'blend' +--- @field virt_text? {[1]:string,[2]:any}[] +--- @field virt_text_pos? 'eol'|'overlay'|'right_align'|'inline' +--- @field virt_text_win_col? integer +--- @field virt_text_hide? boolean + +--- @class vim.diagnostic.Opts.Signs +--- @field severity? vim.diagnostic.Severity +--- @field priority? integer +--- @field text? table +--- @field numhl? table +--- @field linehl? table +--- @field texthl? table + +--- @enum vim.diagnostic.Severity M.severity = { ERROR = 1, WARN = 2, INFO = 3, HINT = 4, + [1] = 'ERROR', + [2] = 'WARN', + [3] = 'INFO', + [4] = 'HINT', } -vim.tbl_add_reverse_lookup(M.severity) +--- @alias vim.diagnostic.SeverityInt 1|2|3|4 -- Mappings from qflist/loclist error types to severities M.severity.E = M.severity.ERROR @@ -18,6 +90,7 @@ M.severity.W = M.severity.WARN M.severity.I = M.severity.INFO M.severity.N = M.severity.HINT +--- @type vim.diagnostic.Opts local global_diagnostic_options = { signs = true, underline = true, @@ -27,6 +100,11 @@ local global_diagnostic_options = { severity_sort = false, } +--- @class vim.diagnostic.Handler +--- @field show? fun(namespace: integer, bufnr: integer, diagnostics: vim.Diagnostic[], opts?: vim.diagnostic.OptsResolved) +--- @field hide? fun(namespace:integer, bufnr:integer) + +--- @type table M.handlers = setmetatable({}, { __newindex = function(t, name, handler) vim.validate({ handler = { handler, 't' } }) @@ -39,6 +117,9 @@ M.handlers = setmetatable({}, { -- Metatable that automatically creates an empty table when assigning to a missing key local bufnr_and_namespace_cacher_mt = { + --- @param t table + --- @param bufnr integer + --- @return table __index = function(t, bufnr) assert(bufnr > 0, 'Invalid buffer number') t[bufnr] = {} @@ -46,10 +127,13 @@ local bufnr_and_namespace_cacher_mt = { end, } -local diagnostic_cache +-- bufnr -> ns -> Diagnostic[] +local diagnostic_cache = {} --- @type table> do local group = api.nvim_create_augroup('DiagnosticBufWipeout', {}) - diagnostic_cache = setmetatable({}, { + setmetatable(diagnostic_cache, { + --- @param t table + --- @param bufnr integer __index = function(t, bufnr) assert(bufnr > 0, 'Invalid buffer number') api.nvim_create_autocmd('BufWipeout', { @@ -65,13 +149,35 @@ do }) end +--- @class vim.diagnostic._extmark +--- @field [1] integer id +--- @field [2] integer start +--- @field [3] integer end +--- @field [4] table details + +--- @type table> local diagnostic_cache_extmarks = setmetatable({}, bufnr_and_namespace_cacher_mt) + +--- @type table local diagnostic_attached_buffers = {} + +--- @type table> local diagnostic_disabled = {} + +--- @type table> local bufs_waiting_to_update = setmetatable({}, bufnr_and_namespace_cacher_mt) +--- @class vim.diagnostic.NS +--- @field name string +--- @field opts vim.diagnostic.Opts +--- @field user_data table +--- @field disabled? boolean + +--- @type table local all_namespaces = {} +---@param severity string|vim.diagnostic.Severity +---@return vim.diagnostic.Severity? local function to_severity(severity) if type(severity) == 'string' then return assert( @@ -82,45 +188,56 @@ local function to_severity(severity) return severity end +--- @param severity vim.diagnostic.Severity|vim.diagnostic.Severity[]|{min:vim.diagnostic.Severity,max:vim.diagnostic.Severity} +--- @param diagnostics vim.Diagnostic[] +--- @return vim.Diagnostic[] local function filter_by_severity(severity, diagnostics) if not severity then return diagnostics end if type(severity) ~= 'table' then - severity = to_severity(severity) + severity = assert(to_severity(severity)) + --- @param t vim.Diagnostic return vim.tbl_filter(function(t) return t.severity == severity end, diagnostics) end 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 local max_severity = to_severity(severity.max) or M.severity.ERROR + --- @param t vim.Diagnostic return vim.tbl_filter(function(t) return t.severity <= min_severity and t.severity >= max_severity end, diagnostics) end - local severities = {} + --- @cast severity vim.diagnostic.Severity[] + + local severities = {} --- @type table for _, s in ipairs(severity) do - severities[to_severity(s)] = true + severities[assert(to_severity(s))] = true end - --- @param t table + --- @param t vim.Diagnostic return vim.tbl_filter(function(t) return severities[t.severity] end, diagnostics) end +--- @param bufnr integer +--- @return integer local function count_sources(bufnr) - local seen = {} + local seen = {} --- @type table local count = 0 for _, namespace_diagnostics in pairs(diagnostic_cache[bufnr]) do for _, diagnostic in ipairs(namespace_diagnostics) do - if diagnostic.source and not seen[diagnostic.source] then - seen[diagnostic.source] = true + local source = diagnostic.source + if source and not seen[source] then + seen[source] = true count = count + 1 end end @@ -128,7 +245,10 @@ local function count_sources(bufnr) return count end +--- @param diagnostics vim.Diagnostic[] +--- @return vim.Diagnostic[] local function prefix_source(diagnostics) + --- @param d vim.Diagnostic return vim.tbl_map(function(d) if not d.source then return d @@ -140,6 +260,8 @@ local function prefix_source(diagnostics) end, diagnostics) end +--- @param diagnostics vim.Diagnostic[] +--- @return vim.Diagnostic[] local function reformat_diagnostics(format, diagnostics) vim.validate({ format = { format, 'f' }, @@ -153,26 +275,35 @@ local function reformat_diagnostics(format, diagnostics) return formatted end +--- @param option string +--- @param namespace integer? +--- @return table local function enabled_value(option, namespace) local ns = namespace and M.get_namespace(namespace) or {} if ns.opts and type(ns.opts[option]) == 'table' then return ns.opts[option] end - if type(global_diagnostic_options[option]) == 'table' then - return global_diagnostic_options[option] + local global_opt = global_diagnostic_options[option] + if type(global_opt) == 'table' then + return global_opt end return {} end +--- @param option string +--- @param value any? +--- @param namespace integer? +--- @param bufnr integer +--- @return any local function resolve_optional_value(option, value, namespace, bufnr) if not value then return false elseif value == true then return enabled_value(option, namespace) elseif type(value) == 'function' then - local val = value(namespace, bufnr) + local val = value(namespace, bufnr) --- @type any if val == true then return enabled_value(option, namespace) else @@ -180,15 +311,18 @@ local function resolve_optional_value(option, value, namespace, bufnr) end elseif type(value) == 'table' then return value - else - error('Unexpected option type: ' .. vim.inspect(value)) end + error('Unexpected option type: ' .. vim.inspect(value)) end +--- @param opts vim.diagnostic.Opts? +--- @param namespace integer? +--- @param bufnr integer +--- @return vim.diagnostic.OptsResolved local function get_resolved_options(opts, namespace, bufnr) local ns = namespace and M.get_namespace(namespace) or {} -- Do not use tbl_deep_extend so that an empty table can be used to reset to default values - local resolved = vim.tbl_extend('keep', opts or {}, ns.opts or {}, global_diagnostic_options) + local resolved = vim.tbl_extend('keep', opts or {}, ns.opts or {}, global_diagnostic_options) --- @type table for k in pairs(global_diagnostic_options) do if resolved[k] ~= nil then resolved[k] = resolve_optional_value(k, resolved[k], namespace, bufnr) @@ -205,9 +339,11 @@ local diagnostic_severities = { [M.severity.HINT] = { ctermfg = 7, guifg = 'LightGrey' }, } --- Make a map from DiagnosticSeverity -> Highlight Name +--- Make a map from vim.diagnostic.Severity -> Highlight Name +--- @param base_name string +--- @return table local function make_highlight_map(base_name) - local result = {} + local result = {} --- @type table for k in pairs(diagnostic_severities) do local name = M.severity[k] name = name:sub(1, 1) .. name:sub(2):lower() @@ -217,6 +353,8 @@ local function make_highlight_map(base_name) 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 underline_highlight_map = make_highlight_map('Underline') local floating_highlight_map = make_highlight_map('Floating') @@ -229,12 +367,14 @@ local function get_bufnr(bufnr) return bufnr end +--- @param diagnostics vim.Diagnostic[] +--- @return table local function diagnostic_lines(diagnostics) if not diagnostics then return {} end - local diagnostics_by_line = {} + local diagnostics_by_line = {} --- @type table for _, diagnostic in ipairs(diagnostics) do local line_diagnostics = diagnostics_by_line[diagnostic.lnum] if not line_diagnostics then @@ -246,6 +386,9 @@ local function diagnostic_lines(diagnostics) return diagnostics_by_line end +--- @param namespace integer +--- @param bufnr integer +--- @param diagnostics vim.Diagnostic[] local function set_diagnostic_cache(namespace, bufnr, diagnostics) for _, diagnostic in ipairs(diagnostics) do assert(diagnostic.lnum, 'Diagnostic line number is required') @@ -260,10 +403,12 @@ local function set_diagnostic_cache(namespace, bufnr, diagnostics) diagnostic_cache[bufnr][namespace] = diagnostics end +--- @param bufnr integer +--- @param last integer local function restore_extmarks(bufnr, last) for ns, extmarks in pairs(diagnostic_cache_extmarks[bufnr]) do local extmarks_current = api.nvim_buf_get_extmarks(bufnr, ns, 0, -1, { details = true }) - local found = {} + local found = {} --- @type table for _, extmark in ipairs(extmarks_current) do -- nvim_buf_set_lines will move any extmark to the line after the last -- nvim_buf_set_text will move any extmark to the last line @@ -281,6 +426,8 @@ local function restore_extmarks(bufnr, last) end end +--- @param namespace integer +--- @param bufnr? integer local function save_extmarks(namespace, bufnr) bufnr = get_bufnr(bufnr) if not diagnostic_attached_buffers[bufnr] then @@ -298,6 +445,7 @@ local function save_extmarks(namespace, bufnr) api.nvim_buf_get_extmarks(bufnr, namespace, 0, -1, { details = true }) end +--- @type table local registered_autocmds = {} local function make_augroup_key(namespace, bufnr) @@ -305,6 +453,8 @@ local function make_augroup_key(namespace, bufnr) return string.format('DiagnosticInsertLeave:%s:%s', bufnr, ns.name) end +--- @param namespace integer +--- @param bufnr integer local function execute_scheduled_display(namespace, bufnr) local args = bufs_waiting_to_update[bufnr][namespace] if not args then @@ -320,6 +470,9 @@ end --- Table of autocmd events to fire the update for displaying new diagnostic information local insert_leave_auto_cmds = { 'InsertLeave', 'CursorHoldI' } +--- @param namespace integer +--- @param bufnr integer +--- @param args any[] local function schedule_display(namespace, bufnr, args) bufs_waiting_to_update[bufnr][namespace] = args @@ -338,6 +491,8 @@ local function schedule_display(namespace, bufnr, args) end end +--- @param namespace integer +--- @param bufnr integer local function clear_scheduled_display(namespace, bufnr) local key = make_augroup_key(namespace, bufnr) @@ -347,6 +502,10 @@ local function clear_scheduled_display(namespace, bufnr) end end +--- @param bufnr integer? +--- @param opts vim.diagnostic.GetOpts? +--- @param clamp boolean +--- @return vim.Diagnostic[] local function get_diagnostics(bufnr, opts, clamp) opts = opts or {} @@ -354,13 +513,19 @@ local function get_diagnostics(bufnr, opts, clamp) local diagnostics = {} -- Memoized results of buf_line_count per bufnr + --- @type table local buf_line_count = setmetatable({}, { + --- @param t table + --- @param k integer + --- @return integer __index = function(t, k) t[k] = api.nvim_buf_line_count(k) return rawget(t, k) end, }) + ---@param b integer + ---@param d vim.Diagnostic local function add(b, d) if not opts.lnum or d.lnum == opts.lnum then if clamp and api.nvim_buf_is_loaded(b) then @@ -375,7 +540,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(d.end_lnum, line_count), 0) + d.end_lnum = math.max(math.min(assert(d.end_lnum), line_count), 0) d.col = math.max(d.col, 0) d.end_col = math.max(d.end_col, 0) end @@ -384,6 +549,8 @@ local function get_diagnostics(bufnr, opts, clamp) end end + --- @param buf integer + --- @param diags vim.Diagnostic[] local function add_all_diags(buf, diags) for _, diagnostic in pairs(diags) do add(buf, diagnostic) @@ -417,18 +584,20 @@ local function get_diagnostics(bufnr, opts, clamp) return diagnostics end +--- @param loclist boolean +--- @param opts vim.diagnostic.setqflist.Opts|vim.diagnostic.setloclist.Opts? local function set_list(loclist, opts) opts = opts or {} - local open = vim.F.if_nil(opts.open, true) + local open = if_nil(opts.open, true) local title = opts.title or 'Diagnostics' local winnr = opts.winnr or 0 - local bufnr + local bufnr --- @type integer? if loclist then bufnr = api.nvim_win_get_buf(winnr) end -- Don't clamp line numbers since the quickfix list can already handle line -- numbers beyond the end of the buffer - local diagnostics = get_diagnostics(bufnr, opts, false) + local diagnostics = get_diagnostics(bufnr, opts --[[@as vim.diagnostic.GetOpts]], false) local items = M.toqflist(diagnostics) if loclist then vim.fn.setloclist(winnr, {}, ' ', { title = title, items = items }) @@ -440,10 +609,16 @@ local function set_list(loclist, opts) end end +--- @param position {[1]: integer, [2]: integer} +--- @param search_forward boolean +--- @param bufnr integer +--- @param opts vim.diagnostic.GotoOpts +--- @param namespace integer +--- @return vim.Diagnostic? local function next_diagnostic(position, search_forward, bufnr, opts, namespace) position[1] = position[1] - 1 bufnr = get_bufnr(bufnr) - local wrap = vim.F.if_nil(opts.wrap, true) + local wrap = if_nil(opts.wrap, true) local line_count = api.nvim_buf_line_count(bufnr) local diagnostics = get_diagnostics(bufnr, vim.tbl_extend('keep', opts, { namespace = namespace }), true) @@ -460,6 +635,7 @@ local function next_diagnostic(position, search_forward, bufnr, opts, namespace) end if line_diagnostics[lnum] and not vim.tbl_isempty(line_diagnostics[lnum]) then local line_length = #api.nvim_buf_get_lines(bufnr, lnum, lnum + 1, true)[1] + --- @type function, function local sort_diagnostics, is_next if search_forward then sort_diagnostics = function(a, b) @@ -478,7 +654,9 @@ local function next_diagnostic(position, search_forward, bufnr, opts, namespace) end table.sort(line_diagnostics[lnum], sort_diagnostics) if i == 0 then - for _, v in pairs(line_diagnostics[lnum]) do + for _, v in + pairs(line_diagnostics[lnum] --[[@as table]]) + do if is_next(v) then return v end @@ -490,10 +668,12 @@ local function next_diagnostic(position, search_forward, bufnr, opts, namespace) end end +--- @param opts vim.diagnostic.GotoOpts? +--- @param pos {[1]:integer,[2]:integer}|false local function diagnostic_move_pos(opts, pos) opts = opts or {} - local float = vim.F.if_nil(opts.float, true) + local float = if_nil(opts.float, true) local win_id = opts.win_id or api.nvim_get_current_win() if not pos then @@ -549,8 +729,8 @@ end --- - `table`: Enable this feature with overrides. Use an empty table to use default values. --- - `function`: Function with signature (namespace, bufnr) that returns any of the above. --- ----@param opts table|nil When omitted or "nil", retrieve the current configuration. Otherwise, a ---- configuration table with the following keys: +---@param opts vim.diagnostic.Opts? (table?) When omitted or "nil", retrieve the current +--- configuration. Otherwise, a configuration table with the following keys: --- - underline: (default true) Use underline for diagnostics. Options: --- * severity: Only underline diagnostics matching the given --- severity |diagnostic-severity| @@ -616,17 +796,17 @@ end --- Options: --- * reverse: (boolean) Reverse sort order --- ----@param namespace integer|nil Update the options for the given namespace. When omitted, update the ---- global diagnostic options. +---@param namespace integer? Update the options for the given namespace. When omitted, update the +--- global diagnostic options. --- ----@return table|nil table of current diagnostic config if `opts` is omitted. +---@return vim.diagnostic.Opts? (table?) table of current diagnostic config if `opts` is omitted. function M.config(opts, namespace) vim.validate({ opts = { opts, 't', true }, namespace = { namespace, 'n', true }, }) - local t + local t --- @type vim.diagnostic.Opts if namespace then local ns = M.get_namespace(namespace) t = ns.opts @@ -639,7 +819,9 @@ function M.config(opts, namespace) return vim.deepcopy(t, true) end - for k, v in pairs(opts) do + for k, v in + pairs(opts --[[@as table]]) + do t[k] = v end @@ -662,8 +844,8 @@ end --- ---@param namespace integer The diagnostic namespace ---@param bufnr integer Buffer number ----@param diagnostics table A list of diagnostic items |diagnostic-structure| ----@param opts table|nil Display options to pass to |vim.diagnostic.show()| +---@param diagnostics vim.Diagnostic[] A list of diagnostic items |diagnostic-structure| +---@param opts? vim.diagnostic.Opts (table) Display options to pass to |vim.diagnostic.show()| function M.set(namespace, bufnr, diagnostics, opts) vim.validate({ namespace = { namespace, 'n' }, @@ -689,6 +871,7 @@ function M.set(namespace, bufnr, diagnostics, opts) api.nvim_exec_autocmds('DiagnosticChanged', { modeline = false, buffer = bufnr, + -- TODO(lewis6991): should this be deepcopy()'d like they are in vim.diagnostic.get() data = { diagnostics = diagnostics }, }) end @@ -696,11 +879,11 @@ end --- Get namespace metadata. --- ---@param namespace integer Diagnostic namespace ----@return table Namespace metadata +---@return vim.diagnostic.NS (table) Namespace metadata function M.get_namespace(namespace) vim.validate({ namespace = { namespace, 'n' } }) if not all_namespaces[namespace] then - local name + local name --- @type string? for k, v in pairs(api.nvim_get_namespaces()) do if namespace == v then name = k @@ -721,35 +904,22 @@ end --- Get current diagnostic namespaces. --- ----@return table A list of active diagnostic namespaces |vim.diagnostic|. +---@return table A list of active diagnostic namespaces |vim.diagnostic|. function M.get_namespaces() return vim.deepcopy(all_namespaces, true) end ----@class Diagnostic ----@field bufnr? integer ----@field lnum integer 0-indexed ----@field end_lnum? integer 0-indexed ----@field col integer 0-indexed ----@field end_col? integer 0-indexed ----@field severity? DiagnosticSeverity ----@field message string ----@field source? string ----@field code? string ----@field _tags? { deprecated: boolean, unnecessary: boolean} ----@field user_data? any arbitrary data plugins can add - --- Get current diagnostics. --- --- Modifying diagnostics in the returned table has no effect. To set diagnostics in a buffer, use |vim.diagnostic.set()|. --- ----@param bufnr integer|nil Buffer number to get diagnostics from. Use 0 for +---@param bufnr integer? Buffer number to get diagnostics from. Use 0 for --- current buffer or nil for all buffers. ----@param opts table|nil A table with the following keys: +---@param opts? vim.diagnostic.GetOpts (table) A table with the following keys: --- - namespace: (number) Limit diagnostics to the given namespace. --- - lnum: (number) Limit diagnostics to the given line number. --- - severity: See |diagnostic-severity|. ----@return Diagnostic[] table A list of diagnostic items |diagnostic-structure|. Keys `bufnr`, `end_lnum`, `end_col`, and `severity` are guaranteed to be present. +---@return vim.Diagnostic[] table A list of diagnostic items |diagnostic-structure|. Keys `bufnr`, `end_lnum`, `end_col`, and `severity` are guaranteed to be present. function M.get(bufnr, opts) vim.validate({ bufnr = { bufnr, 'n', true }, @@ -761,12 +931,12 @@ end --- Get current diagnostics count. --- ----@param bufnr integer|nil Buffer number to get diagnostics from. Use 0 for ---- current buffer or nil for all buffers. ----@param opts table|nil A table with the following keys: ---- - namespace: (number) Limit diagnostics to the given namespace. ---- - lnum: (number) Limit diagnostics to the given line number. ---- - severity: See |diagnostic-severity|. +---@param bufnr? integer Buffer number to get diagnostics from. Use 0 for +--- current buffer or nil for all buffers. +---@param opts? table A table with the following keys: +--- - namespace: (number) Limit diagnostics to the given namespace. +--- - lnum: (number) Limit diagnostics to the given line number. +--- - severity: See |diagnostic-severity|. ---@return table A table with actually present severity values as keys (see |diagnostic-severity|) and integer counts as values. function M.count(bufnr, opts) vim.validate({ @@ -775,9 +945,9 @@ function M.count(bufnr, opts) }) local diagnostics = get_diagnostics(bufnr, opts, false) - local count = {} + local count = {} --- @type table for i = 1, #diagnostics do - local severity = diagnostics[i].severity + local severity = diagnostics[i].severity --[[@as integer]] count[severity] = (count[severity] or 0) + 1 end return count @@ -785,8 +955,8 @@ end --- Get the previous diagnostic closest to the cursor position. --- ----@param opts nil|table See |vim.diagnostic.goto_next()| ----@return Diagnostic|nil Previous diagnostic +---@param opts? vim.diagnostic.GotoOpts (table) See |vim.diagnostic.goto_next()| +---@return vim.Diagnostic? Previous diagnostic function M.get_prev(opts) opts = opts or {} @@ -799,9 +969,9 @@ end --- Return the position of the previous diagnostic in the current buffer. --- ----@param opts table|nil See |vim.diagnostic.goto_next()| ----@return table|false Previous diagnostic position as a (row, col) tuple or false if there is no ---- prior diagnostic +---@param opts? vim.diagnostic.GotoOpts (table) See |vim.diagnostic.goto_next()| +---@return table|false: Previous diagnostic position as a (row, col) tuple or false if there is no +--- prior diagnostic function M.get_prev_pos(opts) local prev = M.get_prev(opts) if not prev then @@ -812,15 +982,15 @@ function M.get_prev_pos(opts) end --- Move to the previous diagnostic in the current buffer. ----@param opts table|nil See |vim.diagnostic.goto_next()| +---@param opts? vim.diagnostic.GotoOpts (table) See |vim.diagnostic.goto_next()| function M.goto_prev(opts) return diagnostic_move_pos(opts, M.get_prev_pos(opts)) end --- Get the next diagnostic closest to the cursor position. --- ----@param opts table|nil See |vim.diagnostic.goto_next()| ----@return Diagnostic|nil Next diagnostic +---@param opts? vim.diagnostic.GotoOpts (table) See |vim.diagnostic.goto_next()| +---@return vim.Diagnostic? : Next diagnostic function M.get_next(opts) opts = opts or {} @@ -833,9 +1003,9 @@ end --- Return the position of the next diagnostic in the current buffer. --- ----@param opts table|nil See |vim.diagnostic.goto_next()| ----@return table|false Next diagnostic position as a (row, col) tuple or false if no next ---- diagnostic. +---@param opts? vim.diagnostic.GotoOpts (table) See |vim.diagnostic.goto_next()| +---@return table|false : Next diagnostic position as a (row, col) tuple or false if no next +--- diagnostic. function M.get_next_pos(opts) local next = M.get_next(opts) if not next then @@ -845,10 +1015,21 @@ function M.get_next_pos(opts) return { next.lnum, next.col } end +--- @class vim.diagnostic.GetOpts +--- @field namespace? integer +--- @field lnum? integer +--- @field severity? vim.diagnostic.Severity + +--- @class vim.diagnostic.GotoOpts : vim.diagnostic.GetOpts +--- @field cursor_position? {[1]:integer,[2]:integer} +--- @field wrap? integer +--- @field float? boolean|vim.diagnostic.Opts.Float +--- @field win_id? integer + --- Move to the next diagnostic. --- ----@param opts table|nil Configuration table with the following keys: ---- - namespace: (number) Only consider diagnostics from the given namespace. +---@param opts? vim.diagnostic.GotoOpts (table) Configuration table with the following keys: +--- - namespace: (integer) Only consider diagnostics from the given namespace. --- - cursor_position: (cursor position) Cursor position as a (row, col) tuple. --- See |nvim_win_get_cursor()|. Defaults to the current cursor position. --- - wrap: (boolean, default true) Whether to loop around file or not. Similar to 'wrapscan'. @@ -860,7 +1041,7 @@ end --- the "scope" option). --- - win_id: (number, default 0) Window ID function M.goto_next(opts) - return diagnostic_move_pos(opts, M.get_next_pos(opts)) + diagnostic_move_pos(opts, M.get_next_pos(opts)) end M.handlers.signs = { @@ -885,7 +1066,7 @@ M.handlers.signs = { -- 10 is the default sign priority when none is explicitly specified local priority = opts.signs and opts.signs.priority or 10 - local get_priority + local get_priority --- @type function if opts.severity_sort then if type(opts.severity_sort) == 'table' and opts.severity_sort.reverse then get_priority = function(severity) @@ -951,7 +1132,7 @@ M.handlers.signs = { end end - local text = {} ---@type table + local text = {} ---@type table for k in pairs(M.severity) do if opts.signs.text and opts.signs.text[k] then text[k] = opts.signs.text[k] @@ -975,6 +1156,9 @@ M.handlers.signs = { end end end, + + --- @param namespace integer + --- @param bufnr integer hide = function(namespace, bufnr) local ns = M.get_namespace(namespace) if ns.user_data.sign_ns and api.nvim_buf_is_valid(bufnr) then @@ -1015,10 +1199,12 @@ M.handlers.underline = { local underline_ns = ns.user_data.underline_ns for _, diagnostic in ipairs(diagnostics) do - local higroup = underline_highlight_map[diagnostic.severity] + --- @type string? + local higroup = underline_highlight_map[assert(diagnostic.severity)] if higroup == nil then -- Default to error if we don't have a highlight associated + -- TODO(lewis6991): this is always nil since underline_highlight_map only has integer keys higroup = underline_highlight_map.Error end @@ -1074,7 +1260,7 @@ M.handlers.virtual_text = { return end - local severity + local severity --- @type vim.diagnostic.Severity? if opts.virtual_text then if opts.virtual_text.format then diagnostics = reformat_diagnostics(opts.virtual_text.format, diagnostics) @@ -1132,7 +1318,9 @@ M.handlers.virtual_text = { --- Exported for backward compatibility with --- vim.lsp.diagnostic.get_virtual_text_chunks_for_line(). When that function is eventually removed, --- this can be made local. ----@private +--- @private +--- @param line_diags table +--- @param opts vim.diagnostic.Opts.VirtualText function M._get_virt_text_chunks(line_diags, opts) if #line_diags == 0 then return nil @@ -1182,10 +1370,10 @@ end --- To hide diagnostics and prevent them from re-displaying, use --- |vim.diagnostic.disable()|. --- ----@param namespace integer|nil Diagnostic namespace. When omitted, hide ---- diagnostics from all namespaces. ----@param bufnr integer|nil Buffer number, or 0 for current buffer. When ---- omitted, hide diagnostics in all buffers. +---@param namespace integer? Diagnostic namespace. When omitted, hide +--- diagnostics from all namespaces. +---@param bufnr integer? Buffer number, or 0 for current buffer. When +--- omitted, hide diagnostics in all buffers. function M.hide(namespace, bufnr) vim.validate({ namespace = { namespace, 'n', true }, @@ -1207,11 +1395,11 @@ end --- Check whether diagnostics are disabled in a given buffer. --- ----@param bufnr integer|nil Buffer number, or 0 for current buffer. ----@param namespace integer|nil Diagnostic namespace. When omitted, checks if ---- all diagnostics are disabled in {bufnr}. ---- Otherwise, only checks if diagnostics from ---- {namespace} are disabled. +---@param bufnr integer? Buffer number, or 0 for current buffer. +---@param namespace integer? Diagnostic namespace. When omitted, checks if +--- all diagnostics are disabled in {bufnr}. +--- Otherwise, only checks if diagnostics from +--- {namespace} are disabled. ---@return boolean function M.is_disabled(bufnr, namespace) bufnr = get_bufnr(bufnr) @@ -1228,17 +1416,17 @@ end --- Display diagnostics for the given namespace and buffer. --- ----@param namespace integer|nil Diagnostic namespace. When omitted, show ---- diagnostics from all namespaces. ----@param bufnr integer|nil Buffer number, or 0 for current buffer. When omitted, show ---- diagnostics in all buffers. ----@param diagnostics table|nil The diagnostics to display. When omitted, use the +---@param namespace integer? Diagnostic namespace. When omitted, show +--- diagnostics from all namespaces. +---@param bufnr integer? Buffer number, or 0 for current buffer. When omitted, show +--- diagnostics in all buffers. +---@param diagnostics vim.Diagnostic[]? The diagnostics to display. When omitted, use the --- saved diagnostics for the given namespace and --- buffer. This can be used to display a list of diagnostics --- without saving them or to display only a subset of --- diagnostics. May not be used when {namespace} --- or {bufnr} is nil. ----@param opts table|nil Display options. See |vim.diagnostic.config()|. +---@param opts? vim.diagnostic.Opts (table) Display options. See |vim.diagnostic.config()|. function M.show(namespace, bufnr, diagnostics, opts) vim.validate({ namespace = { namespace, 'n', true }, @@ -1277,24 +1465,24 @@ function M.show(namespace, bufnr, diagnostics, opts) diagnostics = diagnostics or get_diagnostics(bufnr, { namespace = namespace }, true) - if not diagnostics or vim.tbl_isempty(diagnostics) then + if vim.tbl_isempty(diagnostics) then return end - opts = get_resolved_options(opts, namespace, bufnr) + local opts_res = get_resolved_options(opts, namespace, bufnr) - if opts.update_in_insert then + if opts_res.update_in_insert then clear_scheduled_display(namespace, bufnr) else local mode = api.nvim_get_mode() if string.sub(mode.mode, 1, 1) == 'i' then - schedule_display(namespace, bufnr, opts) + schedule_display(namespace, bufnr, opts_res) return end end - if vim.F.if_nil(opts.severity_sort, false) then - if type(opts.severity_sort) == 'table' and opts.severity_sort.reverse then + if if_nil(opts_res.severity_sort, false) 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 end) @@ -1306,15 +1494,15 @@ function M.show(namespace, bufnr, diagnostics, opts) end for handler_name, handler in pairs(M.handlers) do - if handler.show and opts[handler_name] then - handler.show(namespace, bufnr, diagnostics, opts) + if handler.show and opts_res[handler_name] then + handler.show(namespace, bufnr, diagnostics, opts_res) end end end --- Show diagnostics in a floating window. --- ----@param opts table|nil Configuration table with the same keys +---@param opts vim.diagnostic.Opts.Float? (table?) Configuration table with the same keys --- as |vim.lsp.util.open_floating_preview()| in addition to the following: --- - bufnr: (number) Buffer number to show diagnostics from. --- Defaults to the current buffer. @@ -1354,13 +1542,13 @@ end --- Overrides the setting from |vim.diagnostic.config()|. --- - suffix: Same as {prefix}, but appends the text to the diagnostic instead of --- prepending it. Overrides the setting from |vim.diagnostic.config()|. ----@return integer|nil, integer|nil: ({float_bufnr}, {win_id}) +---@return integer?, integer?: ({float_bufnr}, {win_id}) function M.open_float(opts, ...) -- Support old (bufnr, opts) signature - local bufnr + local bufnr --- @type integer? if opts == nil or type(opts) == 'number' then bufnr = opts - opts = ... + opts = ... --- @type vim.diagnostic.Opts.Float else vim.validate({ opts = { opts, 't', true }, @@ -1382,16 +1570,17 @@ function M.open_float(opts, ...) end local scope = ({ l = 'line', c = 'cursor', b = 'buffer' })[opts.scope] or opts.scope or 'line' - local lnum, col + local lnum, col --- @type integer, integer + local opts_pos = opts.pos if scope == 'line' or scope == 'cursor' then - if not opts.pos then + if not opts_pos then local pos = api.nvim_win_get_cursor(0) lnum = pos[1] - 1 col = pos[2] - elseif type(opts.pos) == 'number' then - lnum = opts.pos - elseif type(opts.pos) == 'table' then - lnum, col = unpack(opts.pos) + elseif type(opts_pos) == 'number' then + lnum = opts_pos + elseif type(opts_pos) == 'table' then + lnum, col = opts_pos[1], opts_pos[2] else error("Invalid value for option 'pos'") end @@ -1399,15 +1588,17 @@ function M.open_float(opts, ...) error("Invalid value for option 'scope'") end - local diagnostics = get_diagnostics(bufnr, opts, true) + local diagnostics = get_diagnostics(bufnr, opts --[[@as vim.diagnostic.GetOpts]], true) if scope == 'line' then + --- @param d vim.Diagnostic diagnostics = vim.tbl_filter(function(d) return d.lnum == lnum end, diagnostics) elseif scope == 'cursor' then -- LSP servers can send diagnostics with `end_col` past the length of the line local line_length = #api.nvim_buf_get_lines(bufnr, lnum, lnum + 1, true)[1] + --- @param d vim.Diagnostic diagnostics = vim.tbl_filter(function(d) return d.lnum == lnum and math.min(d.col, line_length - 1) <= col @@ -1419,7 +1610,7 @@ function M.open_float(opts, ...) return end - local severity_sort = vim.F.if_nil(opts.severity_sort, global_diagnostic_options.severity_sort) + local severity_sort = if_nil(opts.severity_sort, global_diagnostic_options.severity_sort) if severity_sort then if type(severity_sort) == 'table' and severity_sort.reverse then table.sort(diagnostics, function(a, b) @@ -1432,8 +1623,8 @@ function M.open_float(opts, ...) end end - local lines = {} - local highlights = {} + local lines = {} --- @type string[] + local highlights = {} --- @type table[] local header = if_nil(opts.header, 'Diagnostics:') if header then vim.validate({ @@ -1468,7 +1659,7 @@ function M.open_float(opts, ...) return string.format('%d. ', i) end) - local prefix, prefix_hl_group + local prefix, prefix_hl_group --- @type string?, string? if prefix_opt then vim.validate({ prefix = { @@ -1488,7 +1679,7 @@ function M.open_float(opts, ...) return diagnostic.code and string.format(' [%s]', diagnostic.code) or '' end) - local suffix, suffix_hl_group + local suffix, suffix_hl_group --- @type string?, string? if suffix_opt then vim.validate({ suffix = { @@ -1505,15 +1696,18 @@ function M.open_float(opts, ...) end for i, diagnostic in ipairs(diagnostics) do - if prefix_opt and type(prefix_opt) == 'function' then - prefix, prefix_hl_group = prefix_opt(diagnostic, i, #diagnostics) - prefix, prefix_hl_group = prefix or '', prefix_hl_group or 'NormalFloat' + if type(prefix_opt) == 'function' then + --- @cast prefix_opt fun(...): string?, string? + local prefix0, prefix_hl_group0 = prefix_opt(diagnostic, i, #diagnostics) + prefix, prefix_hl_group = prefix0 or '', prefix_hl_group0 or 'NormalFloat' end - if suffix_opt and type(suffix_opt) == 'function' then - suffix, suffix_hl_group = suffix_opt(diagnostic, i, #diagnostics) - suffix, suffix_hl_group = suffix or '', suffix_hl_group or 'NormalFloat' + if type(suffix_opt) == 'function' then + --- @cast suffix_opt fun(...): string?, string? + local suffix0, suffix_hl_group0 = suffix_opt(diagnostic, i, #diagnostics) + suffix, suffix_hl_group = suffix0 or '', suffix_hl_group0 or 'NormalFloat' end - local hiname = floating_highlight_map[diagnostic.severity] + --- @type string? + local hiname = floating_highlight_map[assert(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) @@ -1561,10 +1755,10 @@ end --- simply remove diagnostic decorations in a way that they can be --- re-displayed, use |vim.diagnostic.hide()|. --- ----@param namespace integer|nil Diagnostic namespace. When omitted, remove ---- diagnostics from all namespaces. ----@param bufnr integer|nil Remove diagnostics for the given buffer. When omitted, ---- diagnostics are removed for all buffers. +---@param namespace integer? Diagnostic namespace. When omitted, remove +--- diagnostics from all namespaces. +---@param bufnr integer? Remove diagnostics for the given buffer. When omitted, +--- diagnostics are removed for all buffers. function M.reset(namespace, bufnr) vim.validate({ namespace = { namespace, 'n', true }, @@ -1591,9 +1785,15 @@ function M.reset(namespace, bufnr) end end +--- @class vim.diagnostic.setqflist.Opts +--- @field namespace? integer +--- @field open? boolean +--- @field title? string +--- @field severity? vim.diagnostic.Severity + --- Add all diagnostics to the quickfix list. --- ----@param opts table|nil Configuration table with the following keys: +---@param opts? vim.diagnostic.setqflist.Opts (table) Configuration table with the following keys: --- - namespace: (number) Only add diagnostics from the given namespace. --- - open: (boolean, default true) Open quickfix list after setting. --- - title: (string) Title of quickfix list. Defaults to "Diagnostics". @@ -1602,9 +1802,16 @@ function M.setqflist(opts) set_list(false, opts) end +--- @class vim.diagnostic.setloclist.Opts +--- @field namespace? integer +--- @field open? boolean +--- @field title? string +--- @field severity? vim.diagnostic.Severity +--- @field winnr? integer + --- Add buffer diagnostics to the location list. --- ----@param opts table|nil Configuration table with the following keys: +---@param opts? vim.diagnostic.setloclist.Opts (table) Configuration table with the following keys: --- - namespace: (number) Only add diagnostics from the given namespace. --- - winnr: (number, default 0) Window number to set location list for. --- - open: (boolean, default true) Open the location list after setting. @@ -1616,9 +1823,9 @@ end --- Disable diagnostics in the given buffer. --- ----@param bufnr integer|nil Buffer number, or 0 for current buffer. When ---- omitted, disable diagnostics in all buffers. ----@param namespace integer|nil Only disable diagnostics for the given namespace. +---@param bufnr integer? Buffer number, or 0 for current buffer. When +--- omitted, disable diagnostics in all buffers. +---@param namespace integer? Only disable diagnostics for the given namespace. function M.disable(bufnr, namespace) vim.validate({ bufnr = { bufnr, 'n', true }, namespace = { namespace, 'n', true } }) if bufnr == nil then @@ -1653,9 +1860,9 @@ end --- Enable diagnostics in the given buffer. --- ----@param bufnr integer|nil Buffer number, or 0 for current buffer. When ---- omitted, enable diagnostics in all buffers. ----@param namespace integer|nil Only enable diagnostics for the given namespace. +---@param bufnr integer? Buffer number, or 0 for current buffer. When +--- omitted, enable diagnostics in all buffers. +---@param namespace integer? Only enable diagnostics for the given namespace. function M.enable(bufnr, namespace) vim.validate({ bufnr = { bufnr, 'n', true }, namespace = { namespace, 'n', true } }) if bufnr == nil then @@ -1701,14 +1908,14 @@ end --- ---@param str string String to parse diagnostics from. ---@param pat string Lua pattern with capture groups. ----@param groups table List of fields in a |diagnostic-structure| to +---@param groups string[] List of fields in a |diagnostic-structure| to --- associate with captures from {pat}. ---@param severity_map table A table mapping the severity field from {groups} --- with an item from |vim.diagnostic.severity|. ----@param defaults table|nil Table of default values for any fields not listed in {groups}. ---- When omitted, numeric values default to 0 and "severity" defaults to ---- ERROR. ----@return Diagnostic|nil: |diagnostic-structure| or `nil` if {pat} fails to match {str}. +---@param defaults table? Table of default values for any fields not listed in {groups}. +--- When omitted, numeric values default to 0 and "severity" defaults to +--- ERROR. +---@return vim.Diagnostic?: |diagnostic-structure| or `nil` if {pat} fails to match {str}. function M.match(str, pat, groups, severity_map, defaults) vim.validate({ str = { str, 's' }, @@ -1718,14 +1925,16 @@ function M.match(str, pat, groups, severity_map, defaults) defaults = { defaults, 't', true }, }) + --- @type table severity_map = severity_map or M.severity - local diagnostic = {} - local matches = { string.match(str, pat) } + local matches = { str:match(pat) } --- @type any[] if vim.tbl_isempty(matches) then return end + local diagnostic = {} --- @type type + for i, match in ipairs(matches) do local field = groups[i] if field == 'severity' then @@ -1733,10 +1942,10 @@ function M.match(str, pat, groups, severity_map, defaults) elseif field == 'lnum' or field == 'end_lnum' or field == 'col' or field == 'end_col' then match = assert(tonumber(match)) - 1 end - diagnostic[field] = match + diagnostic[field] = match --- @type any end - diagnostic = vim.tbl_extend('keep', diagnostic, defaults or {}) + diagnostic = vim.tbl_extend('keep', diagnostic, defaults or {}) --- @type vim.Diagnostic diagnostic.severity = diagnostic.severity or M.severity.ERROR diagnostic.col = diagnostic.col or 0 diagnostic.end_lnum = diagnostic.end_lnum or diagnostic.lnum @@ -1754,7 +1963,7 @@ local errlist_type_map = { --- Convert a list of diagnostics to a list of quickfix items that can be --- passed to |setqflist()| or |setloclist()|. --- ----@param diagnostics table List of diagnostics |diagnostic-structure|. +---@param diagnostics vim.Diagnostic[] List of diagnostics |diagnostic-structure|. ---@return table[] of quickfix list items |setqflist-what| function M.toqflist(diagnostics) vim.validate({ @@ -1765,7 +1974,7 @@ function M.toqflist(diagnostics) }, }) - local list = {} + local list = {} --- @type table[] for _, v in ipairs(diagnostics) do local item = { bufnr = v.bufnr, @@ -1795,7 +2004,7 @@ end --- Convert a list of quickfix items to a list of diagnostics. --- ---@param list table[] List of quickfix items from |getqflist()| or |getloclist()|. ----@return Diagnostic[] array of |diagnostic-structure| +---@return vim.Diagnostic[] array of |diagnostic-structure| function M.fromqflist(list) vim.validate({ list = { @@ -1805,7 +2014,7 @@ function M.fromqflist(list) }, }) - local diagnostics = {} + local diagnostics = {} --- @type vim.Diagnostic[] for _, item in ipairs(list) do if item.valid == 1 then local lnum = math.max(0, item.lnum - 1) @@ -1813,7 +2022,7 @@ function M.fromqflist(list) local end_lnum = item.end_lnum > 0 and (item.end_lnum - 1) or lnum local end_col = item.end_col > 0 and (item.end_col - 1) or col local severity = item.type ~= '' and M.severity[item.type] or M.severity.ERROR - table.insert(diagnostics, { + diagnostics[#diagnostics + 1] = { bufnr = item.bufnr, lnum = lnum, col = col, @@ -1821,7 +2030,7 @@ function M.fromqflist(list) end_col = end_col, severity = severity, message = item.text, - }) + } end end return diagnostics -- cgit From 5aa14e1231b7eccfbc54cba8f20d54105212847d Mon Sep 17 00:00:00 2001 From: altermo <107814000+altermo@users.noreply.github.com> Date: Wed, 17 Jan 2024 20:34:25 +0100 Subject: fix(lua): return after assert returns assert message (#27064) --- runtime/lua/vim/diagnostic.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index c7a1e8ebd3..03a1fe9a2f 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -180,10 +180,8 @@ local all_namespaces = {} ---@return vim.diagnostic.Severity? local function to_severity(severity) if type(severity) == 'string' then - return assert( - M.severity[string.upper(severity)], - string.format('Invalid severity: %s', severity) - ) + assert(M.severity[string.upper(severity)], string.format('Invalid severity: %s', severity)) + return M.severity[string.upper(severity)] end return severity end -- cgit From 89ffdebd20fd1d9c1ceff5fb005db11a0cf8c4d4 Mon Sep 17 00:00:00 2001 From: Jongwook Choi Date: Tue, 23 Jan 2024 01:04:20 -0500 Subject: fix(diagnostic): fix typing on field |diagnostic-severity| Problem: vim.diagnostic.{underline,float,virtual_text...}.severity will have a type warning on list-like or table (min-max) inputs, e.g. `vim.diagnostic.config { float = { severity = { min = INFO } } }`. Solution: Correct the typing as documented in |diagnostic-severity|. --- runtime/lua/vim/diagnostic.lua | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 03a1fe9a2f..8845fb5b61 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -38,7 +38,7 @@ local M = {} --- @field scope? 'line'|'buffer'|'cursor'|'c'|'l'|'b' --- @field pos? integer|{[1]:integer,[2]:integer} --- @field severity_sort? boolean|{reverse?:boolean} ---- @field severity? vim.diagnostic.Severity +--- @field severity? vim.diagnostic.SeverityFilter --- @field header? string|{[1]:string,[2]:any} --- @field source? boolean|string --- @field format? fun(diagnostic:vim.Diagnostic): string @@ -47,10 +47,10 @@ local M = {} --- @field focus_id? string --- @class vim.diagnostic.Opts.Underline ---- @field severity? vim.diagnostic.Severity +--- @field severity? vim.diagnostic.SeverityFilter --- @class vim.diagnostic.Opts.VirtualText ---- @field severity? vim.diagnostic.Severity +--- @field severity? vim.diagnostic.SeverityFilter --- @field source? boolean|string --- @field prefix? string|function --- @field suffix? string|function @@ -63,7 +63,7 @@ local M = {} --- @field virt_text_hide? boolean --- @class vim.diagnostic.Opts.Signs ---- @field severity? vim.diagnostic.Severity +--- @field severity? vim.diagnostic.SeverityFilter --- @field priority? integer --- @field text? table --- @field numhl? table @@ -84,6 +84,9 @@ M.severity = { --- @alias vim.diagnostic.SeverityInt 1|2|3|4 +--- 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} + -- Mappings from qflist/loclist error types to severities M.severity.E = M.severity.ERROR M.severity.W = M.severity.WARN @@ -186,7 +189,7 @@ local function to_severity(severity) return severity end ---- @param severity vim.diagnostic.Severity|vim.diagnostic.Severity[]|{min:vim.diagnostic.Severity,max:vim.diagnostic.Severity} +--- @param severity vim.diagnostic.SeverityFilter --- @param diagnostics vim.Diagnostic[] --- @return vim.Diagnostic[] local function filter_by_severity(severity, diagnostics) @@ -1016,7 +1019,7 @@ end --- @class vim.diagnostic.GetOpts --- @field namespace? integer --- @field lnum? integer ---- @field severity? vim.diagnostic.Severity +--- @field severity? vim.diagnostic.SeverityFilter --- @class vim.diagnostic.GotoOpts : vim.diagnostic.GetOpts --- @field cursor_position? {[1]:integer,[2]:integer} @@ -1258,7 +1261,7 @@ M.handlers.virtual_text = { return end - local severity --- @type vim.diagnostic.Severity? + local severity --- @type vim.diagnostic.SeverityFilter? if opts.virtual_text then if opts.virtual_text.format then diagnostics = reformat_diagnostics(opts.virtual_text.format, diagnostics) -- cgit From 2e982f1aad9f1a03562b7a451d642f76b04c37cb Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 22 Jan 2024 18:23:28 +0100 Subject: refactor: create function for deferred loading The benefit of this is that users only pay for what they use. If e.g. only `vim.lsp.buf_get_clients()` is called then they don't need to load all modules under `vim.lsp` which could lead to significant startuptime saving. Also `vim.lsp.module` is a bit nicer to user compared to `require("vim.lsp.module")`. This isn't used for some nested modules such as `filetype` as it breaks tests with error messages such as "attempt to index field 'detect'". It's not entirely certain the reason for this, but it is likely it is due to filetype being precompiled which would imply deferred loading isn't needed for performance reasons. --- runtime/lua/vim/diagnostic.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 8845fb5b61..a3a2422ab5 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -1732,7 +1732,7 @@ function M.open_float(opts, ...) if not opts.focus_id then opts.focus_id = scope end - local float_bufnr, winnr = require('vim.lsp.util').open_floating_preview(lines, 'plaintext', opts) + local float_bufnr, winnr = vim.lsp.util.open_floating_preview(lines, 'plaintext', opts) for i, hl in ipairs(highlights) do local line = lines[i] local prefix_len = hl.prefix and hl.prefix.length or 0 -- cgit From 63b810c9d8543bfcbee0367554e97cb97d1c14e6 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Tue, 6 Feb 2024 12:30:02 +0100 Subject: docs: small fixes (#27213) Co-authored-by: Matthieu Coudron <886074+teto@users.noreply.github.com> --- runtime/lua/vim/diagnostic.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index a3a2422ab5..ec465f4780 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -1023,7 +1023,7 @@ end --- @class vim.diagnostic.GotoOpts : vim.diagnostic.GetOpts --- @field cursor_position? {[1]:integer,[2]:integer} ---- @field wrap? integer +--- @field wrap? boolean --- @field float? boolean|vim.diagnostic.Opts.Float --- @field win_id? integer -- cgit From 3be2536ca039fb0f0de4ed2858db5a6d13baeba3 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Tue, 6 Feb 2024 12:34:04 +0000 Subject: fix(lsp): send back diagnostic tags to the server Fixes: #27318 --- runtime/lua/vim/diagnostic.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index ec465f4780..91f91b5879 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -11,7 +11,7 @@ local M = {} --- @field severity? vim.diagnostic.Severity --- @field message string --- @field source? string ---- @field code? string +--- @field code? string|integer --- @field _tags? { deprecated: boolean, unnecessary: boolean} --- @field user_data? any arbitrary data plugins can add --- @field namespace? integer -- cgit From 9beb40a4db5613601fc1a4b828a44e5977eca046 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Thu, 15 Feb 2024 17:16:04 +0000 Subject: feat(docs): replace lua2dox.lua Problem: The documentation flow (`gen_vimdoc.py`) has several issues: - it's not very versatile - depends on doxygen - doesn't work well with Lua code as it requires an awkward filter script to convert it into pseudo-C. - The intermediate XML files and filters makes it too much like a rube goldberg machine. Solution: Re-implement the flow using Lua, LPEG and treesitter. - `gen_vimdoc.py` is now replaced with `gen_vimdoc.lua` and replicates a portion of the logic. - `lua2dox.lua` is gone! - No more XML files. - Doxygen is now longer used and instead we now use: - LPEG for comment parsing (see `scripts/luacats_grammar.lua` and `scripts/cdoc_grammar.lua`). - LPEG for C parsing (see `scripts/cdoc_parser.lua`) - Lua patterns for Lua parsing (see `scripts/luacats_parser.lua`). - Treesitter for Markdown parsing (see `scripts/text_utils.lua`). - The generated `runtime/doc/*.mpack` files have been removed. - `scripts/gen_eval_files.lua` now instead uses `scripts/cdoc_parser.lua` directly. - Text wrapping is implemented in `scripts/text_utils.lua` and appears to produce more consistent results (the main contributer to the diff of this change). --- runtime/lua/vim/diagnostic.lua | 125 +++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 61 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 91f91b5879..49165c4db9 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -70,6 +70,7 @@ local M = {} --- @field linehl? table --- @field texthl? table +--- @nodoc --- @enum vim.diagnostic.Severity M.severity = { ERROR = 1, @@ -107,6 +108,7 @@ local global_diagnostic_options = { --- @field show? fun(namespace: integer, bufnr: integer, diagnostics: vim.Diagnostic[], opts?: vim.diagnostic.OptsResolved) --- @field hide? fun(namespace:integer, bufnr:integer) +--- @nodoc --- @type table M.handlers = setmetatable({}, { __newindex = function(t, name, handler) @@ -731,71 +733,71 @@ end --- - `function`: Function with signature (namespace, bufnr) that returns any of the above. --- ---@param opts vim.diagnostic.Opts? (table?) When omitted or "nil", retrieve the current ---- configuration. Otherwise, a configuration table with the following keys: +--- configuration. Otherwise, a configuration table with the following keys: --- - underline: (default true) Use underline for diagnostics. Options: ---- * severity: Only underline diagnostics matching the given ---- severity |diagnostic-severity| +--- * severity: Only underline diagnostics matching the given +--- severity |diagnostic-severity| --- - virtual_text: (default true) Use virtual text for diagnostics. If multiple diagnostics ---- are set for a namespace, one prefix per diagnostic + the last diagnostic ---- message are shown. In addition to the options listed below, the ---- "virt_text" options of |nvim_buf_set_extmark()| may also be used here ---- (e.g. "virt_text_pos" and "hl_mode"). ---- Options: ---- * severity: Only show virtual text for diagnostics matching the given ---- severity |diagnostic-severity| ---- * source: (boolean or string) Include the diagnostic source in virtual ---- text. Use "if_many" to only show sources if there is more than ---- one diagnostic source in the buffer. Otherwise, any truthy value ---- means to always show the diagnostic source. ---- * spacing: (number) Amount of empty spaces inserted at the beginning ---- of the virtual text. ---- * prefix: (string or function) prepend diagnostic message with prefix. ---- If a function, it must have the signature (diagnostic, i, total) ---- -> string, where {diagnostic} is of type |diagnostic-structure|, ---- {i} is the index of the diagnostic being evaluated, and {total} ---- is the total number of diagnostics for the line. This can be ---- used to render diagnostic symbols or error codes. ---- * suffix: (string or function) Append diagnostic message with suffix. ---- If a function, it must have the signature (diagnostic) -> ---- string, where {diagnostic} is of type |diagnostic-structure|. ---- This can be used to render an LSP diagnostic error code. ---- * format: (function) A function that takes a diagnostic as input and ---- returns a string. The return value is the text used to display ---- the diagnostic. Example: ----
lua
----                         function(diagnostic)
----                           if diagnostic.severity == vim.diagnostic.severity.ERROR then
----                             return string.format("E: %s", diagnostic.message)
----                           end
----                           return diagnostic.message
----                         end
----                       
+--- are set for a namespace, one prefix per diagnostic + the last diagnostic +--- message are shown. In addition to the options listed below, the +--- "virt_text" options of |nvim_buf_set_extmark()| may also be used here +--- (e.g. "virt_text_pos" and "hl_mode"). +--- Options: +--- * severity: Only show virtual text for diagnostics matching the given +--- severity |diagnostic-severity| +--- * source: (boolean or string) Include the diagnostic source in virtual +--- text. Use "if_many" to only show sources if there is more than +--- one diagnostic source in the buffer. Otherwise, any truthy value +--- means to always show the diagnostic source. +--- * spacing: (number) Amount of empty spaces inserted at the beginning +--- of the virtual text. +--- * prefix: (string or function) prepend diagnostic message with prefix. +--- If a function, it must have the signature (diagnostic, i, total) +--- -> string, where {diagnostic} is of type |diagnostic-structure|, +--- {i} is the index of the diagnostic being evaluated, and {total} +--- is the total number of diagnostics for the line. This can be +--- used to render diagnostic symbols or error codes. +--- * suffix: (string or function) Append diagnostic message with suffix. +--- If a function, it must have the signature (diagnostic) -> +--- string, where {diagnostic} is of type |diagnostic-structure|. +--- This can be used to render an LSP diagnostic error code. +--- * format: (function) A function that takes a diagnostic as input and +--- returns a string. The return value is the text used to display +--- the diagnostic. Example: +--- ```lua +--- function(diagnostic) +--- if diagnostic.severity == vim.diagnostic.severity.ERROR then +--- return string.format("E: %s", diagnostic.message) +--- end +--- return diagnostic.message +--- end +--- ``` --- - signs: (default true) Use signs for diagnostics |diagnostic-signs|. Options: ---- * severity: Only show signs for diagnostics matching the given ---- severity |diagnostic-severity| ---- * priority: (number, default 10) Base priority to use for signs. When ---- {severity_sort} is used, the priority of a sign is adjusted based on ---- its severity. Otherwise, all signs use the same priority. ---- * text: (table) A table mapping |diagnostic-severity| to the sign text ---- to display in the sign column. The default is to use "E", "W", "I", and "H" ---- for errors, warnings, information, and hints, respectively. Example: ----
lua
----                       vim.diagnostic.config({
----                         signs = { text = { [vim.diagnostic.severity.ERROR] = 'E', ... } }
----                       })
----                   
---- * numhl: (table) A table mapping |diagnostic-severity| to the highlight ---- group used for the line number where the sign is placed. ---- * linehl: (table) A table mapping |diagnostic-severity| to the highlight group ---- used for the whole line the sign is placed in. +--- * severity: Only show signs for diagnostics matching the given +--- severity |diagnostic-severity| +--- * priority: (number, default 10) Base priority to use for signs. When +--- {severity_sort} is used, the priority of a sign is adjusted based on +--- its severity. Otherwise, all signs use the same priority. +--- * text: (table) A table mapping |diagnostic-severity| to the sign text +--- to display in the sign column. The default is to use "E", "W", "I", and "H" +--- for errors, warnings, information, and hints, respectively. Example: +--- ```lua +--- vim.diagnostic.config({ +--- signs = { text = { [vim.diagnostic.severity.ERROR] = 'E', ... } } +--- }) +--- ``` +--- * numhl: (table) A table mapping |diagnostic-severity| to the highlight +--- group used for the line number where the sign is placed. +--- * linehl: (table) A table mapping |diagnostic-severity| to the highlight group +--- used for the whole line the sign is placed in. --- - float: Options for floating windows. See |vim.diagnostic.open_float()|. --- - update_in_insert: (default false) Update diagnostics in Insert mode (if false, --- diagnostics are updated on InsertLeave) --- - severity_sort: (default false) Sort diagnostics by severity. This affects the order in ---- which signs and virtual text are displayed. When true, higher severities ---- are displayed before lower severities (e.g. ERROR is displayed before WARN). ---- Options: ---- * reverse: (boolean) Reverse sort order +--- which signs and virtual text are displayed. When true, higher severities +--- are displayed before lower severities (e.g. ERROR is displayed before WARN). +--- Options: +--- * reverse: (boolean) Reverse sort order --- ---@param namespace integer? Update the options for the given namespace. When omitted, update the --- global diagnostic options. @@ -1090,8 +1092,8 @@ M.handlers.signs = { api.nvim_create_namespace(string.format('%s/diagnostic/signs', ns.name)) end - --- Handle legacy diagnostic sign definitions - --- These were deprecated in 0.10 and will be removed in 0.12 + -- Handle legacy diagnostic sign definitions + -- These were deprecated in 0.10 and will be removed in 0.12 if opts.signs and not opts.signs.text and not opts.signs.numhl and not opts.signs.texthl then for _, v in ipairs({ 'Error', 'Warn', 'Info', 'Hint' }) do local name = string.format('DiagnosticSign%s', v) @@ -1543,7 +1545,8 @@ end --- Overrides the setting from |vim.diagnostic.config()|. --- - suffix: Same as {prefix}, but appends the text to the diagnostic instead of --- prepending it. Overrides the setting from |vim.diagnostic.config()|. ----@return integer?, integer?: ({float_bufnr}, {win_id}) +---@return integer? float_bufnr +---@return integer? win_id function M.open_float(opts, ...) -- Support old (bufnr, opts) signature local bufnr --- @type integer? -- cgit From a5fe8f59d98398d04bed8586cee73864bbcdde92 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Tue, 27 Feb 2024 15:20:32 +0000 Subject: docs: improve/add documentation of Lua types - Added `@inlinedoc` so single use Lua types can be inlined into the functions docs. E.g. ```lua --- @class myopts --- @inlinedoc --- --- Documentation for some field --- @field somefield integer --- @param opts myOpts function foo(opts) end ``` Will be rendered as ``` foo(opts) Parameters: - {opts} (table) Object with the fields: - somefield (integer) Documentation for some field ``` - Marked many classes with with `@nodoc` or `(private)`. We can eventually introduce these when we want to. --- runtime/lua/vim/diagnostic.lua | 123 +++++++++++++++++++++++++++++++---------- 1 file changed, 93 insertions(+), 30 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 49165c4db9..3979e5512c 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -2,18 +2,44 @@ local api, if_nil = vim.api, vim.F.if_nil local M = {} +--- *diagnostic-structure* +--- +--- Diagnostics use the same indexing as the rest of the Nvim API (i.e. 0-based +--- rows and columns). |api-indexing| --- @class vim.Diagnostic +--- +--- Buffer number --- @field bufnr? integer ---- @field lnum integer 0-indexed ---- @field end_lnum? integer 0-indexed ---- @field col integer 0-indexed ---- @field end_col? integer 0-indexed +--- +--- The starting line of the diagnostic (0-indexed) +--- @field lnum integer +--- +--- The final line of the diagnostic (0-indexed) +--- @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 +--- +--- The severity of the diagnostic |vim.diagnostic.severity| --- @field severity? vim.diagnostic.Severity +--- +--- The diagnostic text --- @field message string +--- +--- The source of the diagnostic --- @field source? string +--- +--- The diagnostic code --- @field code? string|integer +--- --- @field _tags? { deprecated: boolean, unnecessary: boolean} +--- +--- Arbitrary data plugins or users can add --- @field user_data? any arbitrary data plugins can add +--- --- @field namespace? integer --- @class vim.diagnostic.Opts @@ -104,7 +130,7 @@ local global_diagnostic_options = { severity_sort = false, } ---- @class vim.diagnostic.Handler +--- @class (private) vim.diagnostic.Handler --- @field show? fun(namespace: integer, bufnr: integer, diagnostics: vim.Diagnostic[], opts?: vim.diagnostic.OptsResolved) --- @field hide? fun(namespace:integer, bufnr:integer) @@ -154,7 +180,7 @@ do }) end ---- @class vim.diagnostic._extmark +--- @class (private) vim.diagnostic._extmark --- @field [1] integer id --- @field [2] integer start --- @field [3] integer end @@ -1018,31 +1044,52 @@ function M.get_next_pos(opts) return { next.lnum, next.col } end +--- A table with the following keys: --- @class vim.diagnostic.GetOpts +--- @inlinedoc +--- +--- Limit diagnostics to the given namespace. --- @field namespace? integer +--- +--- Limit diagnostics to the given line number. --- @field lnum? integer +--- +--- See |diagnostic-severity|. --- @field severity? vim.diagnostic.SeverityFilter +--- Configuration table with the following keys: --- @class vim.diagnostic.GotoOpts : vim.diagnostic.GetOpts +--- @inlinedoc +--- +--- Only consider diagnostics from the given namespace. +--- @field namespace integer +--- +--- Cursor position as a (row, col) tuple. +--- See |nvim_win_get_cursor()|. Defaults to the current cursor position. --- @field cursor_position? {[1]:integer,[2]:integer} +--- +--- Whether to loop around file or not. Similar to 'wrapscan'. +--- (default: `true`) --- @field wrap? boolean +--- +--- See |diagnostic-severity|. +--- @field severity vim.diagnostic.Severity +--- +--- If "true", call |vim.diagnostic.open_float()| +--- after moving. If a table, pass the table as the {opts} parameter +--- to |vim.diagnostic.open_float()|. Unless overridden, the float will show +--- diagnostics at the new cursor position (as if "cursor" were passed to +--- the "scope" option). +--- (default: `true`) --- @field float? boolean|vim.diagnostic.Opts.Float +--- +--- Window ID +--- (default: `0`) --- @field win_id? integer --- Move to the next diagnostic. --- ----@param opts? vim.diagnostic.GotoOpts (table) Configuration table with the following keys: ---- - namespace: (integer) Only consider diagnostics from the given namespace. ---- - cursor_position: (cursor position) Cursor position as a (row, col) tuple. ---- See |nvim_win_get_cursor()|. Defaults to the current cursor position. ---- - wrap: (boolean, default true) Whether to loop around file or not. Similar to 'wrapscan'. ---- - severity: See |diagnostic-severity|. ---- - float: (boolean or table, default true) If "true", call |vim.diagnostic.open_float()| ---- after moving. If a table, pass the table as the {opts} parameter ---- to |vim.diagnostic.open_float()|. Unless overridden, the float will show ---- diagnostics at the new cursor position (as if "cursor" were passed to ---- the "scope" option). ---- - win_id: (number, default 0) Window ID +---@param opts? vim.diagnostic.GotoOpts function M.goto_next(opts) diagnostic_move_pos(opts, M.get_next_pos(opts)) end @@ -1789,38 +1836,54 @@ function M.reset(namespace, bufnr) end end +--- Configuration table with the following keys: --- @class vim.diagnostic.setqflist.Opts +--- @inlinedoc +--- +--- Only add diagnostics from the given namespace. --- @field namespace? integer +--- +--- Open quickfix list after setting. +--- (default: `true`) --- @field open? boolean +--- +--- Title of quickfix list. Defaults to "Diagnostics". --- @field title? string +--- +--- See |diagnostic-severity|. --- @field severity? vim.diagnostic.Severity --- Add all diagnostics to the quickfix list. --- ----@param opts? vim.diagnostic.setqflist.Opts (table) Configuration table with the following keys: ---- - namespace: (number) Only add diagnostics from the given namespace. ---- - open: (boolean, default true) Open quickfix list after setting. ---- - title: (string) Title of quickfix list. Defaults to "Diagnostics". ---- - severity: See |diagnostic-severity|. +---@param opts? vim.diagnostic.setqflist.Opts function M.setqflist(opts) set_list(false, opts) end +---Configuration table with the following keys: --- @class vim.diagnostic.setloclist.Opts +--- @inlinedoc +--- +--- Only add diagnostics from the given namespace. --- @field namespace? integer +--- +--- Window number to set location list for. +--- (default: `0`) +--- @field winnr? integer +--- +--- Open the location list after setting. +--- (default: `true`) --- @field open? boolean +--- +--- Title of the location list. Defaults to "Diagnostics". --- @field title? string +--- +--- See |diagnostic-severity|. --- @field severity? vim.diagnostic.Severity ---- @field winnr? integer --- Add buffer diagnostics to the location list. --- ----@param opts? vim.diagnostic.setloclist.Opts (table) Configuration table with the following keys: ---- - namespace: (number) Only add diagnostics from the given namespace. ---- - winnr: (number, default 0) Window number to set location list for. ---- - open: (boolean, default true) Open the location list after setting. ---- - title: (string) Title of the location list. Defaults to "Diagnostics". ---- - severity: See |diagnostic-severity|. +---@param opts? vim.diagnostic.setloclist.Opts function M.setloclist(opts) set_list(true, opts) end -- cgit From a4290f462ed7dc81e17b09bd27877b106b24b6bd Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Tue, 5 Mar 2024 12:06:15 +0000 Subject: docs(lua): improvements for LSP and Diagnostic --- runtime/lua/vim/diagnostic.lua | 371 ++++++++++++++++++++++------------------- 1 file changed, 197 insertions(+), 174 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 3979e5512c..9483474a40 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -42,15 +42,44 @@ local M = {} --- --- @field namespace? integer +--- Each of the configuration options below accepts one of the following: +--- - `false`: Disable this feature +--- - `true`: Enable this feature, use default settings. +--- - `table`: Enable this feature with overrides. Use an empty table to use default values. +--- - `function`: Function with signature (namespace, bufnr) that returns any of the above. --- @class vim.diagnostic.Opts ---- @field float? boolean|vim.diagnostic.Opts.Float +--- +--- Use underline for diagnostics. +--- (default: `true`) +--- @field underline? boolean|vim.diagnostic.Opts.Underline|fun(namespace: integer, bufnr:integer): vim.diagnostic.Opts.Underline +--- +--- Use virtual text for diagnostics. If multiple diagnostics are set for a +--- namespace, one prefix per diagnostic + the last diagnostic message are +--- shown. +--- (default: `true`) +--- @field virtual_text? boolean|vim.diagnostic.Opts.VirtualText|fun(namespace: integer, bufnr:integer): vim.diagnostic.Opts.VirtualText +--- +--- Use signs for diagnostics |diagnostic-signs|. +--- (default: `true`) +--- @field signs? boolean|vim.diagnostic.Opts.Signs|fun(namespace: integer, bufnr:integer): vim.diagnostic.Opts.Signs +--- +--- Options for floating windows. See |vim.diagnostic.Opts.Float|. +--- @field float? boolean|vim.diagnostic.Opts.Float|fun(namespace: integer, bufnr:integer): vim.diagnostic.Opts.Float +--- +--- Update diagnostics in Insert mode +--- (if `false`, diagnostics are updated on |InsertLeave|) +--- (default: `false) --- @field update_in_insert? boolean ---- @field underline? boolean|vim.diagnostic.Opts.Underline ---- @field virtual_text? boolean|vim.diagnostic.Opts.VirtualText ---- @field signs? boolean|vim.diagnostic.Opts.Signs +--- +--- Sort diagnostics by severity. This affects the order in which signs and +--- virtual text are displayed. When true, higher severities are displayed +--- before lower severities (e.g. ERROR is displayed before WARN). +--- Options: +--- - {reverse}? (boolean) Reverse sort order +--- (default: `false) --- @field severity_sort? boolean|{reverse?:boolean} ---- @class vim.diagnostic.OptsResolved +--- @class (private) vim.diagnostic.OptsResolved --- @field float vim.diagnostic.Opts.Float --- @field update_in_insert boolean --- @field underline vim.diagnostic.Opts.Underline @@ -59,42 +88,156 @@ local M = {} --- @field severity_sort {reverse?:boolean} --- @class vim.diagnostic.Opts.Float +--- +--- Buffer number to show diagnostics from. +--- (default: current buffer) --- @field bufnr? integer +--- +--- Limit diagnostics to the given namespace --- @field namespace? integer +--- +--- Show diagnostics from the whole buffer (`buffer"`, the current cursor line +--- (`line`), or the current cursor position (`cursor`). Shorthand versions +--- are also accepted (`c` for `cursor`, `l` for `line`, `b` for `buffer`). +--- (default: `line`) --- @field scope? 'line'|'buffer'|'cursor'|'c'|'l'|'b' +--- +--- If {scope} is "line" or "cursor", use this position rather than the cursor +--- position. If a number, interpreted as a line number; otherwise, a +--- (row, col) tuple. --- @field pos? integer|{[1]:integer,[2]:integer} +--- +--- Sort diagnostics by severity. +--- Overrides the setting from |vim.diagnostic.config()|. +--- (default: `false`) --- @field severity_sort? boolean|{reverse?:boolean} +--- +--- See |diagnostic-severity|. +--- Overrides the setting from |vim.diagnostic.config()|. --- @field severity? vim.diagnostic.SeverityFilter +--- +--- String to use as the header for the floating window. If a table, it is +--- interpreted as a `[text, hl_group]` tuple. +--- Overrides the setting from |vim.diagnostic.config()|. --- @field header? string|{[1]:string,[2]:any} ---- @field source? boolean|string +--- +--- Include the diagnostic source in the message. +--- Use "if_many" to only show sources if there is more than one source of +--- diagnostics in the buffer. Otherwise, any truthy value means to always show +--- the diagnostic source. +--- Overrides the setting from |vim.diagnostic.config()|. +--- @field source? boolean|'if_many' +--- +--- A function that takes a diagnostic as input and returns a string. +--- The return value is the text used to display the diagnostic. +--- Overrides the setting from |vim.diagnostic.config()|. --- @field format? fun(diagnostic:vim.Diagnostic): string +--- +--- Prefix each diagnostic in the floating window: +--- - If a `function`, {i} is the index of the diagnostic being evaluated and +--- {total} is the total number of diagnostics displayed in the window. The +--- function should return a `string` which is prepended to each diagnostic +--- in the window as well as an (optional) highlight group which will be +--- used to highlight the prefix. +--- - If a `table`, it is interpreted as a `[text, hl_group]` tuple as +--- in |nvim_echo()| +--- - If a `string`, it is prepended to each diagnostic in the window with no +--- highlight. +--- Overrides the setting from |vim.diagnostic.config()|. --- @field prefix? string|table|(fun(diagnostic:vim.Diagnostic,i:integer,total:integer): string, string) +--- +--- Same as {prefix}, but appends the text to the diagnostic instead of +--- prepending it. +--- Overrides the setting from |vim.diagnostic.config()|. --- @field suffix? string|table|(fun(diagnostic:vim.Diagnostic,i:integer,total:integer): string, string) +--- --- @field focus_id? string --- @class vim.diagnostic.Opts.Underline +--- +--- Only underline diagnostics matching the given +--- severity |diagnostic-severity|. --- @field severity? vim.diagnostic.SeverityFilter --- @class vim.diagnostic.Opts.VirtualText +--- +--- Only show virtual text for diagnostics matching the given +--- severity |diagnostic-severity| --- @field severity? vim.diagnostic.SeverityFilter ---- @field source? boolean|string ---- @field prefix? string|function ---- @field suffix? string|function +--- +--- Include the diagnostic source in virtual text. Use `'if_many'` to only +--- show sources if there is more than one diagnostic source in the buffer. +--- Otherwise, any truthy value means to always show the diagnostic source. +--- @field source? boolean|"if_many" +--- +--- Amount of empty spaces inserted at the beginning of the virtual text. --- @field spacing? integer ---- @field format? function +--- +--- Prepend diagnostic message with prefix. If a `function`, {i} is the index +--- of the diagnostic being evaluated, and {total} is the total number of +--- diagnostics for the line. This can be used to render diagnostic symbols +--- or error codes. +--- @field prefix? string|(fun(diagnostic:vim.Diagnostic,i:integer,total:integer): string) +--- +--- Append diagnostic message with suffix. +--- This can be used to render an LSP diagnostic error code. +--- @field suffix? string|(fun(diagnostic:vim.Diagnostic): string) +--- +--- The return value is the text used to display the diagnostic. Example: +--- ```lua +--- function(diagnostic) +--- if diagnostic.severity == vim.diagnostic.severity.ERROR then +--- return string.format("E: %s", diagnostic.message) +--- end +--- return diagnostic.message +--- end +--- ``` +--- @field format? fun(diagnostic:vim.Diagnostic): string +--- +--- See |nvim_buf_set_extmark()|. --- @field hl_mode? 'replace'|'combine'|'blend' +--- +--- See |nvim_buf_set_extmark()|. --- @field virt_text? {[1]:string,[2]:any}[] +--- +--- See |nvim_buf_set_extmark()|. --- @field virt_text_pos? 'eol'|'overlay'|'right_align'|'inline' +--- +--- See |nvim_buf_set_extmark()|. --- @field virt_text_win_col? integer +--- +--- See |nvim_buf_set_extmark()|. --- @field virt_text_hide? boolean --- @class vim.diagnostic.Opts.Signs +--- +--- Only show virtual text for diagnostics matching the given +--- severity |diagnostic-severity| --- @field severity? vim.diagnostic.SeverityFilter +--- +--- Base priority to use for signs. When {severity_sort} is used, the priority +--- of a sign is adjusted based on its severity. +--- Otherwise, all signs use the same priority. +--- (default: `10`) --- @field priority? integer +--- +--- A table mapping |diagnostic-severity| to the sign text to display in the +--- sign column. The default is to use `"E"`, `"W"`, `"I"`, and `"H"` for errors, +--- warnings, information, and hints, respectively. Example: +--- ```lua +--- vim.diagnostic.config({ +--- signs = { text = { [vim.diagnostic.severity.ERROR] = 'E', ... } } +--- }) +--- ``` --- @field text? table +--- +--- A table mapping |diagnostic-severity| to the highlight group used for the +--- line number where the sign is placed. --- @field numhl? table +--- +--- A table mapping |diagnostic-severity| to the highlight group used for the +--- whole line the sign is placed in. --- @field linehl? table ---- @field texthl? table --- @nodoc --- @enum vim.diagnostic.Severity @@ -752,83 +895,11 @@ end --- --- then virtual text will not be enabled for those diagnostics. --- ----@note Each of the configuration options below accepts one of the following: ---- - `false`: Disable this feature ---- - `true`: Enable this feature, use default settings. ---- - `table`: Enable this feature with overrides. Use an empty table to use default values. ---- - `function`: Function with signature (namespace, bufnr) that returns any of the above. ---- ----@param opts vim.diagnostic.Opts? (table?) When omitted or "nil", retrieve the current ---- configuration. Otherwise, a configuration table with the following keys: ---- - underline: (default true) Use underline for diagnostics. Options: ---- * severity: Only underline diagnostics matching the given ---- severity |diagnostic-severity| ---- - virtual_text: (default true) Use virtual text for diagnostics. If multiple diagnostics ---- are set for a namespace, one prefix per diagnostic + the last diagnostic ---- message are shown. In addition to the options listed below, the ---- "virt_text" options of |nvim_buf_set_extmark()| may also be used here ---- (e.g. "virt_text_pos" and "hl_mode"). ---- Options: ---- * severity: Only show virtual text for diagnostics matching the given ---- severity |diagnostic-severity| ---- * source: (boolean or string) Include the diagnostic source in virtual ---- text. Use "if_many" to only show sources if there is more than ---- one diagnostic source in the buffer. Otherwise, any truthy value ---- means to always show the diagnostic source. ---- * spacing: (number) Amount of empty spaces inserted at the beginning ---- of the virtual text. ---- * prefix: (string or function) prepend diagnostic message with prefix. ---- If a function, it must have the signature (diagnostic, i, total) ---- -> string, where {diagnostic} is of type |diagnostic-structure|, ---- {i} is the index of the diagnostic being evaluated, and {total} ---- is the total number of diagnostics for the line. This can be ---- used to render diagnostic symbols or error codes. ---- * suffix: (string or function) Append diagnostic message with suffix. ---- If a function, it must have the signature (diagnostic) -> ---- string, where {diagnostic} is of type |diagnostic-structure|. ---- This can be used to render an LSP diagnostic error code. ---- * format: (function) A function that takes a diagnostic as input and ---- returns a string. The return value is the text used to display ---- the diagnostic. Example: ---- ```lua ---- function(diagnostic) ---- if diagnostic.severity == vim.diagnostic.severity.ERROR then ---- return string.format("E: %s", diagnostic.message) ---- end ---- return diagnostic.message ---- end ---- ``` ---- - signs: (default true) Use signs for diagnostics |diagnostic-signs|. Options: ---- * severity: Only show signs for diagnostics matching the given ---- severity |diagnostic-severity| ---- * priority: (number, default 10) Base priority to use for signs. When ---- {severity_sort} is used, the priority of a sign is adjusted based on ---- its severity. Otherwise, all signs use the same priority. ---- * text: (table) A table mapping |diagnostic-severity| to the sign text ---- to display in the sign column. The default is to use "E", "W", "I", and "H" ---- for errors, warnings, information, and hints, respectively. Example: ---- ```lua ---- vim.diagnostic.config({ ---- signs = { text = { [vim.diagnostic.severity.ERROR] = 'E', ... } } ---- }) ---- ``` ---- * numhl: (table) A table mapping |diagnostic-severity| to the highlight ---- group used for the line number where the sign is placed. ---- * linehl: (table) A table mapping |diagnostic-severity| to the highlight group ---- used for the whole line the sign is placed in. ---- - float: Options for floating windows. See |vim.diagnostic.open_float()|. ---- - update_in_insert: (default false) Update diagnostics in Insert mode (if false, ---- diagnostics are updated on InsertLeave) ---- - severity_sort: (default false) Sort diagnostics by severity. This affects the order in ---- which signs and virtual text are displayed. When true, higher severities ---- are displayed before lower severities (e.g. ERROR is displayed before WARN). ---- Options: ---- * reverse: (boolean) Reverse sort order ---- ----@param namespace integer? Update the options for the given namespace. When omitted, update the ---- global diagnostic options. ---- ----@return vim.diagnostic.Opts? (table?) table of current diagnostic config if `opts` is omitted. +---@param opts vim.diagnostic.Opts? When omitted or `nil`, retrieve the current +--- configuration. Otherwise, a configuration table (see |vim.diagnostic.Opts|). +---@param namespace integer? Update the options for the given namespace. +--- When omitted, update the global diagnostic options. +---@return vim.diagnostic.Opts? : Current diagnostic config if {opts} is omitted. function M.config(opts, namespace) vim.validate({ opts = { opts, 't', true }, @@ -873,8 +944,8 @@ end --- ---@param namespace integer The diagnostic namespace ---@param bufnr integer Buffer number ----@param diagnostics vim.Diagnostic[] A list of diagnostic items |diagnostic-structure| ----@param opts? vim.diagnostic.Opts (table) Display options to pass to |vim.diagnostic.show()| +---@param diagnostics vim.Diagnostic[] +---@param opts? vim.diagnostic.Opts Display options to pass to |vim.diagnostic.show()| function M.set(namespace, bufnr, diagnostics, opts) vim.validate({ namespace = { namespace, 'n' }, @@ -908,7 +979,7 @@ end --- Get namespace metadata. --- ---@param namespace integer Diagnostic namespace ----@return vim.diagnostic.NS (table) Namespace metadata +---@return vim.diagnostic.NS : Namespace metadata function M.get_namespace(namespace) vim.validate({ namespace = { namespace, 'n' } }) if not all_namespaces[namespace] then @@ -933,22 +1004,21 @@ end --- Get current diagnostic namespaces. --- ----@return table A list of active diagnostic namespaces |vim.diagnostic|. +---@return table : List of active diagnostic namespaces |vim.diagnostic|. function M.get_namespaces() return vim.deepcopy(all_namespaces, true) end --- Get current diagnostics. --- ---- Modifying diagnostics in the returned table has no effect. To set diagnostics in a buffer, use |vim.diagnostic.set()|. +--- Modifying diagnostics in the returned table has no effect. +--- To set diagnostics in a buffer, use |vim.diagnostic.set()|. --- ---@param bufnr integer? Buffer number to get diagnostics from. Use 0 for ---- current buffer or nil for all buffers. ----@param opts? vim.diagnostic.GetOpts (table) A table with the following keys: ---- - namespace: (number) Limit diagnostics to the given namespace. ---- - lnum: (number) Limit diagnostics to the given line number. ---- - severity: See |diagnostic-severity|. ----@return vim.Diagnostic[] table A list of diagnostic items |diagnostic-structure|. Keys `bufnr`, `end_lnum`, `end_col`, and `severity` are guaranteed to be present. +--- current buffer or nil for all buffers. +---@param opts? vim.diagnostic.GetOpts +---@return vim.Diagnostic[] : Fields `bufnr`, `end_lnum`, `end_col`, and `severity` +--- are guaranteed to be present. function M.get(bufnr, opts) vim.validate({ bufnr = { bufnr, 'n', true }, @@ -962,11 +1032,9 @@ end --- ---@param bufnr? integer Buffer number to get diagnostics from. Use 0 for --- current buffer or nil for all buffers. ----@param opts? table A table with the following keys: ---- - namespace: (number) Limit diagnostics to the given namespace. ---- - lnum: (number) Limit diagnostics to the given line number. ---- - severity: See |diagnostic-severity|. ----@return table A table with actually present severity values as keys (see |diagnostic-severity|) and integer counts as values. +---@param opts? vim.diagnostic.GetOpts +---@return table : Table with actually present severity values as keys +--- (see |diagnostic-severity|) and integer counts as values. function M.count(bufnr, opts) vim.validate({ bufnr = { bufnr, 'n', true }, @@ -984,8 +1052,8 @@ end --- Get the previous diagnostic closest to the cursor position. --- ----@param opts? vim.diagnostic.GotoOpts (table) See |vim.diagnostic.goto_next()| ----@return vim.Diagnostic? Previous diagnostic +---@param opts? vim.diagnostic.GotoOpts +---@return vim.Diagnostic? : Previous diagnostic function M.get_prev(opts) opts = opts or {} @@ -998,9 +1066,9 @@ end --- Return the position of the previous diagnostic in the current buffer. --- ----@param opts? vim.diagnostic.GotoOpts (table) See |vim.diagnostic.goto_next()| ----@return table|false: Previous diagnostic position as a (row, col) tuple or false if there is no ---- prior diagnostic +---@param opts? vim.diagnostic.GotoOpts +---@return table|false: Previous diagnostic position as a `(row, col)` tuple +--- or `false` if there is no prior diagnostic. function M.get_prev_pos(opts) local prev = M.get_prev(opts) if not prev then @@ -1011,14 +1079,14 @@ function M.get_prev_pos(opts) end --- Move to the previous diagnostic in the current buffer. ----@param opts? vim.diagnostic.GotoOpts (table) See |vim.diagnostic.goto_next()| +---@param opts? vim.diagnostic.GotoOpts function M.goto_prev(opts) return diagnostic_move_pos(opts, M.get_prev_pos(opts)) end --- Get the next diagnostic closest to the cursor position. --- ----@param opts? vim.diagnostic.GotoOpts (table) See |vim.diagnostic.goto_next()| +---@param opts? vim.diagnostic.GotoOpts ---@return vim.Diagnostic? : Next diagnostic function M.get_next(opts) opts = opts or {} @@ -1032,8 +1100,8 @@ end --- Return the position of the next diagnostic in the current buffer. --- ----@param opts? vim.diagnostic.GotoOpts (table) See |vim.diagnostic.goto_next()| ----@return table|false : Next diagnostic position as a (row, col) tuple or false if no next +---@param opts? vim.diagnostic.GotoOpts +---@return table|false : Next diagnostic position as a `(row, col)` tuple or false if no next --- diagnostic. function M.get_next_pos(opts) local next = M.get_next(opts) @@ -1046,7 +1114,6 @@ end --- A table with the following keys: --- @class vim.diagnostic.GetOpts ---- @inlinedoc --- --- Limit diagnostics to the given namespace. --- @field namespace? integer @@ -1059,13 +1126,10 @@ end --- Configuration table with the following keys: --- @class vim.diagnostic.GotoOpts : vim.diagnostic.GetOpts ---- @inlinedoc ---- ---- Only consider diagnostics from the given namespace. ---- @field namespace integer --- ---- Cursor position as a (row, col) tuple. ---- See |nvim_win_get_cursor()|. Defaults to the current cursor position. +--- Cursor position as a `(row, col)` tuple. +--- See |nvim_win_get_cursor()|. +--- (default: current cursor position) --- @field cursor_position? {[1]:integer,[2]:integer} --- --- Whether to loop around file or not. Similar to 'wrapscan'. @@ -1075,11 +1139,10 @@ end --- See |diagnostic-severity|. --- @field severity vim.diagnostic.Severity --- ---- If "true", call |vim.diagnostic.open_float()| ---- after moving. If a table, pass the table as the {opts} parameter ---- to |vim.diagnostic.open_float()|. Unless overridden, the float will show ---- diagnostics at the new cursor position (as if "cursor" were passed to ---- the "scope" option). +--- If `true`, call |vim.diagnostic.open_float()| after moving. +--- If a table, pass the table as the {opts} parameter to |vim.diagnostic.open_float()|. +--- Unless overridden, the float will show diagnostics at the new cursor +--- position (as if "cursor" were passed to the "scope" option). --- (default: `true`) --- @field float? boolean|vim.diagnostic.Opts.Float --- @@ -1141,7 +1204,7 @@ M.handlers.signs = { -- Handle legacy diagnostic sign definitions -- These were deprecated in 0.10 and will be removed in 0.12 - if opts.signs and not opts.signs.text and not opts.signs.numhl and not opts.signs.texthl then + if opts.signs and not opts.signs.text and not opts.signs.numhl then for _, v in ipairs({ 'Error', 'Warn', 'Info', 'Hint' }) do local name = string.format('DiagnosticSign%s', v) local sign = vim.fn.sign_getdefined(name)[1] @@ -1476,7 +1539,7 @@ end --- without saving them or to display only a subset of --- diagnostics. May not be used when {namespace} --- or {bufnr} is nil. ----@param opts? vim.diagnostic.Opts (table) Display options. See |vim.diagnostic.config()|. +---@param opts? vim.diagnostic.Opts Display options. function M.show(namespace, bufnr, diagnostics, opts) vim.validate({ namespace = { namespace, 'n', true }, @@ -1552,46 +1615,7 @@ end --- Show diagnostics in a floating window. --- ----@param opts vim.diagnostic.Opts.Float? (table?) Configuration table with the same keys ---- as |vim.lsp.util.open_floating_preview()| in addition to the following: ---- - bufnr: (number) Buffer number to show diagnostics from. ---- Defaults to the current buffer. ---- - namespace: (number) Limit diagnostics to the given namespace ---- - scope: (string, default "line") Show diagnostics from the whole buffer ("buffer"), ---- the current cursor line ("line"), or the current cursor position ("cursor"). ---- Shorthand versions are also accepted ("c" for "cursor", "l" for "line", "b" ---- for "buffer"). ---- - pos: (number or table) If {scope} is "line" or "cursor", use this position rather ---- than the cursor position. If a number, interpreted as a line number; ---- otherwise, a (row, col) tuple. ---- - severity_sort: (default false) Sort diagnostics by severity. Overrides the setting ---- from |vim.diagnostic.config()|. ---- - severity: See |diagnostic-severity|. Overrides the setting ---- from |vim.diagnostic.config()|. ---- - header: (string or table) String to use as the header for the floating window. If a ---- table, it is interpreted as a [text, hl_group] tuple. Overrides the setting ---- from |vim.diagnostic.config()|. ---- - source: (boolean or string) Include the diagnostic source in the message. ---- Use "if_many" to only show sources if there is more than one source of ---- diagnostics in the buffer. Otherwise, any truthy value means to always show ---- the diagnostic source. Overrides the setting from |vim.diagnostic.config()|. ---- - format: (function) A function that takes a diagnostic as input and returns a ---- string. The return value is the text used to display the diagnostic. ---- Overrides the setting from |vim.diagnostic.config()|. ---- - prefix: (function, string, or table) Prefix each diagnostic in the floating ---- window. If a function, it must have the signature (diagnostic, i, ---- total) -> (string, string), where {i} is the index of the diagnostic ---- being evaluated and {total} is the total number of diagnostics ---- displayed in the window. The function should return a string which ---- is prepended to each diagnostic in the window as well as an ---- (optional) highlight group which will be used to highlight the ---- prefix. If {prefix} is a table, it is interpreted as a [text, ---- hl_group] tuple as in |nvim_echo()|; otherwise, if {prefix} is a ---- string, it is prepended to each diagnostic in the window with no ---- highlight. ---- Overrides the setting from |vim.diagnostic.config()|. ---- - suffix: Same as {prefix}, but appends the text to the diagnostic instead of ---- prepending it. Overrides the setting from |vim.diagnostic.config()|. +---@param opts vim.diagnostic.Opts.Float? ---@return integer? float_bufnr ---@return integer? win_id function M.open_float(opts, ...) @@ -1963,8 +1987,7 @@ end --- WARNING filename:27:3: Variable 'foo' does not exist --- ``` --- ---- This can be parsed into a diagnostic |diagnostic-structure| ---- with: +--- This can be parsed into |vim.Diagnostic| structure with: --- --- ```lua --- local s = "WARNING filename:27:3: Variable 'foo' does not exist" @@ -1975,14 +1998,14 @@ end --- ---@param str string String to parse diagnostics from. ---@param pat string Lua pattern with capture groups. ----@param groups string[] List of fields in a |diagnostic-structure| to +---@param groups string[] List of fields in a |vim.Diagnostic| structure to --- associate with captures from {pat}. ---@param severity_map table A table mapping the severity field from {groups} --- with an item from |vim.diagnostic.severity|. ---@param defaults table? Table of default values for any fields not listed in {groups}. --- When omitted, numeric values default to 0 and "severity" defaults to --- ERROR. ----@return vim.Diagnostic?: |diagnostic-structure| or `nil` if {pat} fails to match {str}. +---@return vim.Diagnostic?: |vim.Diagnostic| structure or `nil` if {pat} fails to match {str}. function M.match(str, pat, groups, severity_map, defaults) vim.validate({ str = { str, 's' }, @@ -2030,8 +2053,8 @@ local errlist_type_map = { --- Convert a list of diagnostics to a list of quickfix items that can be --- passed to |setqflist()| or |setloclist()|. --- ----@param diagnostics vim.Diagnostic[] List of diagnostics |diagnostic-structure|. ----@return table[] of quickfix list items |setqflist-what| +---@param diagnostics vim.Diagnostic[] +---@return table[] : Quickfix list items |setqflist-what| function M.toqflist(diagnostics) vim.validate({ diagnostics = { @@ -2071,7 +2094,7 @@ end --- Convert a list of quickfix items to a list of diagnostics. --- ---@param list table[] List of quickfix items from |getqflist()| or |getloclist()|. ----@return vim.Diagnostic[] array of |diagnostic-structure| +---@return vim.Diagnostic[] function M.fromqflist(list) vim.validate({ list = { -- cgit From ade1b12f49c3b3914c74847d791eb90ea90b56b7 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Fri, 8 Mar 2024 12:25:18 +0000 Subject: docs: support inline markdown - Tags are now created with `[tag]()` - References are now created with `[tag]` - Code spans are no longer wrapped --- runtime/lua/vim/diagnostic.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 9483474a40..d5075d7d3d 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -2,7 +2,7 @@ local api, if_nil = vim.api, vim.F.if_nil local M = {} ---- *diagnostic-structure* +--- [diagnostic-structure]() --- --- Diagnostics use the same indexing as the rest of the Nvim API (i.e. 0-based --- rows and columns). |api-indexing| @@ -68,7 +68,7 @@ local M = {} --- --- Update diagnostics in Insert mode --- (if `false`, diagnostics are updated on |InsertLeave|) ---- (default: `false) +--- (default: `false`) --- @field update_in_insert? boolean --- --- Sort diagnostics by severity. This affects the order in which signs and -- cgit