diff options
-rw-r--r-- | runtime/doc/deprecated.txt | 2 | ||||
-rw-r--r-- | runtime/doc/diagnostic.txt | 16 | ||||
-rw-r--r-- | runtime/doc/news.txt | 5 | ||||
-rw-r--r-- | runtime/lua/vim/diagnostic.lua | 28 | ||||
-rw-r--r-- | test/functional/lua/diagnostic_spec.lua | 116 |
5 files changed, 164 insertions, 3 deletions
diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt index 9d32f64aef..0f2dbaa77c 100644 --- a/runtime/doc/deprecated.txt +++ b/runtime/doc/deprecated.txt @@ -90,7 +90,7 @@ For each of the functions below, use the corresponding function in - *vim.lsp.diagnostic.enable()* - *vim.lsp.diagnostic.get()* - *vim.lsp.diagnostic.get_all()* Use |vim.diagnostic.get()| instead. -- *vim.lsp.diagnostic.get_count()* Use |vim.diagnostic.get()| instead. +- *vim.lsp.diagnostic.get_count()* Use |vim.diagnostic.count()| instead. - *vim.lsp.diagnostic.get_line_diagnostics()* Use |vim.diagnostic.get()| instead. - *vim.lsp.diagnostic.get_next()* - *vim.lsp.diagnostic.get_next_pos()* diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt index fa5ef22e37..106e130a41 100644 --- a/runtime/doc/diagnostic.txt +++ b/runtime/doc/diagnostic.txt @@ -481,6 +481,22 @@ config({opts}, {namespace}) *vim.diagnostic.config()* Return: ~ (table|nil) table of current diagnostic config if `opts` is omitted. +count({bufnr}, {opts}) *vim.diagnostic.count()* + Get current diagnostics count. + + Parameters: ~ + • {bufnr} (integer|nil) Buffer number to get diagnostics from. Use 0 + for current buffer or nil for all buffers. + • {opts} (table|nil) A table with the following keys: + • namespace: (number) Limit diagnostics to the given + namespace. + • lnum: (number) Limit diagnostics to the given line number. + • severity: See |diagnostic-severity|. + + Return: ~ + (table) A table with actually present severity values as keys (see + |diagnostic-severity|) and integer counts as values. + disable({bufnr}, {namespace}) *vim.diagnostic.disable()* Disable diagnostics in the given buffer. diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 112a76c013..8efad2454b 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -275,6 +275,11 @@ The following new APIs and features were added. • |v_Q-default| and |v_@-default| repeat a register for each line of a visual selection. +• |vim.diagnostic.count()| returns the number of diagnostics for a given + buffer and/or namespace, by severity. This is a faster alternative to + |vim.diagnostic.get()| when only the number of diagnostics is needed, but + not the diagnostics themselves. + ============================================================================== CHANGED FEATURES *news-changed* diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index ad40723737..a447463dff 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -363,7 +363,6 @@ local function get_diagnostics(bufnr, opts, clamp) local function add(b, d) if not opts.lnum or d.lnum == opts.lnum then - d = vim.deepcopy(d) if clamp and api.nvim_buf_is_loaded(b) then local line_count = buf_line_count[b] - 1 if @@ -374,6 +373,7 @@ local function get_diagnostics(bufnr, opts, clamp) or d.col < 0 or d.end_col < 0 then + d = vim.deepcopy(d) d.lnum = math.max(math.min(d.lnum, line_count), 0) d.end_lnum = math.max(math.min(d.end_lnum, line_count), 0) d.col = math.max(d.col, 0) @@ -756,7 +756,31 @@ function M.get(bufnr, opts) opts = { opts, 't', true }, }) - return get_diagnostics(bufnr, opts, false) + return vim.deepcopy(get_diagnostics(bufnr, opts, false)) +end + +--- Get current diagnostics count. +--- +---@param bufnr integer|nil Buffer number to get diagnostics from. Use 0 for +--- current buffer or nil for all buffers. +---@param opts table|nil A table with the following keys: +--- - namespace: (number) Limit diagnostics to the given namespace. +--- - lnum: (number) Limit diagnostics to the given line number. +--- - severity: See |diagnostic-severity|. +---@return table A table with actually present severity values as keys (see |diagnostic-severity|) and integer counts as values. +function M.count(bufnr, opts) + vim.validate({ + bufnr = { bufnr, 'n', true }, + opts = { opts, 't', true }, + }) + + local diagnostics = get_diagnostics(bufnr, opts, false) + local count = {} + for i = 1, #diagnostics do + local severity = diagnostics[i].severity + count[severity] = (count[severity] or 0) + 1 + end + return count end --- Get the previous diagnostic closest to the cursor position. diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index 688118a085..d59ee02f01 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -930,6 +930,122 @@ end) end) end) + describe('count', function() + it('returns actually present severity counts', function() + eq( + exec_lua [[return { + [vim.diagnostic.severity.ERROR] = 4, + [vim.diagnostic.severity.WARN] = 3, + [vim.diagnostic.severity.INFO] = 2, + [vim.diagnostic.severity.HINT] = 1, + }]], + exec_lua [[ + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error("Error 1", 1, 1, 1, 2), + make_error("Error 2", 1, 3, 1, 4), + make_error("Error 3", 1, 5, 1, 6), + make_error("Error 4", 1, 7, 1, 8), + make_warning("Warning 1", 2, 1, 2, 2), + make_warning("Warning 2", 2, 3, 2, 4), + make_warning("Warning 3", 2, 5, 2, 6), + make_info("Info 1", 3, 1, 3, 2), + make_info("Info 2", 3, 3, 3, 4), + make_hint("Hint 1", 4, 1, 4, 2), + }) + return vim.diagnostic.count(diagnostic_bufnr) + ]] + ) + eq( + exec_lua [[return { + [vim.diagnostic.severity.ERROR] = 2, + [vim.diagnostic.severity.INFO] = 1, + }]], + exec_lua [[ + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error("Error 1", 1, 1, 1, 2), + make_error("Error 2", 1, 3, 1, 4), + make_info("Info 1", 3, 1, 3, 2), + }) + return vim.diagnostic.count(diagnostic_bufnr) + ]] + ) + end) + + it('returns only requested diagnostics count when severity range is supplied', function() + eq( + exec_lua [[return { + { [vim.diagnostic.severity.ERROR] = 1, [vim.diagnostic.severity.WARN] = 1 }, + { [vim.diagnostic.severity.WARN] = 1, [vim.diagnostic.severity.INFO] = 1, [vim.diagnostic.severity.HINT] = 1 }, + { [vim.diagnostic.severity.WARN] = 1, [vim.diagnostic.severity.INFO] = 1 }, + }]], + exec_lua [[ + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error("Error 1", 1, 1, 1, 5), + make_warning("Warning on Server 1", 1, 1, 2, 3), + make_info("Ignored information", 1, 1, 2, 3), + make_hint("Here's a hint", 1, 1, 2, 3), + }) + + return { + vim.diagnostic.count(diagnostic_bufnr, { severity = {min=vim.diagnostic.severity.WARN} }), + vim.diagnostic.count(diagnostic_bufnr, { severity = {max=vim.diagnostic.severity.WARN} }), + vim.diagnostic.count(diagnostic_bufnr, { + severity = { + min=vim.diagnostic.severity.INFO, + max=vim.diagnostic.severity.WARN, + } + }), + } + ]] + ) + end) + + it('returns only requested diagnostics when severities are supplied', function() + eq( + exec_lua [[return { + { [vim.diagnostic.severity.WARN] = 1 }, + { [vim.diagnostic.severity.ERROR] = 1 }, + { [vim.diagnostic.severity.WARN] = 1, [vim.diagnostic.severity.INFO] = 1 }, + }]], + exec_lua [[ + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error("Error 1", 1, 1, 1, 5), + make_warning("Warning on Server 1", 1, 1, 2, 3), + make_info("Ignored information", 1, 1, 2, 3), + make_hint("Here's a hint", 1, 1, 2, 3), + }) + + return { + vim.diagnostic.count(diagnostic_bufnr, { severity = {vim.diagnostic.severity.WARN} }), + vim.diagnostic.count(diagnostic_bufnr, { severity = {vim.diagnostic.severity.ERROR} }), + vim.diagnostic.count(diagnostic_bufnr, { + severity = { + vim.diagnostic.severity.INFO, + vim.diagnostic.severity.WARN, + } + }), + } + ]] + ) + end) + + it('allows filtering by line', function() + eq( + exec_lua [[return { [vim.diagnostic.severity.ERROR] = 1 }]], + exec_lua [[ + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error("Error 1", 1, 1, 1, 5), + make_warning("Warning on Server 1", 1, 1, 2, 3), + make_info("Ignored information", 1, 1, 2, 3), + make_error("Error On Other Line", 2, 1, 1, 5), + }) + + return vim.diagnostic.count(diagnostic_bufnr, {lnum = 2}) + ]] + ) + end) + end) + describe('config()', function() it('works with global, namespace, and ephemeral options', function() eq(1, exec_lua [[ |