mirror of
https://github.com/neovim/neovim.git
synced 2024-12-24 05:05:00 -07:00
feat(diagnostic): goto functions jump to highest severity (#28490)
When the "severity" option is nil, vim.diagnostic.goto_next() and vim.diagnostic.goto_prev() jump to the next diagnostic with the highest severity.
This commit is contained in:
parent
e0d92b9cc2
commit
b13e63db1d
@ -389,8 +389,9 @@ Lua module: vim.diagnostic *diagnostic-api*
|
|||||||
|nvim_win_get_cursor()|.
|
|nvim_win_get_cursor()|.
|
||||||
• {wrap}? (`boolean`, default: `true`) Whether to loop
|
• {wrap}? (`boolean`, default: `true`) Whether to loop
|
||||||
around file or not. Similar to 'wrapscan'.
|
around file or not. Similar to 'wrapscan'.
|
||||||
• {severity} (`vim.diagnostic.Severity`) See
|
• {severity}? (`vim.diagnostic.Severity`) See
|
||||||
|diagnostic-severity|.
|
|diagnostic-severity|. If `nil`, go to the
|
||||||
|
diagnostic with the highest severity.
|
||||||
• {float}? (`boolean|vim.diagnostic.Opts.Float`, default:
|
• {float}? (`boolean|vim.diagnostic.Opts.Float`, default:
|
||||||
`true`) If `true`, call
|
`true`) If `true`, call
|
||||||
|vim.diagnostic.open_float()| after moving. If a
|
|vim.diagnostic.open_float()| after moving. If a
|
||||||
|
@ -387,6 +387,11 @@ The following changes to existing APIs or features add new behavior.
|
|||||||
• |vim.diagnostic.config()| now accepts a function for the virtual_text.prefix
|
• |vim.diagnostic.config()| now accepts a function for the virtual_text.prefix
|
||||||
option, which allows for rendering e.g., diagnostic severities differently.
|
option, which allows for rendering e.g., diagnostic severities differently.
|
||||||
|
|
||||||
|
• |vim.diagnostic.goto_next()| and |vim.diagnostic.goto_prev()| jump to the
|
||||||
|
diagnostic with the highest severity when the "severity" option is
|
||||||
|
unspecified. To use the old behavior, use: >lua
|
||||||
|
vim.diagnostic.goto_next({ severity = { min = vim.diagnostic.severity.HINT } })
|
||||||
|
|
||||||
• Defaults:
|
• Defaults:
|
||||||
• On Windows 'isfname' does not include ":". Drive letters are handled
|
• On Windows 'isfname' does not include ":". Drive letters are handled
|
||||||
correctly without it. (Use |gF| for filepaths suffixed with ":line:col").
|
correctly without it. (Use |gF| for filepaths suffixed with ":line:col").
|
||||||
|
@ -820,11 +820,35 @@ local function next_diagnostic(position, search_forward, bufnr, opts, namespace)
|
|||||||
position[1] = position[1] - 1
|
position[1] = position[1] - 1
|
||||||
bufnr = get_bufnr(bufnr)
|
bufnr = get_bufnr(bufnr)
|
||||||
local wrap = if_nil(opts.wrap, true)
|
local wrap = if_nil(opts.wrap, true)
|
||||||
local line_count = api.nvim_buf_line_count(bufnr)
|
|
||||||
local diagnostics =
|
local diagnostics =
|
||||||
get_diagnostics(bufnr, vim.tbl_extend('keep', opts, { namespace = namespace }), true)
|
get_diagnostics(bufnr, vim.tbl_extend('keep', opts, { namespace = namespace }), true)
|
||||||
|
|
||||||
|
-- When severity is unset we jump to the diagnostic with the highest severity. First sort the
|
||||||
|
-- diagnostics by severity. The first diagnostic then contains the highest severity, and we can
|
||||||
|
-- discard all diagnostics with a lower severity.
|
||||||
|
if opts.severity == nil then
|
||||||
|
table.sort(diagnostics, function(a, b)
|
||||||
|
return a.severity < b.severity
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Find the first diagnostic where the severity does not match the highest severity, and remove
|
||||||
|
-- that element and all subsequent elements from the array
|
||||||
|
local worst = (diagnostics[1] or {}).severity
|
||||||
|
local len = #diagnostics
|
||||||
|
for i = 2, len do
|
||||||
|
if diagnostics[i].severity ~= worst then
|
||||||
|
for j = i, len do
|
||||||
|
diagnostics[j] = nil
|
||||||
|
end
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local line_diagnostics = diagnostic_lines(diagnostics)
|
local line_diagnostics = diagnostic_lines(diagnostics)
|
||||||
|
|
||||||
|
local line_count = api.nvim_buf_line_count(bufnr)
|
||||||
for i = 0, line_count do
|
for i = 0, line_count do
|
||||||
local offset = i * (search_forward and 1 or -1)
|
local offset = i * (search_forward and 1 or -1)
|
||||||
local lnum = position[1] + offset
|
local lnum = position[1] + offset
|
||||||
@ -1165,8 +1189,8 @@ end
|
|||||||
--- (default: `true`)
|
--- (default: `true`)
|
||||||
--- @field wrap? boolean
|
--- @field wrap? boolean
|
||||||
---
|
---
|
||||||
--- See |diagnostic-severity|.
|
--- See |diagnostic-severity|. If `nil`, go to the diagnostic with the highest severity.
|
||||||
--- @field severity vim.diagnostic.Severity
|
--- @field severity? vim.diagnostic.Severity
|
||||||
---
|
---
|
||||||
--- If `true`, call |vim.diagnostic.open_float()| after moving.
|
--- If `true`, call |vim.diagnostic.open_float()| after moving.
|
||||||
--- If a table, pass the table as the {opts} parameter to |vim.diagnostic.open_float()|.
|
--- If a table, pass the table as the {opts} parameter to |vim.diagnostic.open_float()|.
|
||||||
|
@ -18,12 +18,12 @@ describe('vim.diagnostic', function()
|
|||||||
exec_lua [[
|
exec_lua [[
|
||||||
require('vim.diagnostic')
|
require('vim.diagnostic')
|
||||||
|
|
||||||
function make_diagnostic(msg, x1, y1, x2, y2, severity, source, code)
|
function make_diagnostic(msg, lnum, col, end_lnum, end_col, severity, source, code)
|
||||||
return {
|
return {
|
||||||
lnum = x1,
|
lnum = lnum,
|
||||||
col = y1,
|
col = col,
|
||||||
end_lnum = x2,
|
end_lnum = end_lnum,
|
||||||
end_col = y2,
|
end_col = end_col,
|
||||||
message = msg,
|
message = msg,
|
||||||
severity = severity,
|
severity = severity,
|
||||||
source = source,
|
source = source,
|
||||||
@ -31,20 +31,20 @@ describe('vim.diagnostic', function()
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
function make_error(msg, x1, y1, x2, y2, source, code)
|
function make_error(msg, lnum, col, end_lnum, end_col, source, code)
|
||||||
return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.ERROR, source, code)
|
return make_diagnostic(msg, lnum, col, end_lnum, end_col, vim.diagnostic.severity.ERROR, source, code)
|
||||||
end
|
end
|
||||||
|
|
||||||
function make_warning(msg, x1, y1, x2, y2, source, code)
|
function make_warning(msg, lnum, col, end_lnum, end_col, source, code)
|
||||||
return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.WARN, source, code)
|
return make_diagnostic(msg, lnum, col, end_lnum, end_col, vim.diagnostic.severity.WARN, source, code)
|
||||||
end
|
end
|
||||||
|
|
||||||
function make_info(msg, x1, y1, x2, y2, source, code)
|
function make_info(msg, lnum, col, end_lnum, end_col, source, code)
|
||||||
return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.INFO, source, code)
|
return make_diagnostic(msg, lnum, col, end_lnum, end_col, vim.diagnostic.severity.INFO, source, code)
|
||||||
end
|
end
|
||||||
|
|
||||||
function make_hint(msg, x1, y1, x2, y2, source, code)
|
function make_hint(msg, lnum, col, end_lnum, end_col, source, code)
|
||||||
return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.HINT, source, code)
|
return make_diagnostic(msg, lnum, col, end_lnum, end_col, vim.diagnostic.severity.HINT, source, code)
|
||||||
end
|
end
|
||||||
|
|
||||||
function count_diagnostics(bufnr, severity, namespace)
|
function count_diagnostics(bufnr, severity, namespace)
|
||||||
@ -934,15 +934,112 @@ describe('vim.diagnostic', function()
|
|||||||
eq(
|
eq(
|
||||||
{ 4, 0 },
|
{ 4, 0 },
|
||||||
exec_lua [[
|
exec_lua [[
|
||||||
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
|
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
|
||||||
make_error('Diagnostic #1', 3, 9001, 3, 9001),
|
make_error('Diagnostic #1', 3, 9001, 3, 9001),
|
||||||
make_error('Diagnostic #2', 4, -1, 4, -1),
|
make_error('Diagnostic #2', 4, -1, 4, -1),
|
||||||
})
|
})
|
||||||
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
|
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
|
||||||
vim.api.nvim_win_set_cursor(0, {1, 1})
|
vim.api.nvim_win_set_cursor(0, {1, 1})
|
||||||
vim.diagnostic.goto_next { float = false }
|
vim.diagnostic.goto_next { float = false }
|
||||||
return vim.diagnostic.get_next_pos { namespace = diagnostic_ns }
|
return vim.diagnostic.get_next_pos { namespace = diagnostic_ns }
|
||||||
]]
|
]]
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('jumps to diagnostic with highest severity', function()
|
||||||
|
exec_lua([[
|
||||||
|
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
|
||||||
|
make_info('Info', 1, 0, 1, 1),
|
||||||
|
make_error('Error', 2, 0, 2, 1),
|
||||||
|
make_warning('Warning', 3, 0, 3, 1),
|
||||||
|
make_error('Error', 4, 0, 4, 1),
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
|
||||||
|
vim.api.nvim_win_set_cursor(0, {1, 0})
|
||||||
|
]])
|
||||||
|
|
||||||
|
eq(
|
||||||
|
{ 3, 0 },
|
||||||
|
exec_lua([[
|
||||||
|
vim.diagnostic.goto_next()
|
||||||
|
return vim.api.nvim_win_get_cursor(0)
|
||||||
|
]])
|
||||||
|
)
|
||||||
|
|
||||||
|
eq(
|
||||||
|
{ 5, 0 },
|
||||||
|
exec_lua([[
|
||||||
|
vim.diagnostic.goto_next()
|
||||||
|
return vim.api.nvim_win_get_cursor(0)
|
||||||
|
]])
|
||||||
|
)
|
||||||
|
|
||||||
|
exec_lua([[
|
||||||
|
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
|
||||||
|
make_info('Info', 1, 0, 1, 1),
|
||||||
|
make_hint('Hint', 2, 0, 2, 1),
|
||||||
|
make_warning('Warning', 3, 0, 3, 1),
|
||||||
|
make_hint('Hint', 4, 0, 4, 1),
|
||||||
|
make_warning('Warning', 5, 0, 5, 1),
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
|
||||||
|
vim.api.nvim_win_set_cursor(0, {1, 0})
|
||||||
|
]])
|
||||||
|
|
||||||
|
eq(
|
||||||
|
{ 4, 0 },
|
||||||
|
exec_lua([[
|
||||||
|
vim.diagnostic.goto_next()
|
||||||
|
return vim.api.nvim_win_get_cursor(0)
|
||||||
|
]])
|
||||||
|
)
|
||||||
|
|
||||||
|
eq(
|
||||||
|
{ 6, 0 },
|
||||||
|
exec_lua([[
|
||||||
|
vim.diagnostic.goto_next()
|
||||||
|
return vim.api.nvim_win_get_cursor(0)
|
||||||
|
]])
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('jumps to next diagnostic if severity is non-nil', function()
|
||||||
|
exec_lua([[
|
||||||
|
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
|
||||||
|
make_info('Info', 1, 0, 1, 1),
|
||||||
|
make_error('Error', 2, 0, 2, 1),
|
||||||
|
make_warning('Warning', 3, 0, 3, 1),
|
||||||
|
make_error('Error', 4, 0, 4, 1),
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
|
||||||
|
vim.api.nvim_win_set_cursor(0, {1, 0})
|
||||||
|
]])
|
||||||
|
|
||||||
|
eq(
|
||||||
|
{ 2, 0 },
|
||||||
|
exec_lua([[
|
||||||
|
vim.diagnostic.goto_next({ severity = { min = vim.diagnostic.severity.HINT } })
|
||||||
|
return vim.api.nvim_win_get_cursor(0)
|
||||||
|
]])
|
||||||
|
)
|
||||||
|
|
||||||
|
eq(
|
||||||
|
{ 3, 0 },
|
||||||
|
exec_lua([[
|
||||||
|
vim.diagnostic.goto_next({ severity = { min = vim.diagnostic.severity.HINT } })
|
||||||
|
return vim.api.nvim_win_get_cursor(0)
|
||||||
|
]])
|
||||||
|
)
|
||||||
|
|
||||||
|
eq(
|
||||||
|
{ 4, 0 },
|
||||||
|
exec_lua([[
|
||||||
|
vim.diagnostic.goto_next({ severity = { min = vim.diagnostic.severity.HINT } })
|
||||||
|
return vim.api.nvim_win_get_cursor(0)
|
||||||
|
]])
|
||||||
)
|
)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user