From fc6d713dd8066f3132f7234a94ac059ae6d596a7 Mon Sep 17 00:00:00 2001 From: Mayrom <32033791+nhruo123@users.noreply.github.com> Date: Wed, 27 Mar 2024 02:08:54 +0200 Subject: feat(diagnostic): add support for many namespaces filtering in GetOpts (#28045) --- runtime/lua/vim/diagnostic.lua | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index d5075d7d3d..57491d155d 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -682,6 +682,13 @@ local function get_diagnostics(bufnr, opts, clamp) opts = opts or {} local namespace = opts.namespace + + if type(namespace) == 'number' then + namespace = { namespace } + end + + ---@cast namespace integer[] + local diagnostics = {} -- Memoized results of buf_line_count per bufnr @@ -742,11 +749,15 @@ local function get_diagnostics(bufnr, opts, clamp) end elseif bufnr == nil then for b, t in pairs(diagnostic_cache) do - add_all_diags(b, t[namespace] or {}) + for _, iter_namespace in ipairs(namespace) do + add_all_diags(b, t[iter_namespace] or {}) + end end else bufnr = get_bufnr(bufnr) - add_all_diags(bufnr, diagnostic_cache[bufnr][namespace] or {}) + for _, iter_namespace in ipairs(namespace) do + add_all_diags(bufnr, diagnostic_cache[bufnr][iter_namespace] or {}) + end end if opts.severity then @@ -785,7 +796,7 @@ end --- @param search_forward boolean --- @param bufnr integer --- @param opts vim.diagnostic.GotoOpts ---- @param namespace integer +--- @param namespace integer[]|integer --- @return vim.Diagnostic? local function next_diagnostic(position, search_forward, bufnr, opts, namespace) position[1] = position[1] - 1 @@ -1115,8 +1126,8 @@ end --- A table with the following keys: --- @class vim.diagnostic.GetOpts --- ---- Limit diagnostics to the given namespace. ---- @field namespace? integer +--- Limit diagnostics to one or more namespaces. +--- @field namespace? integer[]|integer --- --- Limit diagnostics to the given line number. --- @field lnum? integer -- cgit From 26765e8461c1ba1e9a351632212cf89900221781 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 8 Apr 2024 00:41:41 +0200 Subject: feat(diagnostic): is_enabled, enable(…, enable:boolean) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: `vim.diagnostic.is_disabled` and `vim.diagnostic.disable` are unnecessary and inconsistent with the "toggle" pattern (established starting with `vim.lsp.inlay_hint`, see https://github.com/neovim/neovim/pull/25512#pullrequestreview-1676750276 As a reminder, the rationale is: - we always need `enable()` - we always end up needing `is_enabled()` - "toggle" can be achieved via `enable(not is_enabled())` - therefore, - `toggle()` and `disable()` are redundant - `is_disabled()` is a needless inconsistency Solution: - Introduce `vim.diagnostic.is_enabled`, and `vim.diagnostic.enable(…, enable:boolean)` - Note: Future improvement would be to add an `enable()` overload `enable(enable:boolean, opts: table)`. - Deprecate `vim.diagnostic.is_disabled`, `vim.diagnostic.disable` --- runtime/lua/vim/diagnostic.lua | 132 +++++++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 59 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 57491d155d..26374aa055 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -1492,7 +1492,7 @@ end --- diagnostics, use |vim.diagnostic.reset()|. --- --- To hide diagnostics and prevent them from re-displaying, use ---- |vim.diagnostic.disable()|. +--- |vim.diagnostic.enable()|. --- ---@param namespace integer? Diagnostic namespace. When omitted, hide --- diagnostics from all namespaces. @@ -1517,25 +1517,35 @@ function M.hide(namespace, bufnr) end end ---- Check whether diagnostics are disabled in a given buffer. +--- Check whether diagnostics are enabled. --- ----@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) +--- @param bufnr integer? Buffer number, or 0 for current buffer. +--- @param namespace integer? Diagnostic namespace, or `nil` for all diagnostics in {bufnr}. +--- @return boolean +--- @since 12 +function M.is_enabled(bufnr, namespace) bufnr = get_bufnr(bufnr) if namespace and M.get_namespace(namespace).disabled then - return true + return false end if type(diagnostic_disabled[bufnr]) == 'table' then - return diagnostic_disabled[bufnr][namespace] + return not diagnostic_disabled[bufnr][namespace] end - return diagnostic_disabled[bufnr] ~= nil + return diagnostic_disabled[bufnr] == nil +end + +--- @deprecated use `vim.diagnostic.is_enabled()` +function M.is_disabled(bufnr, namespace) + vim.deprecate( + 'Defining diagnostic signs with :sign-define or sign_define()', + 'vim.diagnostic.is_enabled()', + '0.12', + nil, + false + ) + return not M.is_enabled(bufnr, namespace) end --- Display diagnostics for the given namespace and buffer. @@ -1923,71 +1933,75 @@ function M.setloclist(opts) set_list(true, opts) end ---- Disable diagnostics in the given buffer. ---- ----@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. +--- @deprecated use `vim.diagnostic.enabled(…, false)` function M.disable(bufnr, namespace) - vim.validate({ bufnr = { bufnr, 'n', true }, namespace = { namespace, 'n', true } }) - if bufnr == nil then - if namespace == nil then - -- Disable everything (including as yet non-existing buffers and - -- namespaces) by setting diagnostic_disabled to an empty table and set - -- its metatable to always return true. This metatable is removed - -- in enable() - diagnostic_disabled = setmetatable({}, { - __index = function() - return true - end, - }) - else - local ns = M.get_namespace(namespace) - ns.disabled = true - end - else - bufnr = get_bufnr(bufnr) - if namespace == nil then - diagnostic_disabled[bufnr] = true - else - if type(diagnostic_disabled[bufnr]) ~= 'table' then - diagnostic_disabled[bufnr] = {} - end - diagnostic_disabled[bufnr][namespace] = true - end - end - - M.hide(namespace, bufnr) + vim.deprecate( + 'vim.diagnostic.disable()', + 'vim.diagnostic.enabled(…, false)', + '0.12', + nil, + false + ) + M.enable(bufnr, namespace, false) end ---- Enable diagnostics in the given buffer. +--- Enables or disables diagnostics. --- ----@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 } }) +--- To "toggle", pass the inverse of `is_enabled()`: +--- +--- ```lua +--- vim.diagnostic.enable(0, not vim.diagnostic.is_enabled()) +--- ``` +--- +--- @param bufnr integer? Buffer number, or 0 for current buffer, or `nil` for all buffers. +--- @param namespace integer? Only for the given namespace, or `nil` for all. +--- @param enable (boolean|nil) true/nil to enable, false to disable +function M.enable(bufnr, namespace, enable) + vim.validate({ + bufnr = { bufnr, 'n', true }, + namespace = { namespace, 'n', true }, + enable = { enable, 'b', true }, + }) + enable = enable == nil and true or enable if bufnr == nil then if namespace == nil then - -- Enable everything by setting diagnostic_disabled to an empty table - diagnostic_disabled = {} + diagnostic_disabled = ( + enable + -- Enable everything by setting diagnostic_disabled to an empty table. + and {} + -- Disable everything (including as yet non-existing buffers and namespaces) by setting + -- diagnostic_disabled to an empty table and set its metatable to always return true. + or setmetatable({}, { + __index = function() + return true + end, + }) + ) else local ns = M.get_namespace(namespace) - ns.disabled = false + ns.disabled = not enable end else bufnr = get_bufnr(bufnr) if namespace == nil then - diagnostic_disabled[bufnr] = nil + diagnostic_disabled[bufnr] = (not enable) and true or nil else if type(diagnostic_disabled[bufnr]) ~= 'table' then - return + if enable then + return + else + diagnostic_disabled[bufnr] = {} + end end - diagnostic_disabled[bufnr][namespace] = nil + diagnostic_disabled[bufnr][namespace] = (not enable) and true or nil end end - M.show(namespace, bufnr) + if enable then + M.show(namespace, bufnr) + else + M.hide(namespace, bufnr) + end end --- Parse a diagnostic from a string. -- cgit From 5ed9916a28b9a09d2e5629f3e4e5b0e81403ded7 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 15 Apr 2024 18:35:59 +0200 Subject: feat(diagnostic): enable(…, opts) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: vim.diagnostic.enable() does not match the signature of vim.lsp.inlay_hint.enable() Solution: - Change the signature so that the first 2 args are (bufnr, enable). - Introduce a 3rd `opts` arg. - Currently it only supports `opts.ns_id`. --- runtime/lua/vim/diagnostic.lua | 67 ++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 19 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 26374aa055..4fcbfa7507 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -239,6 +239,9 @@ local M = {} --- whole line the sign is placed in. --- @field linehl? table +--- @class vim.diagnostic.Filter : vim.diagnostic.Opts +--- @field ns_id? integer Namespace + --- @nodoc --- @enum vim.diagnostic.Severity M.severity = { @@ -1538,13 +1541,7 @@ end --- @deprecated use `vim.diagnostic.is_enabled()` function M.is_disabled(bufnr, namespace) - vim.deprecate( - 'Defining diagnostic signs with :sign-define or sign_define()', - 'vim.diagnostic.is_enabled()', - '0.12', - nil, - false - ) + vim.deprecate('vim.diagnostic.is_disabled()', 'vim.diagnostic.is_enabled()', '0.12', nil, false) return not M.is_enabled(bufnr, namespace) end @@ -1591,7 +1588,7 @@ function M.show(namespace, bufnr, diagnostics, opts) return end - if M.is_disabled(bufnr, namespace) then + if not M.is_enabled(bufnr, namespace) then return end @@ -1942,7 +1939,7 @@ function M.disable(bufnr, namespace) nil, false ) - M.enable(bufnr, namespace, false) + M.enable(bufnr, false, { ns_id = namespace }) end --- Enables or disables diagnostics. @@ -1954,17 +1951,49 @@ end --- ``` --- --- @param bufnr integer? Buffer number, or 0 for current buffer, or `nil` for all buffers. ---- @param namespace integer? Only for the given namespace, or `nil` for all. --- @param enable (boolean|nil) true/nil to enable, false to disable -function M.enable(bufnr, namespace, enable) +--- @param opts vim.diagnostic.Filter? Filter by these opts, or `nil` for all. Only `ns_id` is +--- supported, currently. +function M.enable(bufnr, enable, opts) + opts = opts or {} + if type(enable) == 'number' then + -- Legacy signature. + vim.deprecate( + 'vim.diagnostic.enable(buf:number, namespace)', + 'vim.diagnostic.enable(buf:number, enable:boolean, opts)', + '0.12', + nil, + false + ) + opts.ns_id = enable + enable = true + end vim.validate({ bufnr = { bufnr, 'n', true }, - namespace = { namespace, 'n', true }, - enable = { enable, 'b', true }, + enable = { + enable, + function(o) + return o == nil or type(o) == 'boolean' or type(o) == 'number' + end, + 'boolean or number (deprecated)', + }, + opts = { + opts, + function(o) + return o == nil + or ( + type(o) == 'table' + -- TODO(justinmk): support other `vim.diagnostic.Filter` fields. + and (vim.tbl_isempty(o) or vim.deep_equal(vim.tbl_keys(o), { 'ns_id' })) + ) + end, + 'vim.diagnostic.Filter table (only ns_id is supported currently)', + }, }) enable = enable == nil and true or enable + if bufnr == nil then - if namespace == nil then + if opts.ns_id == nil then diagnostic_disabled = ( enable -- Enable everything by setting diagnostic_disabled to an empty table. @@ -1978,12 +2007,12 @@ function M.enable(bufnr, namespace, enable) }) ) else - local ns = M.get_namespace(namespace) + local ns = M.get_namespace(opts.ns_id) ns.disabled = not enable end else bufnr = get_bufnr(bufnr) - if namespace == nil then + if opts.ns_id == nil then diagnostic_disabled[bufnr] = (not enable) and true or nil else if type(diagnostic_disabled[bufnr]) ~= 'table' then @@ -1993,14 +2022,14 @@ function M.enable(bufnr, namespace, enable) diagnostic_disabled[bufnr] = {} end end - diagnostic_disabled[bufnr][namespace] = (not enable) and true or nil + diagnostic_disabled[bufnr][opts.ns_id] = (not enable) and true or nil end end if enable then - M.show(namespace, bufnr) + M.show(opts.ns_id, bufnr) else - M.hide(namespace, bufnr) + M.hide(opts.ns_id, bufnr) end end -- cgit From f1dfe32bf5552197e0068298b0527526a4f918b1 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 18 Apr 2024 07:57:58 -0700 Subject: feat(lua): enable(enable:boolean, filter:table) #28374 Problem: We need to establish a pattern for `enable()`. Solution: - First `enable()` parameter is always `enable:boolean`. - Update `vim.diagnostic.enable()` - Update `vim.lsp.inlay_hint.enable()`. - It was not released yet, so no deprecation is needed. But to help HEAD users, it will show an informative error. - vim.deprecate(): - Improve message when the "removal version" is a *current or older* version. --- runtime/lua/vim/diagnostic.lua | 109 ++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 51 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 4fcbfa7507..6233bb7058 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -239,8 +239,16 @@ local M = {} --- whole line the sign is placed in. --- @field linehl? table ---- @class vim.diagnostic.Filter : vim.diagnostic.Opts ---- @field ns_id? integer Namespace +-- TODO: inherit from `vim.diagnostic.Opts`, implement its fields. +--- Optional filters |kwargs|, or `nil` for all. +--- @class vim.diagnostic.Filter +--- @inlinedoc +--- +--- Diagnostic namespace, or `nil` for all. +--- @field ns_id? integer +--- +--- Buffer number, or 0 for current buffer, or `nil` for all buffers. +--- @field bufnr? integer --- @nodoc --- @enum vim.diagnostic.Severity @@ -1522,18 +1530,21 @@ end --- Check whether diagnostics are enabled. --- ---- @param bufnr integer? Buffer number, or 0 for current buffer. ---- @param namespace integer? Diagnostic namespace, or `nil` for all diagnostics in {bufnr}. +--- @param filter vim.diagnostic.Filter? --- @return boolean --- @since 12 -function M.is_enabled(bufnr, namespace) - bufnr = get_bufnr(bufnr) - if namespace and M.get_namespace(namespace).disabled then +function M.is_enabled(filter) + filter = filter or {} + if filter.ns_id and M.get_namespace(filter.ns_id).disabled then return false + elseif filter.bufnr == nil then + -- See enable() logic. + return vim.tbl_isempty(diagnostic_disabled) and not diagnostic_disabled[1] end + local bufnr = get_bufnr(filter.bufnr) if type(diagnostic_disabled[bufnr]) == 'table' then - return not diagnostic_disabled[bufnr][namespace] + return not diagnostic_disabled[bufnr][filter.ns_id] end return diagnostic_disabled[bufnr] == nil @@ -1542,7 +1553,7 @@ end --- @deprecated use `vim.diagnostic.is_enabled()` function M.is_disabled(bufnr, namespace) vim.deprecate('vim.diagnostic.is_disabled()', 'vim.diagnostic.is_enabled()', '0.12', nil, false) - return not M.is_enabled(bufnr, namespace) + return not M.is_enabled { bufnr = bufnr or 0, ns_id = namespace } end --- Display diagnostics for the given namespace and buffer. @@ -1588,7 +1599,7 @@ function M.show(namespace, bufnr, diagnostics, opts) return end - if not M.is_enabled(bufnr, namespace) then + if not M.is_enabled { bufnr = bufnr or 0, ns_id = namespace } then return end @@ -1934,12 +1945,12 @@ end function M.disable(bufnr, namespace) vim.deprecate( 'vim.diagnostic.disable()', - 'vim.diagnostic.enabled(…, false)', + 'vim.diagnostic.enabled(false, …)', '0.12', nil, false ) - M.enable(bufnr, false, { ns_id = namespace }) + M.enable(false, { bufnr = bufnr, ns_id = namespace }) end --- Enables or disables diagnostics. @@ -1947,53 +1958,49 @@ end --- To "toggle", pass the inverse of `is_enabled()`: --- --- ```lua ---- vim.diagnostic.enable(0, not vim.diagnostic.is_enabled()) +--- vim.diagnostic.enable(not vim.diagnostic.is_enabled()) --- ``` --- ---- @param bufnr integer? Buffer number, or 0 for current buffer, or `nil` for all buffers. --- @param enable (boolean|nil) true/nil to enable, false to disable ---- @param opts vim.diagnostic.Filter? Filter by these opts, or `nil` for all. Only `ns_id` is ---- supported, currently. -function M.enable(bufnr, enable, opts) - opts = opts or {} - if type(enable) == 'number' then - -- Legacy signature. +--- @param filter vim.diagnostic.Filter? +function M.enable(enable, filter) + -- Deprecated signature. Drop this in 0.12 + local legacy = (enable or filter) + and vim.tbl_contains({ 'number', 'nil' }, type(enable)) + and vim.tbl_contains({ 'number', 'nil' }, type(filter)) + + if legacy then vim.deprecate( - 'vim.diagnostic.enable(buf:number, namespace)', - 'vim.diagnostic.enable(buf:number, enable:boolean, opts)', + 'vim.diagnostic.enable(buf:number, namespace:number)', + 'vim.diagnostic.enable(enable:boolean, filter:table)', '0.12', nil, false ) - opts.ns_id = enable + + vim.validate({ + enable = { enable, 'n', true }, -- Legacy `bufnr` arg. + filter = { filter, 'n', true }, -- Legacy `namespace` arg. + }) + + local ns_id = type(filter) == 'number' and filter or nil + filter = {} + filter.ns_id = ns_id + filter.bufnr = type(enable) == 'number' and enable or nil enable = true + else + filter = filter or {} + vim.validate({ + enable = { enable, 'b', true }, + filter = { filter, 't', true }, + }) end - vim.validate({ - bufnr = { bufnr, 'n', true }, - enable = { - enable, - function(o) - return o == nil or type(o) == 'boolean' or type(o) == 'number' - end, - 'boolean or number (deprecated)', - }, - opts = { - opts, - function(o) - return o == nil - or ( - type(o) == 'table' - -- TODO(justinmk): support other `vim.diagnostic.Filter` fields. - and (vim.tbl_isempty(o) or vim.deep_equal(vim.tbl_keys(o), { 'ns_id' })) - ) - end, - 'vim.diagnostic.Filter table (only ns_id is supported currently)', - }, - }) + enable = enable == nil and true or enable + local bufnr = filter.bufnr if bufnr == nil then - if opts.ns_id == nil then + if filter.ns_id == nil then diagnostic_disabled = ( enable -- Enable everything by setting diagnostic_disabled to an empty table. @@ -2007,12 +2014,12 @@ function M.enable(bufnr, enable, opts) }) ) else - local ns = M.get_namespace(opts.ns_id) + local ns = M.get_namespace(filter.ns_id) ns.disabled = not enable end else bufnr = get_bufnr(bufnr) - if opts.ns_id == nil then + if filter.ns_id == nil then diagnostic_disabled[bufnr] = (not enable) and true or nil else if type(diagnostic_disabled[bufnr]) ~= 'table' then @@ -2022,14 +2029,14 @@ function M.enable(bufnr, enable, opts) diagnostic_disabled[bufnr] = {} end end - diagnostic_disabled[bufnr][opts.ns_id] = (not enable) and true or nil + diagnostic_disabled[bufnr][filter.ns_id] = (not enable) and true or nil end end if enable then - M.show(opts.ns_id, bufnr) + M.show(filter.ns_id, bufnr) else - M.hide(opts.ns_id, bufnr) + M.hide(filter.ns_id, bufnr) end end -- cgit From d9d890562e43493c999f8a6ff2b848959686f5b6 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 21 Apr 2024 15:19:43 +0200 Subject: refactor(lua): rename tbl_islist => islist ref #24572 --- runtime/lua/vim/diagnostic.lua | 14 +++++++------- 1 file changed, 7 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 6233bb7058..5e4835ab88 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -974,7 +974,7 @@ function M.set(namespace, bufnr, diagnostics, opts) bufnr = { bufnr, 'n' }, diagnostics = { diagnostics, - vim.tbl_islist, + vim.islist, 'a list of diagnostics', }, opts = { opts, 't', true }, @@ -1186,7 +1186,7 @@ M.handlers.signs = { bufnr = { bufnr, 'n' }, diagnostics = { diagnostics, - vim.tbl_islist, + vim.islist, 'a list of diagnostics', }, opts = { opts, 't', true }, @@ -1309,7 +1309,7 @@ M.handlers.underline = { bufnr = { bufnr, 'n' }, diagnostics = { diagnostics, - vim.tbl_islist, + vim.islist, 'a list of diagnostics', }, opts = { opts, 't', true }, @@ -1382,7 +1382,7 @@ M.handlers.virtual_text = { bufnr = { bufnr, 'n' }, diagnostics = { diagnostics, - vim.tbl_islist, + vim.islist, 'a list of diagnostics', }, opts = { opts, 't', true }, @@ -1576,7 +1576,7 @@ function M.show(namespace, bufnr, diagnostics, opts) diagnostics = { diagnostics, function(v) - return v == nil or vim.tbl_islist(v) + return v == nil or vim.islist(v) end, 'a list of diagnostics', }, @@ -2120,7 +2120,7 @@ function M.toqflist(diagnostics) vim.validate({ diagnostics = { diagnostics, - vim.tbl_islist, + vim.islist, 'a list of diagnostics', }, }) @@ -2160,7 +2160,7 @@ function M.fromqflist(list) vim.validate({ list = { list, - vim.tbl_islist, + vim.islist, 'a list of quickfix items', }, }) -- cgit From ad76b050eb2cd03174c108b5ae6759b3c1ea8941 Mon Sep 17 00:00:00 2001 From: Raphael Date: Tue, 23 Apr 2024 19:06:41 +0800 Subject: fix(diagnostic): open_float on multi-line diagnostics #28301 Problem: when diagnostic have a range of line, open_float not work. Solution: filter diagnostic by line number range. --- 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 5e4835ab88..7371b5241f 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -1697,7 +1697,7 @@ function M.open_float(opts, ...) if scope == 'line' then --- @param d vim.Diagnostic diagnostics = vim.tbl_filter(function(d) - return d.lnum == lnum + return lnum >= d.lnum and lnum <= d.end_lnum end, diagnostics) elseif scope == 'cursor' then -- LSP servers can send diagnostics with `end_col` past the length of the line -- cgit From a4fc3bb0e68c8b078377fd9826e4cca3b4b3fdbf Mon Sep 17 00:00:00 2001 From: Raphael Date: Tue, 23 Apr 2024 19:13:58 +0800 Subject: fix(diagnostic): vim.diagnostic.get(…,{lnum=…}) on multi-line diagnostic #28273 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: vim.diagnostic.get(…,{lnum=…}) does not match multi-line diagnostics. Solution: add end_lnum support. --- 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 7371b5241f..b42eece4c2 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -717,7 +717,7 @@ local function get_diagnostics(bufnr, opts, clamp) ---@param b integer ---@param d vim.Diagnostic local function add(b, d) - if not opts.lnum or d.lnum == opts.lnum then + if not opts.lnum or (opts.lnum >= d.lnum and opts.lnum <= (d.end_lnum or d.lnum)) then if clamp and api.nvim_buf_is_loaded(b) then local line_count = buf_line_count[b] - 1 if @@ -1140,7 +1140,7 @@ end --- Limit diagnostics to one or more namespaces. --- @field namespace? integer[]|integer --- ---- Limit diagnostics to the given line number. +--- Limit diagnostics to those spanning the specified line number. --- @field lnum? integer --- --- See |diagnostic-severity|. -- cgit From 7f084770c23855083776b0598f2f54bb59a06875 Mon Sep 17 00:00:00 2001 From: Mathias Fußenegger Date: Wed, 24 Apr 2024 21:47:02 +0200 Subject: perf(diagnostic): avoid table copies to filter by severity (#28491) Instead of adding all diagnostics matching lnum filters to a table, and then copying that table to another table while applying the severity filter, this changes the flow to only add diagnostics matching both filters in the first pass. --- runtime/lua/vim/diagnostic.lua | 59 +++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 26 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index b42eece4c2..3321b6ad71 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -372,43 +372,46 @@ local function to_severity(severity) end --- @param severity vim.diagnostic.SeverityFilter ---- @param diagnostics vim.Diagnostic[] ---- @return vim.Diagnostic[] -local function filter_by_severity(severity, diagnostics) - if not severity then - return diagnostics - end - +--- @return fun(vim.Diagnostic):boolean +local function severity_predicate(severity) if type(severity) ~= 'table' then severity = assert(to_severity(severity)) - --- @param t vim.Diagnostic - return vim.tbl_filter(function(t) - return t.severity == severity - end, diagnostics) + ---@param d vim.Diagnostic + return function(d) + return d.severity == severity + end 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) + --- @param d vim.Diagnostic + return function(d) + return d.severity <= min_severity and d.severity >= max_severity + end end --- @cast severity vim.diagnostic.Severity[] - local severities = {} --- @type table for _, s in ipairs(severity) do severities[assert(to_severity(s))] = true end - --- @param t vim.Diagnostic - return vim.tbl_filter(function(t) - return severities[t.severity] - end, diagnostics) + --- @param d vim.Diagnostic + return function(d) + return severities[d.severity] + end +end + +--- @param severity vim.diagnostic.SeverityFilter +--- @param diagnostics vim.Diagnostic[] +--- @return vim.Diagnostic[] +local function filter_by_severity(severity, diagnostics) + if not severity then + return diagnostics + end + return vim.tbl_filter(severity_predicate(severity), diagnostics) end --- @param bufnr integer @@ -714,10 +717,18 @@ local function get_diagnostics(bufnr, opts, clamp) end, }) + local match_severity = opts.severity and severity_predicate(opts.severity) + or function(_) + return true + end + ---@param b integer ---@param d vim.Diagnostic local function add(b, d) - if not opts.lnum or (opts.lnum >= d.lnum and opts.lnum <= (d.end_lnum or d.lnum)) then + if + match_severity(d) + and (not opts.lnum or (opts.lnum >= d.lnum and opts.lnum <= (d.end_lnum or d.lnum))) + then if clamp and api.nvim_buf_is_loaded(b) then local line_count = buf_line_count[b] - 1 if @@ -771,10 +782,6 @@ local function get_diagnostics(bufnr, opts, clamp) end end - if opts.severity then - diagnostics = filter_by_severity(opts.severity, diagnostics) - end - return diagnostics end -- cgit From b13e63db1dbc1dbc7e23690653df1b7317660a2b Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Thu, 25 Apr 2024 08:07:44 -0500 Subject: feat(diagnostic): goto functions jump to highest severity (#28490) When the "severity" option is nil, vim.diagnostic.goto_next() and vim.diagnostic.goto_prev() jump to the next diagnostic with the highest severity. --- runtime/lua/vim/diagnostic.lua | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 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 3321b6ad71..1ae370e9b2 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -820,11 +820,35 @@ local function next_diagnostic(position, search_forward, bufnr, opts, namespace) position[1] = position[1] - 1 bufnr = get_bufnr(bufnr) 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) + + -- When severity is unset we jump to the diagnostic with the highest severity. First sort the + -- diagnostics by severity. The first diagnostic then contains the highest severity, and we can + -- discard all diagnostics with a lower severity. + if opts.severity == nil then + table.sort(diagnostics, function(a, b) + return a.severity < b.severity + end) + + -- Find the first diagnostic where the severity does not match the highest severity, and remove + -- that element and all subsequent elements from the array + local worst = (diagnostics[1] or {}).severity + local len = #diagnostics + for i = 2, len do + if diagnostics[i].severity ~= worst then + for j = i, len do + diagnostics[j] = nil + end + break + end + end + end + local line_diagnostics = diagnostic_lines(diagnostics) + local line_count = api.nvim_buf_line_count(bufnr) for i = 0, line_count do local offset = i * (search_forward and 1 or -1) local lnum = position[1] + offset @@ -1165,8 +1189,8 @@ end --- (default: `true`) --- @field wrap? boolean --- ---- See |diagnostic-severity|. ---- @field severity vim.diagnostic.Severity +--- See |diagnostic-severity|. If `nil`, go to the diagnostic with the highest 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()|. -- cgit From 96f59e1b9902f7622eaaea02eea0329a88b98202 Mon Sep 17 00:00:00 2001 From: Raphael Date: Sun, 28 Apr 2024 05:05:41 +0800 Subject: fix(diagnostic): invalid col number compare in next_diagnostic (#28397) Problem: when line is blank link then there will got an invalid column number in math.min compare. Solution: make sure the min column number is 0 not an illegal number. --- 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 1ae370e9b2..9f1e6448e6 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -867,14 +867,14 @@ local function next_diagnostic(position, search_forward, bufnr, opts, namespace) return a.col < b.col end is_next = function(d) - return math.min(d.col, line_length - 1) > position[2] + return math.min(d.col, math.max(line_length - 1, 0)) > position[2] end else sort_diagnostics = function(a, b) return a.col > b.col end is_next = function(d) - return math.min(d.col, line_length - 1) < position[2] + return math.min(d.col, math.max(line_length - 1, 0)) < position[2] end end table.sort(line_diagnostics[lnum], sort_diagnostics) -- cgit From 83635e4e3db9a99c128e84e79deb590da354215d Mon Sep 17 00:00:00 2001 From: glepnir Date: Sun, 28 Apr 2024 23:15:10 +0800 Subject: fix(diagnostic): get border from config (#28531) Co-authored-by: Justin M. Keyes Co-authored-by: Gregory Anders --- 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 9f1e6448e6..1ed09b51a5 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -152,6 +152,8 @@ local M = {} --- @field suffix? string|table|(fun(diagnostic:vim.Diagnostic,i:integer,total:integer): string, string) --- --- @field focus_id? string +--- +--- @field border? string see |vim.api.nvim_open_win()|. --- @class vim.diagnostic.Opts.Underline --- -- cgit From 61063653b06bfccac083c0105ecd0c433b3bb8f7 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 28 Apr 2024 09:02:18 -0700 Subject: feat(defaults): visual CTRL-R for LSP mappings #28537 Problem: The new LSP "refactor menu" keybinding "crr" is also defined in visual mode, which overlaps with the builtin "c". Solution: Use CTRL-R instead of "crr" for visual mode. fix #28528 --- 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 1ed09b51a5..b34541c72e 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -153,7 +153,7 @@ local M = {} --- --- @field focus_id? string --- ---- @field border? string see |vim.api.nvim_open_win()|. +--- @field border? string see |nvim_open_win()|. --- @class vim.diagnostic.Opts.Underline --- -- cgit From ee41153a945876ad0c7f0927ffa7b5a5afdaca89 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Tue, 30 Apr 2024 09:57:31 +0100 Subject: feat(diagnostic): revert default behaviour of goto_next/prev() Follow-up to #28490 Problem: The new behaviour of goto_next/prev() of navigating to the next highest severity doesn't work well when diagnostic providers have different interpretations of severities. E.g. the user may be blocked from navigating to a useful LSP warning, due to some linter error. Solution: The behaviour of next highest severity is now a hidden option `_highest = true`. We can revisit how to integrate this behaviour during the 0.11 cycle. --- runtime/lua/vim/diagnostic.lua | 59 +++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 24 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index b34541c72e..67ce331891 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -76,7 +76,7 @@ local M = {} --- before lower severities (e.g. ERROR is displayed before WARN). --- Options: --- - {reverse}? (boolean) Reverse sort order ---- (default: `false) +--- (default: `false`) --- @field severity_sort? boolean|{reverse?:boolean} --- @class (private) vim.diagnostic.OptsResolved @@ -812,6 +812,29 @@ local function set_list(loclist, opts) end end +--- Jump to the diagnostic with the highest severity. First sort the +--- diagnostics by severity. The first diagnostic then contains the highest severity, and we can +--- discard all diagnostics with a lower severity. +--- @param diagnostics vim.Diagnostic[] +local function filter_highest(diagnostics) + table.sort(diagnostics, function(a, b) + return a.severity < b.severity + end) + + -- Find the first diagnostic where the severity does not match the highest severity, and remove + -- that element and all subsequent elements from the array + local worst = (diagnostics[1] or {}).severity + local len = #diagnostics + for i = 2, len do + if diagnostics[i].severity ~= worst then + for j = i, len do + diagnostics[j] = nil + end + break + end + end +end + --- @param position {[1]: integer, [2]: integer} --- @param search_forward boolean --- @param bufnr integer @@ -823,29 +846,13 @@ local function next_diagnostic(position, search_forward, bufnr, opts, namespace) bufnr = get_bufnr(bufnr) local wrap = if_nil(opts.wrap, true) - local diagnostics = - get_diagnostics(bufnr, vim.tbl_extend('keep', opts, { namespace = namespace }), true) + local get_opts = vim.deepcopy(opts) + get_opts.namespace = get_opts.namespace or namespace - -- When severity is unset we jump to the diagnostic with the highest severity. First sort the - -- diagnostics by severity. The first diagnostic then contains the highest severity, and we can - -- discard all diagnostics with a lower severity. - if opts.severity == nil then - table.sort(diagnostics, function(a, b) - return a.severity < b.severity - end) + local diagnostics = get_diagnostics(bufnr, get_opts, true) - -- Find the first diagnostic where the severity does not match the highest severity, and remove - -- that element and all subsequent elements from the array - local worst = (diagnostics[1] or {}).severity - local len = #diagnostics - for i = 2, len do - if diagnostics[i].severity ~= worst then - for j = i, len do - diagnostics[j] = nil - end - break - end - end + if opts._highest then + filter_highest(diagnostics) end local line_diagnostics = diagnostic_lines(diagnostics) @@ -1191,8 +1198,12 @@ end --- (default: `true`) --- @field wrap? boolean --- ---- See |diagnostic-severity|. If `nil`, go to the diagnostic with the highest severity. ---- @field severity? vim.diagnostic.Severity +--- See |diagnostic-severity|. +--- @field severity? vim.diagnostic.SeverityFilter +--- +--- Go to the diagnostic with the highest severity. +--- (default: `false`) +--- @field package _highest? boolean --- --- If `true`, call |vim.diagnostic.open_float()| after moving. --- If a table, pass the table as the {opts} parameter to |vim.diagnostic.open_float()|. -- cgit From b5c3687b6ddae8952510bdbbfa8be577de7edf05 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Thu, 16 May 2024 11:37:46 +0200 Subject: docs: misc (#28761) Co-authored-by: Florian Zeitz --- runtime/lua/vim/diagnostic.lua | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 67ce331891..1992a4000d 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -1985,15 +1985,9 @@ function M.setloclist(opts) set_list(true, opts) end ---- @deprecated use `vim.diagnostic.enabled(…, false)` +--- @deprecated use `vim.diagnostic.enable(false, …)` function M.disable(bufnr, namespace) - vim.deprecate( - 'vim.diagnostic.disable()', - 'vim.diagnostic.enabled(false, …)', - '0.12', - nil, - false - ) + vim.deprecate('vim.diagnostic.disable()', 'vim.diagnostic.enable(false, …)', '0.12', nil, false) M.enable(false, { bufnr = bufnr, ns_id = namespace }) end -- cgit From 9a43ec13e6f1c7b52bab3304d855c680cc3ed7bd Mon Sep 17 00:00:00 2001 From: Jongwook Choi Date: Fri, 17 May 2024 19:16:09 -0400 Subject: fix(diagnostic): show backtrace for deprecation warnings Problem: On nvim 11.0-dev, deprecation warnings due to an use of hard-deprecated APIs such as: - `vim.diagnostic.disable()` - `vim.diagnostic.is_disabled()` etc. are not accompanied by backtrace information. It makes difficult for users to figure out which lines or which plugins are still using deprecated APIs. Solution: use `backtrace = true` in vim.deprecate() call. --- runtime/lua/vim/diagnostic.lua | 10 ++++------ 1 file changed, 4 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 1992a4000d..b5146e5beb 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -1281,7 +1281,7 @@ M.handlers.signs = { 'vim.diagnostic.config()', '0.12', nil, - false + false -- suppress backtrace ) if not opts.signs.text then @@ -1596,7 +1596,7 @@ end --- @deprecated use `vim.diagnostic.is_enabled()` function M.is_disabled(bufnr, namespace) - vim.deprecate('vim.diagnostic.is_disabled()', 'vim.diagnostic.is_enabled()', '0.12', nil, false) + vim.deprecate('vim.diagnostic.is_disabled()', 'vim.diagnostic.is_enabled()', '0.12') return not M.is_enabled { bufnr = bufnr or 0, ns_id = namespace } end @@ -1987,7 +1987,7 @@ end --- @deprecated use `vim.diagnostic.enable(false, …)` function M.disable(bufnr, namespace) - vim.deprecate('vim.diagnostic.disable()', 'vim.diagnostic.enable(false, …)', '0.12', nil, false) + vim.deprecate('vim.diagnostic.disable()', 'vim.diagnostic.enable(false, …)', '0.12') M.enable(false, { bufnr = bufnr, ns_id = namespace }) end @@ -2011,9 +2011,7 @@ function M.enable(enable, filter) vim.deprecate( 'vim.diagnostic.enable(buf:number, namespace:number)', 'vim.diagnostic.enable(enable:boolean, filter:table)', - '0.12', - nil, - false + '0.12' ) vim.validate({ -- cgit From d123202ae6ef3f046d5b6579c194dca82ddb8a8f Mon Sep 17 00:00:00 2001 From: dundargoc Date: Thu, 16 May 2024 18:33:09 +0200 Subject: fix: change deprecation presentation Deprecation with vim.deprecate is currently too noisy. Show the following warning instead: [function] is deprecated. Run ":checkhealth vim.deprecated" for more information. The important part is that the full message needs to be short enough to fit in one line in order to not trigger the "Press ENTER or type command to continue" prompt. The full information and stack trace for the deprecated functions will be shown in the new healthcheck `vim.deprecated`. --- runtime/lua/vim/diagnostic.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'runtime/lua/vim/diagnostic.lua') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index b5146e5beb..348204abb7 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -1279,9 +1279,7 @@ M.handlers.signs = { vim.deprecate( 'Defining diagnostic signs with :sign-define or sign_define()', 'vim.diagnostic.config()', - '0.12', - nil, - false -- suppress backtrace + '0.12' ) if not opts.signs.text then -- cgit