aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaria José Solano <majosolano99@gmail.com>2025-02-03 00:54:31 -0800
committerGitHub <noreply@github.com>2025-02-03 00:54:31 -0800
commit445ecca398401ab9cdada163865db6dee374dde3 (patch)
treebb5212329c4519924bd51c6aa649d978d288beec
parent3a2893015759396e5345a1a85e0427705e0570b4 (diff)
downloadrneovim-445ecca398401ab9cdada163865db6dee374dde3.tar.gz
rneovim-445ecca398401ab9cdada163865db6dee374dde3.tar.bz2
rneovim-445ecca398401ab9cdada163865db6dee374dde3.zip
feat(diagnostic): format() can filter diagnostics by returning nil #32302
-rw-r--r--runtime/doc/develop.txt4
-rw-r--r--runtime/doc/diagnostic.txt28
-rw-r--r--runtime/lua/vim/diagnostic.lua31
-rw-r--r--test/functional/lua/diagnostic_spec.lua26
4 files changed, 67 insertions, 22 deletions
diff --git a/runtime/doc/develop.txt b/runtime/doc/develop.txt
index 1e4889747d..d3170f114f 100644
--- a/runtime/doc/develop.txt
+++ b/runtime/doc/develop.txt
@@ -376,6 +376,10 @@ Where possible, these patterns apply to _both_ Lua and the API:
- See |vim.lsp.inlay_hint.enable()| and |vim.lsp.inlay_hint.is_enabled()|
for a reference implementation of these "best practices".
- NOTE: open questions: https://github.com/neovim/neovim/issues/28603
+- Transformation functions should also have a filter functionality when
+ appropriate. That is, when the function returns a nil value it "filters" its
+ input, otherwise the transformed value is used.
+ - Example: |vim.diagnostic.config.format()|
API DESIGN GUIDELINES *dev-api*
diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt
index 80197670ee..b7bdf2b446 100644
--- a/runtime/doc/diagnostic.txt
+++ b/runtime/doc/diagnostic.txt
@@ -532,11 +532,13 @@ Lua module: vim.diagnostic *diagnostic-api*
the buffer. Otherwise, any truthy value means to
always show the diagnostic source. Overrides the
setting from |vim.diagnostic.config()|.
- • {format}? (`fun(diagnostic:vim.Diagnostic): string`) A
+ • {format}? (`fun(diagnostic:vim.Diagnostic): string?`) 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()|.
+ returns a string or nil. If the return value is nil,
+ the diagnostic is not displayed by the handler. Else
+ the output text is used to display the diagnostic.
+ Overrides the setting from
+ |vim.diagnostic.config()|.
• {prefix}? (`string|table|(fun(diagnostic:vim.Diagnostic,i:integer,total:integer): string, string)`)
Prefix each diagnostic in the floating window:
• If a `function`, {i} is the index of the
@@ -607,10 +609,11 @@ Lua module: vim.diagnostic *diagnostic-api*
Fields: ~
• {current_line}? (`boolean`, default: `false`) Only show diagnostics
for the current line.
- • {format}? (`fun(diagnostic:vim.Diagnostic): string`) A function
- that takes a diagnostic as input and returns a
- string. The return value is the text used to display
- the diagnostic.
+ • {format}? (`fun(diagnostic:vim.Diagnostic): string?`) A
+ function that takes a diagnostic as input and returns
+ a string or nil. If the return value is nil, the
+ diagnostic is not displayed by the handler. Else the
+ output text is used to display the diagnostic.
*vim.diagnostic.Opts.VirtualText*
@@ -635,9 +638,9 @@ Lua module: vim.diagnostic *diagnostic-api*
• {suffix}? (`string|(fun(diagnostic:vim.Diagnostic): string)`)
Append diagnostic message with suffix. This can
be used to render an LSP diagnostic error code.
- • {format}? (`fun(diagnostic:vim.Diagnostic): string`) The
- return value is the text used to display the
- diagnostic. Example: >lua
+ • {format}? (`fun(diagnostic:vim.Diagnostic): string?`) If
+ not nil, 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)
@@ -645,6 +648,9 @@ Lua module: vim.diagnostic *diagnostic-api*
return diagnostic.message
end
<
+
+ If the return value is nil, the diagnostic is
+ not displayed by the handler.
• {hl_mode}? (`'replace'|'combine'|'blend'`) See
|nvim_buf_set_extmark()|.
• {virt_text}? (`[string,any][]`) See |nvim_buf_set_extmark()|.
diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua
index 8044767cb0..972a5d1fa6 100644
--- a/runtime/lua/vim/diagnostic.lua
+++ b/runtime/lua/vim/diagnostic.lua
@@ -150,10 +150,11 @@ end
--- 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.
+--- A function that takes a diagnostic as input and returns a string or nil.
+--- If the return value is nil, the diagnostic is not displayed by the handler.
+--- Else the output text is used to display the diagnostic.
--- Overrides the setting from |vim.diagnostic.config()|.
---- @field format? fun(diagnostic:vim.Diagnostic): string
+--- @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
@@ -207,7 +208,7 @@ end
--- 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:
+--- If not nil, the return value is the text used to display the diagnostic. Example:
--- ```lua
--- function(diagnostic)
--- if diagnostic.severity == vim.diagnostic.severity.ERROR then
@@ -216,7 +217,8 @@ end
--- return diagnostic.message
--- end
--- ```
---- @field format? fun(diagnostic:vim.Diagnostic): string
+--- If the return value is nil, the diagnostic is not displayed by the handler.
+--- @field format? fun(diagnostic:vim.Diagnostic): string?
---
--- See |nvim_buf_set_extmark()|.
--- @field hl_mode? 'replace'|'combine'|'blend'
@@ -239,9 +241,10 @@ end
--- (default: `false`)
--- @field current_line? boolean
---
---- A function that takes a diagnostic as input and returns a string.
---- The return value is the text used to display the diagnostic.
---- @field format? fun(diagnostic:vim.Diagnostic): string
+--- A function that takes a diagnostic as input and returns a string or nil.
+--- If the return value is nil, the diagnostic is not displayed by the handler.
+--- Else the output text is used to display the diagnostic.
+--- @field format? fun(diagnostic:vim.Diagnostic): string?
--- @class vim.diagnostic.Opts.Signs
---
@@ -503,15 +506,21 @@ local function prefix_source(diagnostics)
end, diagnostics)
end
+--- @param format fun(vim.Diagnostic): string?
--- @param diagnostics vim.Diagnostic[]
--- @return vim.Diagnostic[]
local function reformat_diagnostics(format, diagnostics)
vim.validate('format', format, 'function')
vim.validate('diagnostics', diagnostics, vim.islist, 'a list of diagnostics')
- local formatted = vim.deepcopy(diagnostics, true)
- for _, diagnostic in ipairs(formatted) do
- diagnostic.message = format(diagnostic)
+ local formatted = {}
+ for _, diagnostic in ipairs(diagnostics) do
+ local message = format(diagnostic)
+ if message ~= nil then
+ local formatted_diagnostic = vim.deepcopy(diagnostic, true)
+ formatted_diagnostic.message = message
+ table.insert(formatted, formatted_diagnostic)
+ end
end
return formatted
end
diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua
index 08c287735e..9a982a1c6d 100644
--- a/test/functional/lua/diagnostic_spec.lua
+++ b/test/functional/lua/diagnostic_spec.lua
@@ -2134,6 +2134,32 @@ describe('vim.diagnostic', function()
end)
)
end)
+
+ it('can filter diagnostics by returning nil when formatting', function()
+ local result = exec_lua(function()
+ vim.diagnostic.config {
+ virtual_text = {
+ format = function(diagnostic)
+ if diagnostic.code == 'foo_err' then
+ return nil
+ end
+ return diagnostic.message
+ end,
+ },
+ }
+
+ vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, {
+ _G.make_error('An error here!', 0, 0, 0, 0, 'foo_server', 'foo_err'),
+ _G.make_error('An error there!', 1, 1, 1, 1, 'bar_server', 'bar_err'),
+ })
+
+ local extmarks = _G.get_virt_text_extmarks(_G.diagnostic_ns)
+ return extmarks
+ end)
+
+ eq(1, #result)
+ eq(' An error there!', result[1][4].virt_text[3][1])
+ end)
end)
describe('handlers.virtual_lines', function()