mirror of
https://github.com/neovim/neovim.git
synced 2024-12-29 14:41:06 -07:00
fix(diagnostic): respect "if_many" source option for virtual text (#16697)
The `prefix_source` function only evaluates the sources from the diagnostics passed to it; however, because each namespace draws its own virtual text, its diagnostics will never contain more than a single source (by definition). This requires changing the semantics of what "if_many" means from "multiple sources in a single 'batch' of diagnostics" to "multiple sources of all diagnostics within a buffer".
This commit is contained in:
parent
9dae939b1f
commit
060eeaa14c
@ -345,9 +345,12 @@ config({opts}, {namespace}) *vim.diagnostic.config()*
|
|||||||
• severity: Only show virtual text for
|
• severity: Only show virtual text for
|
||||||
diagnostics matching the given severity
|
diagnostics matching the given severity
|
||||||
|diagnostic-severity|
|
|diagnostic-severity|
|
||||||
• source: (string) Include the diagnostic
|
• source: (boolean or string) Include the
|
||||||
source in virtual text. One of "always"
|
diagnostic source in virtual text. Use
|
||||||
or "if_many".
|
"if_many" to only show sources if there
|
||||||
|
is more than one diagnostic source in the
|
||||||
|
buffer. Otherwise, any truthy value means
|
||||||
|
to always show the diagnostic source.
|
||||||
• format: (function) A function that takes
|
• format: (function) A function that takes
|
||||||
a diagnostic as input and returns a
|
a diagnostic as input and returns a
|
||||||
string. The return value is the text used
|
string. The return value is the text used
|
||||||
@ -606,9 +609,12 @@ open_float({opts}, {...}) *vim.diagnostic.open_float()*
|
|||||||
is interpreted as a [text, hl_group] tuple.
|
is interpreted as a [text, hl_group] tuple.
|
||||||
Overrides the setting from
|
Overrides the setting from
|
||||||
|vim.diagnostic.config()|.
|
|vim.diagnostic.config()|.
|
||||||
• source: (string) Include the diagnostic source
|
• source: (boolean or string) Include the
|
||||||
in the message. One of "always" or "if_many".
|
diagnostic source in the message. Use "if_many"
|
||||||
Overrides the setting from
|
to only show sources if there is more than one
|
||||||
|
source of diagnostics in the buffer. Otherwise,
|
||||||
|
any truthy value means to always show the
|
||||||
|
diagnostic source. Overrides the setting from
|
||||||
|vim.diagnostic.config()|.
|
|vim.diagnostic.config()|.
|
||||||
• format: (function) A function that takes a
|
• format: (function) A function that takes a
|
||||||
diagnostic as input and returns a string. The
|
diagnostic as input and returns a string. The
|
||||||
|
@ -91,23 +91,22 @@ local function filter_by_severity(severity, diagnostics)
|
|||||||
end
|
end
|
||||||
|
|
||||||
---@private
|
---@private
|
||||||
local function prefix_source(source, diagnostics)
|
local function count_sources(bufnr)
|
||||||
vim.validate { source = {source, function(v)
|
local seen = {}
|
||||||
return v == "always" or v == "if_many"
|
local count = 0
|
||||||
end, "'always' or 'if_many'" } }
|
for _, namespace_diagnostics in pairs(diagnostic_cache[bufnr]) do
|
||||||
|
for _, diagnostic in ipairs(namespace_diagnostics) do
|
||||||
if source == "if_many" then
|
if diagnostic.source and not seen[diagnostic.source] then
|
||||||
local sources = {}
|
seen[diagnostic.source] = true
|
||||||
for _, d in pairs(diagnostics) do
|
count = count + 1
|
||||||
if d.source then
|
|
||||||
sources[d.source] = true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if #vim.tbl_keys(sources) <= 1 then
|
|
||||||
return diagnostics
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
return count
|
||||||
|
end
|
||||||
|
|
||||||
|
---@private
|
||||||
|
local function prefix_source(diagnostics)
|
||||||
return vim.tbl_map(function(d)
|
return vim.tbl_map(function(d)
|
||||||
if not d.source then
|
if not d.source then
|
||||||
return d
|
return d
|
||||||
@ -557,8 +556,10 @@ end
|
|||||||
--- - virtual_text: (default true) Use virtual text for diagnostics. Options:
|
--- - virtual_text: (default true) Use virtual text for diagnostics. Options:
|
||||||
--- * severity: Only show virtual text for diagnostics matching the given
|
--- * severity: Only show virtual text for diagnostics matching the given
|
||||||
--- severity |diagnostic-severity|
|
--- severity |diagnostic-severity|
|
||||||
--- * source: (string) Include the diagnostic source in virtual
|
--- * source: (boolean or string) Include the diagnostic source in virtual
|
||||||
--- text. One of "always" or "if_many".
|
--- text. Use "if_many" to only show sources if there is more than
|
||||||
|
--- one diagnostic source in the buffer. Otherwise, any truthy value
|
||||||
|
--- means to always show the diagnostic source.
|
||||||
--- * format: (function) A function that takes a diagnostic as input and
|
--- * format: (function) A function that takes a diagnostic as input and
|
||||||
--- returns a string. The return value is the text used to display
|
--- returns a string. The return value is the text used to display
|
||||||
--- the diagnostic. Example:
|
--- the diagnostic. Example:
|
||||||
@ -922,8 +923,11 @@ M.handlers.virtual_text = {
|
|||||||
if opts.virtual_text.format then
|
if opts.virtual_text.format then
|
||||||
diagnostics = reformat_diagnostics(opts.virtual_text.format, diagnostics)
|
diagnostics = reformat_diagnostics(opts.virtual_text.format, diagnostics)
|
||||||
end
|
end
|
||||||
if opts.virtual_text.source then
|
if
|
||||||
diagnostics = prefix_source(opts.virtual_text.source, diagnostics)
|
opts.virtual_text.source
|
||||||
|
and (opts.virtual_text.source ~= "if_many" or count_sources(bufnr) > 1)
|
||||||
|
then
|
||||||
|
diagnostics = prefix_source(diagnostics)
|
||||||
end
|
end
|
||||||
if opts.virtual_text.severity then
|
if opts.virtual_text.severity then
|
||||||
severity = opts.virtual_text.severity
|
severity = opts.virtual_text.severity
|
||||||
@ -1148,8 +1152,11 @@ end
|
|||||||
--- - header: (string or table) String to use as the header for the floating window. If a
|
--- - header: (string or table) String to use as the header for the floating window. If a
|
||||||
--- table, it is interpreted as a [text, hl_group] tuple. Overrides the setting
|
--- table, it is interpreted as a [text, hl_group] tuple. Overrides the setting
|
||||||
--- from |vim.diagnostic.config()|.
|
--- from |vim.diagnostic.config()|.
|
||||||
--- - source: (string) Include the diagnostic source in the message. One of "always" or
|
--- - source: (boolean or string) Include the diagnostic source in the message.
|
||||||
--- "if_many". Overrides the setting from |vim.diagnostic.config()|.
|
--- Use "if_many" to only show sources if there is more than one source of
|
||||||
|
--- diagnostics in the buffer. Otherwise, any truthy value means to always show
|
||||||
|
--- the diagnostic source. Overrides the setting from
|
||||||
|
--- |vim.diagnostic.config()|.
|
||||||
--- - format: (function) A function that takes a diagnostic as input and returns a
|
--- - format: (function) A function that takes a diagnostic as input and returns a
|
||||||
--- string. The return value is the text used to display the diagnostic.
|
--- string. The return value is the text used to display the diagnostic.
|
||||||
--- Overrides the setting from |vim.diagnostic.config()|.
|
--- Overrides the setting from |vim.diagnostic.config()|.
|
||||||
@ -1261,8 +1268,8 @@ function M.open_float(opts, ...)
|
|||||||
diagnostics = reformat_diagnostics(opts.format, diagnostics)
|
diagnostics = reformat_diagnostics(opts.format, diagnostics)
|
||||||
end
|
end
|
||||||
|
|
||||||
if opts.source then
|
if opts.source and (opts.source ~= "if_many" or count_sources(bufnr) > 1) then
|
||||||
diagnostics = prefix_source(opts.source, diagnostics)
|
diagnostics = prefix_source(diagnostics)
|
||||||
end
|
end
|
||||||
|
|
||||||
local prefix_opt = if_nil(opts.prefix, (scope == "cursor" and #diagnostics <= 1) and "" or function(_, i)
|
local prefix_opt = if_nil(opts.prefix, (scope == "cursor" and #diagnostics <= 1) and "" or function(_, i)
|
||||||
|
Loading…
Reference in New Issue
Block a user