diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index f5ca034abc..53a31f4d3c 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -1146,8 +1146,12 @@ function M.open_float(bufnr, opts) return d.lnum == lnum end, diagnostics) elseif scope == "cursor" then + -- LSP servers can send diagnostics with `end_col` past the length of the line + local line_length = #vim.api.nvim_buf_get_lines(bufnr, lnum, lnum + 1, true)[1] diagnostics = vim.tbl_filter(function(d) - return d.lnum == lnum and d.col <= col and (d.end_col >= col or d.end_lnum > lnum) + return d.lnum == lnum + and math.min(d.col, line_length - 1) <= col + and (d.end_col >= col or d.end_lnum > lnum) end, diagnostics) end diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index e49453ab76..1cbfa224cc 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -1046,6 +1046,21 @@ describe('vim.diagnostic', function() vim.api.nvim_win_close(winnr, true) return lines ]]) + + -- With column position past the end of the line. #16062 + eq({'1. Syntax error'}, exec_lua [[ + local first_line_len = #vim.api.nvim_buf_get_lines(diagnostic_bufnr, 0, 1, true)[1] + local diagnostics = { + make_error("Syntax error", 0, first_line_len + 1, 1, 0), + } + vim.api.nvim_win_set_buf(0, diagnostic_bufnr) + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics) + vim.api.nvim_win_set_cursor(0, {1, 1}) + local float_bufnr, winnr = vim.diagnostic.open_float(0, {show_header=false, scope="cursor", pos={0,first_line_len}}) + local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) + vim.api.nvim_win_close(winnr, true) + return lines + ]]) end) it('creates floating window and returns float bufnr and winnr if current line contains diagnostics', function()