commit 2f24ae8de471570e3188c91128229b6e98e1710f
parent c681336e3c35bcc39cfe1d5360ac22ec8a6677c9
Author: Maria José Solano <majosolano99@gmail.com>
Date: Mon, 12 May 2025 19:50:37 -0500
feat(diagnostic): add `format` option to `setloclist`/`setqflist` (#33977)
Diffstat:
4 files changed, 78 insertions(+), 1 deletion(-)
diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt
@@ -923,6 +923,11 @@ setloclist({opts}) *vim.diagnostic.setloclist()*
"Diagnostics".
• {severity}? (`vim.diagnostic.SeverityFilter`) See
|diagnostic-severity|.
+ • {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 in the location list. Else the output text is
+ used to display the diagnostic.
setqflist({opts}) *vim.diagnostic.setqflist()*
Add all diagnostics to the quickfix list.
@@ -938,6 +943,11 @@ setqflist({opts}) *vim.diagnostic.setqflist()*
title, it's updated. If not, a new quickfix list is created.
• {severity}? (`vim.diagnostic.SeverityFilter`) See
|diagnostic-severity|.
+ • {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 in the quickfix list. Else the output text is
+ used to display the diagnostic.
*vim.diagnostic.show()*
show({namespace}, {bufnr}, {diagnostics}, {opts})
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
@@ -126,7 +126,9 @@ DEFAULTS
DIAGNOSTICS
-• todo
+• |vim.diagnostic.setloclist()| and |vim.diagnostic.setqflist()| now support a
+ `format` function to modify (or filter) diagnostics before being set in the
+ location/quickfix list.
EDITOR
diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua
@@ -909,6 +909,9 @@ local function set_list(loclist, opts)
-- 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 --[[@as vim.diagnostic.GetOpts]], false)
+ if opts.format then
+ diagnostics = reformat_diagnostics(opts.format, diagnostics)
+ end
local items = M.toqflist(diagnostics)
local qf_id = nil
if loclist then
@@ -2361,6 +2364,11 @@ end
---
--- See |diagnostic-severity|.
--- @field severity? vim.diagnostic.SeverityFilter
+---
+--- 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 in the quickfix list.
+--- Else the output text is used to display the diagnostic.
+--- @field format? fun(diagnostic:vim.Diagnostic): string?
--- Add all diagnostics to the quickfix list.
---
@@ -2389,6 +2397,11 @@ end
---
--- See |diagnostic-severity|.
--- @field severity? vim.diagnostic.SeverityFilter
+---
+--- 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 in the location list.
+--- Else the output text is used to display the diagnostic.
+--- @field format? fun(diagnostic:vim.Diagnostic): string?
--- Add buffer diagnostics to the location list.
---
diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua
@@ -3448,6 +3448,32 @@ describe('vim.diagnostic', function()
eq(1, #loc_list)
eq('Error here!', loc_list[1].text)
end)
+
+ it('supports format function', function()
+ local loc_list = exec_lua(function()
+ vim.api.nvim_win_set_buf(0, _G.diagnostic_bufnr)
+
+ vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, {
+ _G.make_error('Error', 1, 1, 1, 1, 'foo_ls'),
+ _G.make_error('Another error', 2, 2, 2, 2, 'foo_ls'),
+ })
+
+ vim.diagnostic.setloclist({
+ format = function(diagnostic)
+ if diagnostic.lnum > 1 then
+ return nil
+ end
+
+ return string.format('%s: %s', diagnostic.source, diagnostic.message)
+ end,
+ })
+
+ return vim.fn.getloclist(0)
+ end)
+
+ eq(1, #loc_list)
+ eq('foo_ls: Error', loc_list[1].text)
+ end)
end)
describe('setqflist()', function()
@@ -3516,6 +3542,32 @@ describe('vim.diagnostic', function()
neq(0, qf_winid)
end)
+
+ it('supports format function', function()
+ local qf_list = exec_lua(function()
+ vim.api.nvim_win_set_buf(0, _G.diagnostic_bufnr)
+
+ vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, {
+ _G.make_error('Error', 1, 1, 1, 1, 'foo_ls'),
+ _G.make_error('Another error', 2, 2, 2, 2, 'foo_ls'),
+ })
+
+ vim.diagnostic.setqflist({
+ format = function(diagnostic)
+ if diagnostic.lnum > 1 then
+ return nil
+ end
+
+ return string.format('%s: %s', diagnostic.source, diagnostic.message)
+ end,
+ })
+
+ return vim.fn.getqflist()
+ end)
+
+ eq(1, #qf_list)
+ eq('foo_ls: Error', qf_list[1].text)
+ end)
end)
describe('match()', function()