diff options
Diffstat (limited to 'runtime/lua/vim/lsp/diagnostic.lua')
-rw-r--r-- | runtime/lua/vim/lsp/diagnostic.lua | 87 |
1 files changed, 37 insertions, 50 deletions
diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua index 6f2f846a3b..d4580885db 100644 --- a/runtime/lua/vim/lsp/diagnostic.lua +++ b/runtime/lua/vim/lsp/diagnostic.lua @@ -271,8 +271,12 @@ local function set_diagnostic_cache(diagnostics, bufnr, client_id) end -- Account for servers that place diagnostics on terminating newline if buf_line_count > 0 then - local start = diagnostic.range.start - start.line = math.min(start.line, buf_line_count - 1) + diagnostic.range.start.line = math.max(math.min( + diagnostic.range.start.line, buf_line_count - 1 + ), 0) + diagnostic.range["end"].line = math.max(math.min( + diagnostic.range["end"].line, buf_line_count - 1 + ), 0) end end @@ -317,9 +321,9 @@ function M.save(diagnostics, bufnr, client_id) -- Clean up our data when the buffer unloads. api.nvim_buf_attach(bufnr, false, { - on_detach = function(b) + on_detach = function(_, b) clear_diagnostic_cache(b, client_id) - _diagnostic_cleanup[bufnr][client_id] = nil + _diagnostic_cleanup[b][client_id] = nil end }) end @@ -330,15 +334,19 @@ end -- Diagnostic Retrieval {{{ ---- Get all diagnostics for all clients +--- Get all diagnostics for clients --- ----@return {bufnr: Diagnostic[]} -function M.get_all() +---@param client_id number Restrict included diagnostics to the client +--- If nil, diagnostics of all clients are included. +---@return table with diagnostics grouped by bufnr (bufnr: Diagnostic[]) +function M.get_all(client_id) local diagnostics_by_bufnr = {} for bufnr, buf_diagnostics in pairs(diagnostic_cache) do diagnostics_by_bufnr[bufnr] = {} - for _, client_diagnostics in pairs(buf_diagnostics) do - vim.list_extend(diagnostics_by_bufnr[bufnr], client_diagnostics) + for cid, client_diagnostics in pairs(buf_diagnostics) do + if client_id == nil or cid == client_id then + vim.list_extend(diagnostics_by_bufnr[bufnr], client_diagnostics) + end end end return diagnostics_by_bufnr @@ -1151,6 +1159,7 @@ function M.show_line_diagnostics(opts, bufnr, line_nr, client_id) end end + opts.focus_id = "line_diagnostics" local popup_bufnr, winnr = util.open_floating_preview(lines, 'plaintext', opts) for i, hi in ipairs(highlights) do local prefixlen, hiname = unpack(hi) @@ -1161,13 +1170,6 @@ function M.show_line_diagnostics(opts, bufnr, line_nr, client_id) return popup_bufnr, winnr end -local loclist_type_map = { - [DiagnosticSeverity.Error] = 'E', - [DiagnosticSeverity.Warning] = 'W', - [DiagnosticSeverity.Information] = 'I', - [DiagnosticSeverity.Hint] = 'I', -} - --- Clear diagnotics and diagnostic cache --- @@ -1196,44 +1198,29 @@ end --- - Exclusive severity to consider. Overrides {severity_limit} --- - {severity_limit}: (DiagnosticSeverity) --- - Limit severity of diagnostics found. E.g. "Warning" means { "Error", "Warning" } will be valid. +--- - {workspace}: (boolean, default false) +--- - Set the list with workspace diagnostics function M.set_loclist(opts) opts = opts or {} - local open_loclist = if_nil(opts.open_loclist, true) - - local bufnr = vim.api.nvim_get_current_buf() - local buffer_diags = M.get(bufnr, opts.client_id) - - if opts.severity then - buffer_diags = filter_to_severity_limit(opts.severity, buffer_diags) - elseif opts.severity_limit then - buffer_diags = filter_by_severity_limit(opts.severity_limit, buffer_diags) - end - - local items = {} - local insert_diag = function(diag) - local pos = diag.range.start - local row = pos.line - local col = util.character_offset(bufnr, row, pos.character) - - local line = (api.nvim_buf_get_lines(bufnr, row, row + 1, false) or {""})[1] - - table.insert(items, { - bufnr = bufnr, - lnum = row + 1, - col = col + 1, - text = line .. " | " .. diag.message, - type = loclist_type_map[diag.severity or DiagnosticSeverity.Error] or 'E', - }) - end - - for _, diag in ipairs(buffer_diags) do - insert_diag(diag) + local current_bufnr = api.nvim_get_current_buf() + local diags = opts.workspace and M.get_all(opts.client_id) or { + [current_bufnr] = M.get(current_bufnr, opts.client_id) + } + local predicate = function(d) + local severity = to_severity(opts.severity) + if severity then + return d.severity == severity + end + severity = to_severity(opts.severity_limit) + if severity then + return d.severity == severity + end + return true end - - table.sort(items, function(a, b) return a.lnum < b.lnum end) - - util.set_loclist(items) + local items = util.diagnostics_to_items(diags, predicate) + local win_id = vim.api.nvim_get_current_win() + util.set_loclist(items, win_id) if open_loclist then vim.cmd [[lopen]] end |