diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 0e1eb17cdc..6ea6436c5b 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -648,6 +648,7 @@ local sign_highlight_map = make_highlight_map('Sign') --- @return integer col --- @return integer end_lnum --- @return integer end_col +--- @return boolean valid local function get_logical_pos(diagnostic) local ns = M.get_namespace(diagnostic.namespace) local extmark = api.nvim_buf_get_extmark_by_id( @@ -657,7 +658,7 @@ local function get_logical_pos(diagnostic) { details = true } ) - return extmark[1], extmark[2], extmark[3].end_row, extmark[3].end_col + return extmark[1], extmark[2], extmark[3].end_row, extmark[3].end_col, not extmark[3].invalid end --- @param diagnostics vim.Diagnostic[] @@ -669,13 +670,15 @@ local function diagnostic_lines(diagnostics) local diagnostics_by_line = {} --- @type table for _, diagnostic in ipairs(diagnostics) do - local lnum = get_logical_pos(diagnostic) - local line_diagnostics = diagnostics_by_line[lnum] - if not line_diagnostics then - line_diagnostics = {} - diagnostics_by_line[lnum] = line_diagnostics + local lnum, _, _, _, valid = get_logical_pos(diagnostic) + if valid then + local line_diagnostics = diagnostics_by_line[lnum] + if not line_diagnostics then + line_diagnostics = {} + diagnostics_by_line[lnum] = line_diagnostics + end + table.insert(line_diagnostics, diagnostic) end - table.insert(line_diagnostics, diagnostic) end return diagnostics_by_line end @@ -1332,6 +1335,7 @@ function M.set(namespace, bufnr, diagnostics, opts) diagnostic._extmark_id = api.nvim_buf_set_extmark(bufnr, ns.user_data.location_ns, row, col, { end_row = end_row, end_col = end_col, + invalidate = true, }) end end) diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index 06e255aa2f..bff7da72ce 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -1433,15 +1433,6 @@ describe('vim.diagnostic', function() describe('after inserting text before diagnostic position', function() before_each(function() - exec_lua(function() - vim.api.nvim_set_current_buf(_G.diagnostic_bufnr) - - vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, { - _G.make_error('Diagnostic #1', 1, 4, 1, 7), - _G.make_error('Diagnostic #2', 3, 0, 3, 3), - }) - end) - api.nvim_buf_set_text(0, 3, 0, 3, 0, { 'new line', 'new ' }) end) @@ -1449,7 +1440,7 @@ describe('vim.diagnostic', function() eq( { 5, 4 }, exec_lua(function() - vim.api.nvim_win_set_cursor(0, { 2, 4 }) + vim.api.nvim_win_set_cursor(0, { 3, 1 }) vim.diagnostic.jump({ count = 1 }) return vim.api.nvim_win_get_cursor(0) end) @@ -1471,8 +1462,6 @@ describe('vim.diagnostic', function() describe('if diagnostic is set after last character in line', function() before_each(function() exec_lua(function() - vim.api.nvim_set_current_buf(_G.diagnostic_bufnr) - vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, { _G.make_error('Diagnostic #1', 2, 3, 3, 4), }) @@ -1501,6 +1490,34 @@ describe('vim.diagnostic', function() ) end) end) + + describe('after entire text range with a diagnostic was deleted', function() + before_each(function() + api.nvim_buf_set_text(0, 1, 1, 1, 4, {}) + end) + + it('does not find next diagnostic inside the deleted range', function() + eq( + { 3, 0 }, + exec_lua(function() + vim.api.nvim_win_set_cursor(0, { 1, 0 }) + vim.diagnostic.jump({ count = 1 }) + return vim.api.nvim_win_get_cursor(0) + end) + ) + end) + + it('does not find previous diagnostic inside the deleted range', function() + eq( + { 1, 0 }, + exec_lua(function() + vim.api.nvim_win_set_cursor(0, { 3, 0 }) + vim.diagnostic.jump({ count = -1 }) + return vim.api.nvim_win_get_cursor(0) + end) + ) + end) + end) end) describe('get()', function()