From 2f24ae8de471570e3188c91128229b6e98e1710f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maria=20Jos=C3=A9=20Solano?= Date: Mon, 12 May 2025 19:50:37 -0500 Subject: [PATCH] feat(diagnostic): add `format` option to `setloclist`/`setqflist` (#33977) --- runtime/doc/diagnostic.txt | 10 +++++ runtime/doc/news.txt | 4 +- runtime/lua/vim/diagnostic.lua | 13 +++++++ test/functional/lua/diagnostic_spec.lua | 52 +++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt index 26b6f601a6..2f44ca8843 100644 --- 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 index 4f59555ac4..b2673a17a4 100644 --- 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 index 1e6a94090d..ed80cf14bf 100644 --- 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 index 73b865d91a..6ea87d3817 100644 --- 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()