mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
fix(diagnostic): do not override existing config settings #16043
When using `true` as the value of a configuration option, the option is configured to use default values. For example, if a user configures virtual text to include the source globally (using vim.diagnostic.config) and a specific namespace or producer configures virtual text with `virt_text = true`, the user's global configuration is overriden. Instead, interpret a value of `true` to mean "use existing settings if defined, otherwise use defaults".
This commit is contained in:
parent
30af69509d
commit
d2d30dfabd
@ -254,12 +254,31 @@ config({opts}, {namespace}) *vim.diagnostic.config()*
|
||||
Configure diagnostic options globally or for a specific
|
||||
diagnostic namespace.
|
||||
|
||||
Configuration can be specified globally, per-namespace, or
|
||||
ephemerally (i.e. only for a single call to
|
||||
|vim.diagnostic.set()| or |vim.diagnostic.show()|). Ephemeral
|
||||
configuration has highest priority, followed by namespace
|
||||
configuration, and finally global configuration.
|
||||
|
||||
For example, if a user enables virtual text globally with >
|
||||
|
||||
vim.diagnostic.config({virt_text = true})
|
||||
<
|
||||
|
||||
and a diagnostic producer sets diagnostics with >
|
||||
|
||||
vim.diagnostic.set(ns, 0, diagnostics, {virt_text = false})
|
||||
<
|
||||
|
||||
then virtual text will not be enabled for those diagnostics.
|
||||
|
||||
Note:
|
||||
Each of the configuration options below accepts one of the
|
||||
following:
|
||||
• `false` : Disable this feature
|
||||
• `true` : Enable this feature, use default settings.
|
||||
• `table` : Enable this feature with overrides.
|
||||
• `table` : Enable this feature with overrides. Use an
|
||||
empty table to use default values.
|
||||
• `function` : Function with signature (namespace, bufnr)
|
||||
that returns any of the above.
|
||||
|
||||
@ -460,8 +479,9 @@ match({str}, {pat}, {groups}, {severity_map}, {defaults})
|
||||
For example, consider a line of output from a linter: >
|
||||
|
||||
WARNING filename:27:3: Variable 'foo' does not exist
|
||||
<
|
||||
|
||||
< This can be parsed into a diagnostic |diagnostic-structure|
|
||||
This can be parsed into a diagnostic |diagnostic-structure|
|
||||
with: >
|
||||
|
||||
local s = "WARNING filename:27:3: Variable 'foo' does not exist"
|
||||
|
@ -93,28 +93,6 @@ local function reformat_diagnostics(format, diagnostics)
|
||||
return formatted
|
||||
end
|
||||
|
||||
---@private
|
||||
local function resolve_optional_value(option, namespace, bufnr)
|
||||
local enabled_val = {}
|
||||
|
||||
if not option then
|
||||
return false
|
||||
elseif option == true then
|
||||
return enabled_val
|
||||
elseif type(option) == 'function' then
|
||||
local val = option(namespace, bufnr)
|
||||
if val == true then
|
||||
return enabled_val
|
||||
else
|
||||
return val
|
||||
end
|
||||
elseif type(option) == 'table' then
|
||||
return option
|
||||
else
|
||||
error("Unexpected option type: " .. vim.inspect(option))
|
||||
end
|
||||
end
|
||||
|
||||
local all_namespaces = {}
|
||||
|
||||
---@private
|
||||
@ -139,13 +117,47 @@ local function get_namespace(ns)
|
||||
return all_namespaces[ns]
|
||||
end
|
||||
|
||||
---@private
|
||||
local function enabled_value(option, namespace)
|
||||
local ns = get_namespace(namespace)
|
||||
if type(ns.opts[option]) == "table" then
|
||||
return ns.opts[option]
|
||||
end
|
||||
|
||||
if type(global_diagnostic_options[option]) == "table" then
|
||||
return global_diagnostic_options[option]
|
||||
end
|
||||
|
||||
return {}
|
||||
end
|
||||
|
||||
---@private
|
||||
local function resolve_optional_value(option, value, namespace, bufnr)
|
||||
if not value then
|
||||
return false
|
||||
elseif value == true then
|
||||
return enabled_value(option, namespace)
|
||||
elseif type(value) == 'function' then
|
||||
local val = value(namespace, bufnr)
|
||||
if val == true then
|
||||
return enabled_value(option, namespace)
|
||||
else
|
||||
return val
|
||||
end
|
||||
elseif type(value) == 'table' then
|
||||
return value
|
||||
else
|
||||
error("Unexpected option type: " .. vim.inspect(value))
|
||||
end
|
||||
end
|
||||
|
||||
---@private
|
||||
local function get_resolved_options(opts, namespace, bufnr)
|
||||
local ns = get_namespace(namespace)
|
||||
local resolved = vim.tbl_extend('keep', opts or {}, ns.opts, global_diagnostic_options)
|
||||
for k in pairs(global_diagnostic_options) do
|
||||
if resolved[k] ~= nil then
|
||||
resolved[k] = resolve_optional_value(resolved[k], namespace, bufnr)
|
||||
resolved[k] = resolve_optional_value(k, resolved[k], namespace, bufnr)
|
||||
end
|
||||
end
|
||||
return resolved
|
||||
@ -542,10 +554,27 @@ end
|
||||
--- Configure diagnostic options globally or for a specific diagnostic
|
||||
--- namespace.
|
||||
---
|
||||
--- Configuration can be specified globally, per-namespace, or ephemerally
|
||||
--- (i.e. only for a single call to |vim.diagnostic.set()| or
|
||||
--- |vim.diagnostic.show()|). Ephemeral configuration has highest priority,
|
||||
--- followed by namespace configuration, and finally global configuration.
|
||||
---
|
||||
--- For example, if a user enables virtual text globally with
|
||||
--- <pre>
|
||||
--- vim.diagnostic.config({virt_text = true})
|
||||
--- </pre>
|
||||
---
|
||||
--- and a diagnostic producer sets diagnostics with
|
||||
--- <pre>
|
||||
--- vim.diagnostic.set(ns, 0, diagnostics, {virt_text = false})
|
||||
--- </pre>
|
||||
---
|
||||
--- then virtual text will not be enabled for those diagnostics.
|
||||
---
|
||||
---@note Each of the configuration options below accepts one of the following:
|
||||
--- - `false`: Disable this feature
|
||||
--- - `true`: Enable this feature, use default settings.
|
||||
--- - `table`: Enable this feature with overrides.
|
||||
--- - `table`: Enable this feature with overrides. Use an empty table to use default values.
|
||||
--- - `function`: Function with signature (namespace, bufnr) that returns any of the above.
|
||||
---
|
||||
---@param opts table Configuration table with the following keys:
|
||||
@ -653,8 +682,6 @@ function M.set(namespace, bufnr, diagnostics, opts)
|
||||
|
||||
if vim.api.nvim_buf_is_loaded(bufnr) then
|
||||
M.show(namespace, bufnr, diagnostics, opts)
|
||||
elseif opts then
|
||||
M.config(opts, namespace)
|
||||
end
|
||||
|
||||
vim.api.nvim_command("doautocmd <nomodeline> User DiagnosticsChanged")
|
||||
@ -1277,6 +1304,7 @@ end
|
||||
--- <pre>
|
||||
--- WARNING filename:27:3: Variable 'foo' does not exist
|
||||
--- </pre>
|
||||
---
|
||||
--- This can be parsed into a diagnostic |diagnostic-structure|
|
||||
--- with:
|
||||
--- <pre>
|
||||
|
@ -473,6 +473,78 @@ describe('vim.diagnostic', function()
|
||||
end)
|
||||
|
||||
describe('config()', function()
|
||||
it('works with global, namespace, and ephemeral options', function()
|
||||
eq(1, exec_lua [[
|
||||
vim.diagnostic.config({
|
||||
virtual_text = false,
|
||||
})
|
||||
|
||||
vim.diagnostic.config({
|
||||
virtual_text = true,
|
||||
underline = false,
|
||||
}, diagnostic_ns)
|
||||
|
||||
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
|
||||
make_error('Some Error', 4, 4, 4, 4),
|
||||
})
|
||||
|
||||
return count_extmarks(diagnostic_bufnr, diagnostic_ns)
|
||||
]])
|
||||
|
||||
eq(1, exec_lua [[
|
||||
vim.diagnostic.config({
|
||||
virtual_text = false,
|
||||
})
|
||||
|
||||
vim.diagnostic.config({
|
||||
virtual_text = false,
|
||||
underline = false,
|
||||
}, diagnostic_ns)
|
||||
|
||||
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
|
||||
make_error('Some Error', 4, 4, 4, 4),
|
||||
}, {virtual_text = true})
|
||||
|
||||
return count_extmarks(diagnostic_bufnr, diagnostic_ns)
|
||||
]])
|
||||
|
||||
eq(0, exec_lua [[
|
||||
vim.diagnostic.config({
|
||||
virtual_text = false,
|
||||
})
|
||||
|
||||
vim.diagnostic.config({
|
||||
virtual_text = {severity=vim.diagnostic.severity.ERROR},
|
||||
underline = false,
|
||||
}, diagnostic_ns)
|
||||
|
||||
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
|
||||
make_warning('Some Warning', 4, 4, 4, 4),
|
||||
}, {virtual_text = true})
|
||||
|
||||
return count_extmarks(diagnostic_bufnr, diagnostic_ns)
|
||||
]])
|
||||
|
||||
eq(1, exec_lua [[
|
||||
vim.diagnostic.config({
|
||||
virtual_text = false,
|
||||
})
|
||||
|
||||
vim.diagnostic.config({
|
||||
virtual_text = {severity=vim.diagnostic.severity.ERROR},
|
||||
underline = false,
|
||||
}, diagnostic_ns)
|
||||
|
||||
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
|
||||
make_warning('Some Warning', 4, 4, 4, 4),
|
||||
}, {
|
||||
virtual_text = {} -- An empty table uses default values
|
||||
})
|
||||
|
||||
return count_extmarks(diagnostic_bufnr, diagnostic_ns)
|
||||
]])
|
||||
end)
|
||||
|
||||
it('can use functions for config values', function()
|
||||
exec_lua [[
|
||||
vim.diagnostic.config({
|
||||
|
Loading…
Reference in New Issue
Block a user