diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index f8c6288e71..5a78ad0d0a 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -1609,21 +1609,33 @@ M.handlers.underline = { --- @param opts vim.diagnostic.Opts.VirtualText local function render_virtual_text(namespace, bufnr, diagnostics, opts) local lnum = api.nvim_win_get_cursor(0)[1] - 1 + local buf_len = api.nvim_buf_line_count(bufnr) api.nvim_buf_clear_namespace(bufnr, namespace, 0, -1) - for line, line_diagnostics in pairs(diagnostics) do - local virt_texts = M._get_virt_text_chunks(line_diagnostics, opts) - local skip = (opts.current_line == true and line ~= lnum) + local function should_render(line) + if + (line >= buf_len) + or (opts.current_line == true and line ~= lnum) or (opts.current_line == false and line == lnum) + then + return false + end - if virt_texts and not skip then - api.nvim_buf_set_extmark(bufnr, namespace, line, 0, { - hl_mode = opts.hl_mode or 'combine', - virt_text = virt_texts, - virt_text_pos = opts.virt_text_pos, - virt_text_hide = opts.virt_text_hide, - virt_text_win_col = opts.virt_text_win_col, - }) + return true + end + + for line, line_diagnostics in pairs(diagnostics) do + if should_render(line) then + local virt_texts = M._get_virt_text_chunks(line_diagnostics, opts) + if virt_texts then + api.nvim_buf_set_extmark(bufnr, namespace, line, 0, { + hl_mode = opts.hl_mode or 'combine', + virt_text = virt_texts, + virt_text_pos = opts.virt_text_pos, + virt_text_hide = opts.virt_text_hide, + virt_text_win_col = opts.virt_text_win_col, + }) + end end end end diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index 1657941342..41e85b82f6 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -2204,6 +2204,31 @@ describe('vim.diagnostic', function() eq(1, #result) eq(' Another error there!', result[1][4].virt_text[3][1]) end) + + it('only renders virtual_line diagnostics within buffer length', function() + local result = exec_lua(function() + vim.api.nvim_win_set_cursor(0, { 1, 0 }) + + vim.diagnostic.config({ virtual_text = { current_line = false } }) + + vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, { + _G.make_error('Hidden Error here!', 0, 0, 0, 0, 'foo_server'), + _G.make_error('First Error here!', 1, 0, 1, 0, 'foo_server'), + _G.make_error('Second Error here!', 2, 0, 2, 0, 'foo_server'), + _G.make_error('First Ignored Error here!', 3, 0, 3, 0, 'foo_server'), + _G.make_error('Second Ignored Error here!', 6, 0, 6, 0, 'foo_server'), + _G.make_error('Third Ignored Error here!', 8, 0, 8, 0, 'foo_server'), + }) + + vim.api.nvim_buf_set_lines(_G.diagnostic_bufnr, 2, 5, false, {}) + vim.api.nvim_exec_autocmds('CursorMoved', { buffer = _G.diagnostic_bufnr }) + return _G.get_virt_text_extmarks(_G.diagnostic_ns) + end) + + eq(2, #result) + eq(' First Error here!', result[1][4].virt_text[3][1]) + eq(' Second Error here!', result[2][4].virt_text[3][1]) + end) end) describe('handlers.virtual_lines', function() diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index 296151ce68..5d89bbdd80 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -3412,7 +3412,7 @@ describe('extmark decorations', function() {4:^1} | {4:1} |*13 | - ]] + ]], }) feed('') -- Newly visible line should also have the highlight. @@ -3421,7 +3421,7 @@ describe('extmark decorations', function() {4:^1} | {4:1} |*13 | - ]] + ]], }) end) end)