aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/diagnostic.txt47
-rw-r--r--runtime/lua/vim/diagnostic.lua29
-rw-r--r--test/functional/lua/diagnostic_spec.lua51
3 files changed, 80 insertions, 47 deletions
diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt
index 586ce02b2e..276571d042 100644
--- a/runtime/doc/diagnostic.txt
+++ b/runtime/doc/diagnostic.txt
@@ -201,7 +201,52 @@ DiagnosticsChanged After diagnostics have changed.
Example: >
autocmd User DiagnosticsChanged lua vim.diagnostic.setqflist({open = false })
<
-
+==============================================================================
+CUSTOMIZATION *diagnostic-config*
+
+If you need more customization over the way diagnostics are displayed than the
+built-in configuration options provide, you can override the display handler
+explicitly. For example, use the following to only show a sign for the highest
+severity diagnostic on a given line: >
+
+ -- Disable the default signs handler
+ vim.diagnostic.config({signs = false})
+
+ -- Create a namespace. This won't be used to add any diagnostics,
+ -- only to display them.
+ local ns = vim.api.nvim_create_namespace("my_namespace")
+
+ -- Create a reference to the original function
+ local orig_show = vim.diagnostic.show
+
+ local function set_signs(bufnr)
+ -- Get all diagnostics from the current buffer
+ local diagnostics = vim.diagnostic.get(bufnr)
+
+ -- Find the "worst" diagnostic per line
+ local max_severity_per_line = {}
+ for _, d in pairs(diagnostics) do
+ local m = max_severity_per_line[d.lnum]
+ if not m or d.severity < m.severity then
+ max_severity_per_line[d.lnum] = d
+ end
+ end
+
+ -- Show the filtered diagnostics using the custom namespace. Use the
+ -- reference to the original function to avoid a loop.
+ local filtered_diagnostics = vim.tbl_values(max_severity_per_line)
+ orig_show(ns, bufnr, filtered_diagnostics, {
+ virtual_text=false,
+ underline=false,
+ signs=true
+ })
+ end
+
+ function vim.diagnostic.show(namespace, bufnr, ...)
+ orig_show(namespace, bufnr, ...)
+ set_signs(bufnr)
+ end
+<
==============================================================================
Lua module: vim.diagnostic *diagnostic-api*
diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua
index 35badf8a02..c7c8c1878e 100644
--- a/runtime/lua/vim/diagnostic.lua
+++ b/runtime/lua/vim/diagnostic.lua
@@ -620,23 +620,22 @@ function M.set(namespace, bufnr, diagnostics, opts)
}
if vim.tbl_isempty(diagnostics) then
- return M.reset(namespace, bufnr)
- end
-
- if not diagnostic_cleanup[bufnr][namespace] then
- diagnostic_cleanup[bufnr][namespace] = true
-
- -- Clean up our data when the buffer unloads.
- vim.api.nvim_buf_attach(bufnr, false, {
- on_detach = function(_, b)
- clear_diagnostic_cache(b, namespace)
- diagnostic_cleanup[b][namespace] = nil
- end
- })
+ clear_diagnostic_cache(namespace, bufnr)
+ else
+ if not diagnostic_cleanup[bufnr][namespace] then
+ diagnostic_cleanup[bufnr][namespace] = true
+
+ -- Clean up our data when the buffer unloads.
+ vim.api.nvim_buf_attach(bufnr, false, {
+ on_detach = function(_, b)
+ clear_diagnostic_cache(b, namespace)
+ diagnostic_cleanup[b][namespace] = nil
+ end
+ })
+ end
+ set_diagnostic_cache(namespace, bufnr, diagnostics)
end
- set_diagnostic_cache(namespace, bufnr, diagnostics)
-
if vim.api.nvim_buf_is_loaded(bufnr) then
M.show(namespace, bufnr, diagnostics, opts)
elseif opts then
diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua
index 9397af9d9f..45aa4915cd 100644
--- a/test/functional/lua/diagnostic_spec.lua
+++ b/test/functional/lua/diagnostic_spec.lua
@@ -874,6 +874,26 @@ describe('vim.diagnostic', function()
return count_extmarks(diagnostic_bufnr, diagnostic_ns)
]])
end)
+
+ it('sets signs', function()
+ local result = exec_lua [[
+ vim.diagnostic.config({
+ signs = true,
+ })
+
+ local diagnostics = {
+ make_error('Error', 1, 1, 1, 2),
+ make_warning('Warning', 3, 3, 3, 3),
+ }
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+
+ return vim.fn.sign_getplaced(diagnostic_bufnr, {group = '*'})[1].signs
+ ]]
+
+ eq({2, 'DiagnosticSignError'}, {result[1].lnum, result[1].name})
+ eq({4, 'DiagnosticSignWarn'}, {result[2].lnum, result[2].name})
+ end)
end)
describe('show_line_diagnostics()', function()
@@ -995,37 +1015,6 @@ describe('vim.diagnostic', function()
end)
end)
- describe('set_signs()', function()
- -- TODO(tjdevries): Find out why signs are not displayed when set from Lua...??
- pending('sets signs by default', function()
- exec_lua [[
- vim.diagnostic.config({
- update_in_insert = true,
- signs = true,
- })
-
- local diagnostics = {
- make_error('Delayed Diagnostic', 1, 1, 1, 2),
- make_error('Delayed Diagnostic', 3, 3, 3, 3),
- }
-
- vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
- vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
-
- vim.diagnostic._set_signs(diagnostic_ns, diagnostic_bufnr, diagnostics)
- -- return vim.fn.sign_getplaced()
- ]]
-
- nvim("input", "o")
- nvim("input", "<esc>")
-
- -- TODO(tjdevries): Find a way to get the signs to display in the test...
- eq(nil, exec_lua [[
- return im.fn.sign_getplaced()[1].signs
- ]])
- end)
- end)
-
describe('setloclist()', function()
it('sets diagnostics in lnum order', function()
local loc_list = exec_lua [[