mirror of
https://github.com/neovim/neovim.git
synced 2025-10-22 17:11:49 +00:00
lsp: Add severity_limit for other diagnostics features (#13528)
* lsp: Add severity_limit for other diagnostics * docs and tests * fix: lint * Add to other types * fix: lint
This commit is contained in:
@@ -1340,10 +1340,14 @@ set_underline({diagnostics}, {bufnr}, {client_id}, {diagnostic_ns}, {opts})
|
|||||||
|
|
||||||
Parameters: ~
|
Parameters: ~
|
||||||
{diagnostics} Diagnostic []
|
{diagnostics} Diagnostic []
|
||||||
{bufnr} number The buffer number
|
{bufnr} number: The buffer number
|
||||||
{client_id} number the client id
|
{client_id} number: The client id
|
||||||
{diagnostic_ns} number|nil
|
{diagnostic_ns} number|nil: The namespace
|
||||||
{opts} table Currently unused.
|
{opts} table: Configuration table:
|
||||||
|
• severity_limit (DiagnosticSeverity):
|
||||||
|
• Limit severity of diagnostics found.
|
||||||
|
E.g. "Warning" means { "Error",
|
||||||
|
"Warning" } will be valid.
|
||||||
|
|
||||||
*vim.lsp.diagnostic.set_virtual_text()*
|
*vim.lsp.diagnostic.set_virtual_text()*
|
||||||
set_virtual_text({diagnostics}, {bufnr}, {client_id}, {diagnostic_ns}, {opts})
|
set_virtual_text({diagnostics}, {bufnr}, {client_id}, {diagnostic_ns}, {opts})
|
||||||
@@ -1370,6 +1374,10 @@ set_virtual_text({diagnostics}, {bufnr}, {client_id}, {diagnostic_ns}, {opts})
|
|||||||
before virtual text on line
|
before virtual text on line
|
||||||
• spacing (number): Number of spaces to
|
• spacing (number): Number of spaces to
|
||||||
insert before virtual text
|
insert before virtual text
|
||||||
|
• severity_limit (DiagnosticSeverity):
|
||||||
|
• Limit severity of diagnostics found.
|
||||||
|
E.g. "Warning" means { "Error",
|
||||||
|
"Warning" } will be valid.
|
||||||
|
|
||||||
*vim.lsp.diagnostic.show_line_diagnostics()*
|
*vim.lsp.diagnostic.show_line_diagnostics()*
|
||||||
show_line_diagnostics({opts}, {bufnr}, {line_nr}, {client_id})
|
show_line_diagnostics({opts}, {bufnr}, {line_nr}, {client_id})
|
||||||
|
@@ -16,6 +16,24 @@ local to_severity = function(severity)
|
|||||||
return type(severity) == 'string' and DiagnosticSeverity[severity] or severity
|
return type(severity) == 'string' and DiagnosticSeverity[severity] or severity
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local filter_to_severity_limit = function(severity, diagnostics)
|
||||||
|
local filter_level = to_severity(severity)
|
||||||
|
if not filter_level then
|
||||||
|
return diagnostics
|
||||||
|
end
|
||||||
|
|
||||||
|
return vim.tbl_filter(function(t) return t.severity == filter_level end, diagnostics)
|
||||||
|
end
|
||||||
|
|
||||||
|
local filter_by_severity_limit = function(severity_limit, diagnostics)
|
||||||
|
local filter_level = to_severity(severity_limit)
|
||||||
|
if not filter_level then
|
||||||
|
return diagnostics
|
||||||
|
end
|
||||||
|
|
||||||
|
return vim.tbl_filter(function(t) return t.severity <= filter_level end, diagnostics)
|
||||||
|
end
|
||||||
|
|
||||||
local to_position = function(position, bufnr)
|
local to_position = function(position, bufnr)
|
||||||
vim.validate { position = {position, 't'} }
|
vim.validate { position = {position, 't'} }
|
||||||
|
|
||||||
@@ -377,11 +395,9 @@ function M.get_line_diagnostics(bufnr, line_nr, opts, client_id)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if opts.severity then
|
if opts.severity then
|
||||||
local filter_level = to_severity(opts.severity)
|
line_diagnostics = filter_to_severity_limit(opts.severity, line_diagnostics)
|
||||||
line_diagnostics = vim.tbl_filter(function(t) return t.severity == filter_level end, line_diagnostics)
|
|
||||||
elseif opts.severity_limit then
|
elseif opts.severity_limit then
|
||||||
local filter_level = to_severity(opts.severity_limit)
|
line_diagnostics = filter_by_severity_limit(opts.severity_limit, line_diagnostics)
|
||||||
line_diagnostics = vim.tbl_filter(function(t) return t.severity <= filter_level end, line_diagnostics)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if opts.severity_sort then
|
if opts.severity_sort then
|
||||||
@@ -542,7 +558,7 @@ function M.goto_prev(opts)
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get the previous diagnostic closest to the cursor_position
|
--- Get the next diagnostic closest to the cursor_position
|
||||||
---@param opts table See |vim.lsp.diagnostic.goto_next()|
|
---@param opts table See |vim.lsp.diagnostic.goto_next()|
|
||||||
---@return table Next diagnostic
|
---@return table Next diagnostic
|
||||||
function M.get_next(opts)
|
function M.get_next(opts)
|
||||||
@@ -609,6 +625,8 @@ end
|
|||||||
---@param sign_ns number|nil
|
---@param sign_ns number|nil
|
||||||
---@param opts table Configuration for signs. Keys:
|
---@param opts table Configuration for signs. Keys:
|
||||||
--- - priority: Set the priority of the signs.
|
--- - priority: Set the priority of the signs.
|
||||||
|
--- - severity_limit (DiagnosticSeverity):
|
||||||
|
--- - Limit severity of diagnostics found. E.g. "Warning" means { "Error", "Warning" } will be valid.
|
||||||
function M.set_signs(diagnostics, bufnr, client_id, sign_ns, opts)
|
function M.set_signs(diagnostics, bufnr, client_id, sign_ns, opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
sign_ns = sign_ns or M._get_sign_namespace(client_id)
|
sign_ns = sign_ns or M._get_sign_namespace(client_id)
|
||||||
@@ -622,9 +640,11 @@ function M.set_signs(diagnostics, bufnr, client_id, sign_ns, opts)
|
|||||||
end
|
end
|
||||||
|
|
||||||
bufnr = get_bufnr(bufnr)
|
bufnr = get_bufnr(bufnr)
|
||||||
|
diagnostics = filter_by_severity_limit(opts.severity_limit, diagnostics)
|
||||||
|
|
||||||
local ok = true
|
local ok = true
|
||||||
for _, diagnostic in ipairs(diagnostics) do
|
for _, diagnostic in ipairs(diagnostics) do
|
||||||
|
|
||||||
ok = ok and pcall(vim.fn.sign_place,
|
ok = ok and pcall(vim.fn.sign_place,
|
||||||
0,
|
0,
|
||||||
sign_ns,
|
sign_ns,
|
||||||
@@ -654,15 +674,17 @@ end
|
|||||||
--- </pre>
|
--- </pre>
|
||||||
---
|
---
|
||||||
---@param diagnostics Diagnostic[]
|
---@param diagnostics Diagnostic[]
|
||||||
---@param bufnr number The buffer number
|
---@param bufnr number: The buffer number
|
||||||
---@param client_id number the client id
|
---@param client_id number: The client id
|
||||||
---@param diagnostic_ns number|nil
|
---@param diagnostic_ns number|nil: The namespace
|
||||||
---@param opts table Currently unused.
|
---@param opts table: Configuration table:
|
||||||
|
--- - severity_limit (DiagnosticSeverity):
|
||||||
|
--- - Limit severity of diagnostics found. E.g. "Warning" means { "Error", "Warning" } will be valid.
|
||||||
function M.set_underline(diagnostics, bufnr, client_id, diagnostic_ns, opts)
|
function M.set_underline(diagnostics, bufnr, client_id, diagnostic_ns, opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
assert(opts) -- lint
|
|
||||||
|
|
||||||
diagnostic_ns = diagnostic_ns or M._get_diagnostic_namespace(client_id)
|
diagnostic_ns = diagnostic_ns or M._get_diagnostic_namespace(client_id)
|
||||||
|
diagnostics = filter_by_severity_limit(opts.severity_limit, diagnostics)
|
||||||
|
|
||||||
for _, diagnostic in ipairs(diagnostics) do
|
for _, diagnostic in ipairs(diagnostics) do
|
||||||
local start = diagnostic.range["start"]
|
local start = diagnostic.range["start"]
|
||||||
@@ -703,6 +725,8 @@ end
|
|||||||
---@param opts table Options on how to display virtual text. Keys:
|
---@param opts table Options on how to display virtual text. Keys:
|
||||||
--- - prefix (string): Prefix to display before virtual text on line
|
--- - prefix (string): Prefix to display before virtual text on line
|
||||||
--- - spacing (number): Number of spaces to insert before virtual text
|
--- - spacing (number): Number of spaces to insert before virtual text
|
||||||
|
--- - severity_limit (DiagnosticSeverity):
|
||||||
|
--- - Limit severity of diagnostics found. E.g. "Warning" means { "Error", "Warning" } will be valid.
|
||||||
function M.set_virtual_text(diagnostics, bufnr, client_id, diagnostic_ns, opts)
|
function M.set_virtual_text(diagnostics, bufnr, client_id, diagnostic_ns, opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
|
||||||
@@ -721,6 +745,7 @@ function M.set_virtual_text(diagnostics, bufnr, client_id, diagnostic_ns, opts)
|
|||||||
end
|
end
|
||||||
|
|
||||||
for line, line_diagnostics in pairs(buffer_line_diagnostics) do
|
for line, line_diagnostics in pairs(buffer_line_diagnostics) do
|
||||||
|
line_diagnostics = filter_by_severity_limit(opts.severity_limit, line_diagnostics)
|
||||||
local virt_texts = M.get_virtual_text_chunks_for_line(bufnr, line, line_diagnostics, opts)
|
local virt_texts = M.get_virtual_text_chunks_for_line(bufnr, line, line_diagnostics, opts)
|
||||||
|
|
||||||
if virt_texts then
|
if virt_texts then
|
||||||
@@ -1082,7 +1107,7 @@ end
|
|||||||
---@param bufnr number The buffer number
|
---@param bufnr number The buffer number
|
||||||
---@param line_nr number The line number
|
---@param line_nr number The line number
|
||||||
---@param client_id number|nil the client id
|
---@param client_id number|nil the client id
|
||||||
---@return {popup_bufnr, win_id}
|
---@return table {popup_bufnr, win_id}
|
||||||
function M.show_line_diagnostics(opts, bufnr, line_nr, client_id)
|
function M.show_line_diagnostics(opts, bufnr, line_nr, client_id)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
opts.severity_sort = if_nil(opts.severity_sort, true)
|
opts.severity_sort = if_nil(opts.severity_sort, true)
|
||||||
@@ -1151,30 +1176,14 @@ function M.set_loclist(opts)
|
|||||||
local bufnr = vim.api.nvim_get_current_buf()
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
local buffer_diags = M.get(bufnr, opts.client_id)
|
local buffer_diags = M.get(bufnr, opts.client_id)
|
||||||
|
|
||||||
local severity = to_severity(opts.severity)
|
if opts.severity then
|
||||||
local severity_limit = to_severity(opts.severity_limit)
|
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 items = {}
|
||||||
local insert_diag = function(diag)
|
local insert_diag = function(diag)
|
||||||
if severity then
|
|
||||||
-- Handle missing severities
|
|
||||||
if not diag.severity then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if severity ~= diag.severity then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
elseif severity_limit then
|
|
||||||
if not diag.severity then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if severity_limit < diag.severity then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local pos = diag.range.start
|
local pos = diag.range.start
|
||||||
local row = pos.line
|
local row = pos.line
|
||||||
local col = util.character_offset(bufnr, row, pos.character)
|
local col = util.character_offset(bufnr, row, pos.character)
|
||||||
|
@@ -12,41 +12,41 @@ describe('vim.lsp.diagnostic', function()
|
|||||||
clear()
|
clear()
|
||||||
|
|
||||||
exec_lua [[
|
exec_lua [[
|
||||||
require('vim.lsp')
|
require('vim.lsp')
|
||||||
|
|
||||||
make_range = function(x1, y1, x2, y2)
|
make_range = function(x1, y1, x2, y2)
|
||||||
return { start = { line = x1, character = y1 }, ['end'] = { line = x2, character = y2 } }
|
return { start = { line = x1, character = y1 }, ['end'] = { line = x2, character = y2 } }
|
||||||
end
|
end
|
||||||
|
|
||||||
make_error = function(msg, x1, y1, x2, y2)
|
make_error = function(msg, x1, y1, x2, y2)
|
||||||
return {
|
return {
|
||||||
range = make_range(x1, y1, x2, y2),
|
range = make_range(x1, y1, x2, y2),
|
||||||
message = msg,
|
message = msg,
|
||||||
severity = 1,
|
severity = 1,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
make_warning = function(msg, x1, y1, x2, y2)
|
make_warning = function(msg, x1, y1, x2, y2)
|
||||||
return {
|
return {
|
||||||
range = make_range(x1, y1, x2, y2),
|
range = make_range(x1, y1, x2, y2),
|
||||||
message = msg,
|
message = msg,
|
||||||
severity = 2,
|
severity = 2,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
make_information = function(msg, x1, y1, x2, y2)
|
make_information = function(msg, x1, y1, x2, y2)
|
||||||
return {
|
return {
|
||||||
range = make_range(x1, y1, x2, y2),
|
range = make_range(x1, y1, x2, y2),
|
||||||
message = msg,
|
message = msg,
|
||||||
severity = 3,
|
severity = 3,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
count_of_extmarks_for_client = function(bufnr, client_id)
|
count_of_extmarks_for_client = function(bufnr, client_id)
|
||||||
return #vim.api.nvim_buf_get_extmarks(
|
return #vim.api.nvim_buf_get_extmarks(
|
||||||
bufnr, vim.lsp.diagnostic._get_diagnostic_namespace(client_id), 0, -1, {}
|
bufnr, vim.lsp.diagnostic._get_diagnostic_namespace(client_id), 0, -1, {}
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
]]
|
]]
|
||||||
|
|
||||||
fake_uri = "file://fake/uri"
|
fake_uri = "file://fake/uri"
|
||||||
@@ -640,6 +640,36 @@ describe('vim.lsp.diagnostic', function()
|
|||||||
|
|
||||||
eq(expected_spacing, #spacing)
|
eq(expected_spacing, #spacing)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('allows filtering via severity limit', function()
|
||||||
|
local get_extmark_count_with_severity = function(severity_limit)
|
||||||
|
return exec_lua([[
|
||||||
|
PublishDiagnostics = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, {
|
||||||
|
underline = false,
|
||||||
|
virtual_text = {
|
||||||
|
severity_limit = ...
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
PublishDiagnostics(nil, nil, {
|
||||||
|
uri = fake_uri,
|
||||||
|
diagnostics = {
|
||||||
|
make_warning('Delayed Diagnostic', 4, 4, 4, 4),
|
||||||
|
}
|
||||||
|
}, 1
|
||||||
|
)
|
||||||
|
|
||||||
|
return count_of_extmarks_for_client(diagnostic_bufnr, 1)
|
||||||
|
]], severity_limit)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- No messages with Error or higher
|
||||||
|
eq(0, get_extmark_count_with_severity("Error"))
|
||||||
|
|
||||||
|
-- But now we don't filter it
|
||||||
|
eq(1, get_extmark_count_with_severity("Warning"))
|
||||||
|
eq(1, get_extmark_count_with_severity("Hint"))
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('lsp.util.show_line_diagnostics', function()
|
describe('lsp.util.show_line_diagnostics', function()
|
||||||
|
Reference in New Issue
Block a user