diff options
-rw-r--r-- | runtime/doc/develop.txt | 4 | ||||
-rw-r--r-- | runtime/doc/diagnostic.txt | 28 | ||||
-rw-r--r-- | runtime/lua/vim/diagnostic.lua | 31 | ||||
-rw-r--r-- | test/functional/lua/diagnostic_spec.lua | 26 |
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() |