aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Anders <8965202+gpanders@users.noreply.github.com>2021-10-17 08:18:35 -0600
committerGitHub <noreply@github.com>2021-10-17 07:18:35 -0700
commitd2d30dfabdaacfd53b081354248402c797576482 (patch)
tree74f47005521367951803f1275b82aac37b4b0d4f
parent30af69509dc91552dc41451857b18907f018c1bd (diff)
downloadrneovim-d2d30dfabdaacfd53b081354248402c797576482.tar.gz
rneovim-d2d30dfabdaacfd53b081354248402c797576482.tar.bz2
rneovim-d2d30dfabdaacfd53b081354248402c797576482.zip
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".
-rw-r--r--runtime/doc/diagnostic.txt24
-rw-r--r--runtime/lua/vim/diagnostic.lua80
-rw-r--r--test/functional/lua/diagnostic_spec.lua72
3 files changed, 148 insertions, 28 deletions
diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt
index 75c8a2ad6f..17d317522b 100644
--- a/runtime/doc/diagnostic.txt
+++ b/runtime/doc/diagnostic.txt
@@ -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"
diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua
index e8aba6b7a3..326932d982 100644
--- a/runtime/lua/vim/diagnostic.lua
+++ b/runtime/lua/vim/diagnostic.lua
@@ -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
@@ -140,12 +118,46 @@ local function get_namespace(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>
diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua
index a08c8d8681..33469597a1 100644
--- a/test/functional/lua/diagnostic_spec.lua
+++ b/test/functional/lua/diagnostic_spec.lua
@@ -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({