aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/lsp/diagnostic.lua
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim/lsp/diagnostic.lua')
-rw-r--r--runtime/lua/vim/lsp/diagnostic.lua87
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