feat(diagnostic): add vim.diagnostic.jump() (#26745)

Deprecate vim.diagnostic.goto_prev() and vim.diagnostic.goto_next() in
favor of a unified vim.diagnostic.jump() interface.

We cannot name the function "goto()" because some of our tooling
(luacheck and stylua) fail to parse it, presumably because "goto" is a
keyword in newer versions of Lua.

vim.diagnostic.jump() also allows moving to a specific diagnostic and
moving by multiple diagnostics at a time (useful for creating mappings
that use v:count).
This commit is contained in:
Gregory Anders
2024-05-28 08:51:44 -05:00
committed by GitHub
parent 90a4b1a59c
commit 8ba73f0e4c
4 changed files with 401 additions and 189 deletions

View File

@@ -22,6 +22,20 @@ API
LUA LUA
- vim.region() Use |getregionpos()| instead. - vim.region() Use |getregionpos()| instead.
DIAGNOSTICS
- *vim.diagnostic.goto_next()* Use |vim.diagnostic.jump()| with `{count = 1}` instead.
- *vim.diagnostic.goto_prev()* Use |vim.diagnostic.jump()| with `{count = -1}` instead.
- *vim.diagnostic.get_next_pos()*
Use the "lnum" and "col" fields from the return value of
|vim.diagnostic.get_next()| instead.
- *vim.diagnostic.get_prev_pos()*
Use the "lnum" and "col" fields from the return value of
|vim.diagnostic.get_prev()| instead.
- The "win_id" parameter used by various functions is deprecated in favor of
"winid" |winid|
- The "cursor_position" parameter of |vim.diagnostic.JumpOpts| is renamed to
"pos"
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
DEPRECATED IN 0.10 *deprecated-0.10* DEPRECATED IN 0.10 *deprecated-0.10*
@@ -204,9 +218,6 @@ internally and are no longer exposed as part of the API. Instead, use
- *vim.lsp.diagnostic.set_underline()* - *vim.lsp.diagnostic.set_underline()*
- *vim.lsp.diagnostic.set_virtual_text()* - *vim.lsp.diagnostic.set_virtual_text()*
Configuring |diagnostic-signs| with |:sign-define| or |sign_define()| is no
longer supported. Use the "signs" key of |vim.diagnostic.config()| instead.
LSP FUNCTIONS LSP FUNCTIONS
- *vim.lsp.buf.server_ready()* - *vim.lsp.buf.server_ready()*
Use |LspAttach| instead, depending on your use-case. "Server ready" is not Use |LspAttach| instead, depending on your use-case. "Server ready" is not

View File

@@ -378,28 +378,37 @@ Lua module: vim.diagnostic *diagnostic-api*
• {severity}? (`vim.diagnostic.SeverityFilter`) See • {severity}? (`vim.diagnostic.SeverityFilter`) See
|diagnostic-severity|. |diagnostic-severity|.
*vim.diagnostic.GotoOpts* *vim.diagnostic.JumpOpts*
Extends: |vim.diagnostic.GetOpts| Extends: |vim.diagnostic.GetOpts|
Configuration table with the following keys: Configuration table with the following keys:
Fields: ~ Fields: ~
• {cursor_position}? (`{[1]:integer,[2]:integer}`, default: current cursor position) • {diagnostic}? (`vim.Diagnostic`) The diagnostic to jump to. Mutually
Cursor position as a `(row, col)` tuple. See exclusive with {count}, {namespace}, and {severity}.
|nvim_win_get_cursor()|. See |vim.Diagnostic|.
• {wrap}? (`boolean`, default: `true`) Whether to loop • {count}? (`integer`) The number of diagnostics to move by,
around file or not. Similar to 'wrapscan'. starting from {pos}. A positive integer moves forward
by {count} diagnostics, while a negative integer moves
backward by {count} diagnostics. Mutually exclusive
with {diagnostic}.
• {pos}? (`{[1]:integer,[2]:integer}`) Cursor position as a
`(row, col)` tuple. See |nvim_win_get_cursor()|. Used
to find the nearest diagnostic when {count} is used.
Only used when {count} is non-nil. Default is the
current cursor position.
• {wrap}? (`boolean`, default: `true`) Whether to loop around
file or not. Similar to 'wrapscan'.
• {severity}? (`vim.diagnostic.SeverityFilter`) See • {severity}? (`vim.diagnostic.SeverityFilter`) See
|diagnostic-severity|. |diagnostic-severity|.
• {float}? (`boolean|vim.diagnostic.Opts.Float`, default: • {float}? (`boolean|vim.diagnostic.Opts.Float`, default: `true`)
`true`) If `true`, call If `true`, call |vim.diagnostic.open_float()| after
|vim.diagnostic.open_float()| after moving. If a moving. If a table, pass the table as the {opts}
table, pass the table as the {opts} parameter to parameter to |vim.diagnostic.open_float()|. Unless
|vim.diagnostic.open_float()|. Unless overridden, overridden, the float will show diagnostics at the new
the float will show diagnostics at the new cursor cursor position (as if "cursor" were passed to the
position (as if "cursor" were passed to the
"scope" option). "scope" option).
• {win_id}? (`integer`, default: `0`) Window ID • {winid}? (`integer`, default: `0`) Window ID
*vim.diagnostic.NS* *vim.diagnostic.NS*
@@ -678,52 +687,20 @@ get_next({opts}) *vim.diagnostic.get_next()*
Get the next diagnostic closest to the cursor position. Get the next diagnostic closest to the cursor position.
Parameters: ~ Parameters: ~
• {opts} (`vim.diagnostic.GotoOpts?`) See |vim.diagnostic.GotoOpts|. • {opts} (`vim.diagnostic.JumpOpts?`) See |vim.diagnostic.JumpOpts|.
Return: ~ Return: ~
(`vim.Diagnostic?`) Next diagnostic. See |vim.Diagnostic|. (`vim.Diagnostic?`) Next diagnostic. See |vim.Diagnostic|.
get_next_pos({opts}) *vim.diagnostic.get_next_pos()*
Return the position of the next diagnostic in the current buffer.
Parameters: ~
• {opts} (`vim.diagnostic.GotoOpts?`) See |vim.diagnostic.GotoOpts|.
Return: ~
(`table|false`) Next diagnostic position as a `(row, col)` tuple or
false if no next diagnostic.
get_prev({opts}) *vim.diagnostic.get_prev()* get_prev({opts}) *vim.diagnostic.get_prev()*
Get the previous diagnostic closest to the cursor position. Get the previous diagnostic closest to the cursor position.
Parameters: ~ Parameters: ~
• {opts} (`vim.diagnostic.GotoOpts?`) See |vim.diagnostic.GotoOpts|. • {opts} (`vim.diagnostic.JumpOpts?`) See |vim.diagnostic.JumpOpts|.
Return: ~ Return: ~
(`vim.Diagnostic?`) Previous diagnostic. See |vim.Diagnostic|. (`vim.Diagnostic?`) Previous diagnostic. See |vim.Diagnostic|.
get_prev_pos({opts}) *vim.diagnostic.get_prev_pos()*
Return the position of the previous diagnostic in the current buffer.
Parameters: ~
• {opts} (`vim.diagnostic.GotoOpts?`) See |vim.diagnostic.GotoOpts|.
Return: ~
(`table|false`) Previous diagnostic position as a `(row, col)` tuple
or `false` if there is no prior diagnostic.
goto_next({opts}) *vim.diagnostic.goto_next()*
Move to the next diagnostic.
Parameters: ~
• {opts} (`vim.diagnostic.GotoOpts?`) See |vim.diagnostic.GotoOpts|.
goto_prev({opts}) *vim.diagnostic.goto_prev()*
Move to the previous diagnostic in the current buffer.
Parameters: ~
• {opts} (`vim.diagnostic.GotoOpts?`) See |vim.diagnostic.GotoOpts|.
hide({namespace}, {bufnr}) *vim.diagnostic.hide()* hide({namespace}, {bufnr}) *vim.diagnostic.hide()*
Hide currently displayed diagnostics. Hide currently displayed diagnostics.
@@ -753,6 +730,16 @@ is_enabled({filter}) *vim.diagnostic.is_enabled()*
Return: ~ Return: ~
(`boolean`) (`boolean`)
jump({opts}) *vim.diagnostic.jump()*
Move to a diagnostic.
Parameters: ~
• {opts} (`vim.diagnostic.JumpOpts`) See |vim.diagnostic.JumpOpts|.
Return: ~
(`vim.Diagnostic?`) The diagnostic that was moved to. See
|vim.Diagnostic|.
*vim.diagnostic.match()* *vim.diagnostic.match()*
match({str}, {pat}, {groups}, {severity_map}, {defaults}) match({str}, {pat}, {groups}, {severity_map}, {defaults})
Parse a diagnostic from a string. Parse a diagnostic from a string.
@@ -792,7 +779,7 @@ open_float({opts}) *vim.diagnostic.open_float()*
Return (multiple): ~ Return (multiple): ~
(`integer?`) float_bufnr (`integer?`) float_bufnr
(`integer?`) win_id (`integer?`) winid
reset({namespace}, {bufnr}) *vim.diagnostic.reset()* reset({namespace}, {bufnr}) *vim.diagnostic.reset()*
Remove all diagnostics from the given namespace. Remove all diagnostics from the given namespace.

View File

@@ -835,21 +835,36 @@ local function filter_highest(diagnostics)
end end
end end
--- @param position {[1]: integer, [2]: integer}
--- @param search_forward boolean --- @param search_forward boolean
--- @param bufnr integer --- @param opts vim.diagnostic.JumpOpts?
--- @param opts vim.diagnostic.GotoOpts
--- @param namespace integer[]|integer
--- @return vim.Diagnostic? --- @return vim.Diagnostic?
local function next_diagnostic(position, search_forward, bufnr, opts, namespace) local function next_diagnostic(search_forward, opts)
opts = opts or {}
-- Support deprecated win_id alias
if opts.win_id then
vim.deprecate('opts.win_id', 'opts.winid', '0.13')
opts.winid = opts.win_id
opts.win_id = nil
end
-- Support deprecated cursor_position alias
if opts.cursor_position then
vim.deprecate('opts.cursor_position', 'opts.pos', '0.13')
opts.pos = opts.cursor_position
opts.cursor_position = nil
end
local winid = opts.winid or api.nvim_get_current_win()
local bufnr = api.nvim_win_get_buf(winid)
local position = opts.pos or api.nvim_win_get_cursor(winid)
-- Adjust row to be 0-indexed
position[1] = position[1] - 1 position[1] = position[1] - 1
bufnr = get_bufnr(bufnr)
local wrap = if_nil(opts.wrap, true) local wrap = if_nil(opts.wrap, true)
local get_opts = vim.deepcopy(opts) local diagnostics = get_diagnostics(bufnr, opts, true)
get_opts.namespace = get_opts.namespace or namespace
local diagnostics = get_diagnostics(bufnr, get_opts, true)
if opts._highest then if opts._highest then
filter_highest(diagnostics) filter_highest(diagnostics)
@@ -902,32 +917,41 @@ local function next_diagnostic(position, search_forward, bufnr, opts, namespace)
end end
end end
--- @param opts vim.diagnostic.GotoOpts? --- Move the cursor to the given diagnostic.
--- @param pos {[1]:integer,[2]:integer}|false ---
local function diagnostic_move_pos(opts, pos) --- @param diagnostic vim.Diagnostic?
opts = opts or {} --- @param opts vim.diagnostic.JumpOpts?
local function goto_diagnostic(diagnostic, opts)
local float = if_nil(opts.float, true) if not diagnostic then
local win_id = opts.win_id or api.nvim_get_current_win()
if not pos then
api.nvim_echo({ { 'No more valid diagnostics to move to', 'WarningMsg' } }, true, {}) api.nvim_echo({ { 'No more valid diagnostics to move to', 'WarningMsg' } }, true, {})
return return
end end
api.nvim_win_call(win_id, function() opts = opts or {}
-- Support deprecated win_id alias
if opts.win_id then
vim.deprecate('opts.win_id', 'opts.winid', '0.13')
opts.winid = opts.win_id
opts.win_id = nil
end
local winid = opts.winid or api.nvim_get_current_win()
api.nvim_win_call(winid, function()
-- Save position in the window's jumplist -- Save position in the window's jumplist
vim.cmd("normal! m'") vim.cmd("normal! m'")
api.nvim_win_set_cursor(win_id, { pos[1] + 1, pos[2] }) api.nvim_win_set_cursor(winid, { diagnostic.lnum + 1, diagnostic.col })
-- Open folds under the cursor -- Open folds under the cursor
vim.cmd('normal! zv') vim.cmd('normal! zv')
end) end)
local float = if_nil(opts.float, true)
if float then if float then
local float_opts = type(float) == 'table' and float or {} local float_opts = type(float) == 'table' and float or {}
vim.schedule(function() vim.schedule(function()
M.open_float(vim.tbl_extend('keep', float_opts, { M.open_float(vim.tbl_extend('keep', float_opts, {
bufnr = api.nvim_win_get_buf(win_id), bufnr = api.nvim_win_get_buf(winid),
scope = 'cursor', scope = 'cursor',
focus = false, focus = false,
})) }))
@@ -1114,24 +1138,24 @@ end
--- Get the previous diagnostic closest to the cursor position. --- Get the previous diagnostic closest to the cursor position.
--- ---
---@param opts? vim.diagnostic.GotoOpts ---@param opts? vim.diagnostic.JumpOpts
---@return vim.Diagnostic? : Previous diagnostic ---@return vim.Diagnostic? : Previous diagnostic
function M.get_prev(opts) function M.get_prev(opts)
opts = opts or {} return next_diagnostic(false, opts)
local win_id = opts.win_id or api.nvim_get_current_win()
local bufnr = api.nvim_win_get_buf(win_id)
local cursor_position = opts.cursor_position or api.nvim_win_get_cursor(win_id)
return next_diagnostic(cursor_position, false, bufnr, opts, opts.namespace)
end end
--- Return the position of the previous diagnostic in the current buffer. --- Return the position of the previous diagnostic in the current buffer.
--- ---
---@param opts? vim.diagnostic.GotoOpts ---@param opts? vim.diagnostic.JumpOpts
---@return table|false: Previous diagnostic position as a `(row, col)` tuple ---@return table|false: Previous diagnostic position as a `(row, col)` tuple
--- or `false` if there is no prior diagnostic. --- or `false` if there is no prior diagnostic.
---@deprecated
function M.get_prev_pos(opts) function M.get_prev_pos(opts)
vim.deprecate(
'vim.diagnostic.get_prev_pos()',
'access the lnum and col fields from get_prev() instead',
'0.13'
)
local prev = M.get_prev(opts) local prev = M.get_prev(opts)
if not prev then if not prev then
return false return false
@@ -1141,31 +1165,33 @@ function M.get_prev_pos(opts)
end end
--- Move to the previous diagnostic in the current buffer. --- Move to the previous diagnostic in the current buffer.
---@param opts? vim.diagnostic.GotoOpts ---@param opts? vim.diagnostic.JumpOpts
---@deprecated
function M.goto_prev(opts) function M.goto_prev(opts)
return diagnostic_move_pos(opts, M.get_prev_pos(opts)) vim.deprecate('vim.diagnostic.goto_prev()', 'vim.diagnostic.jump()', '0.13')
goto_diagnostic(M.get_prev(opts), opts)
end end
--- Get the next diagnostic closest to the cursor position. --- Get the next diagnostic closest to the cursor position.
--- ---
---@param opts? vim.diagnostic.GotoOpts ---@param opts? vim.diagnostic.JumpOpts
---@return vim.Diagnostic? : Next diagnostic ---@return vim.Diagnostic? : Next diagnostic
function M.get_next(opts) function M.get_next(opts)
opts = opts or {} return next_diagnostic(true, opts)
local win_id = opts.win_id or api.nvim_get_current_win()
local bufnr = api.nvim_win_get_buf(win_id)
local cursor_position = opts.cursor_position or api.nvim_win_get_cursor(win_id)
return next_diagnostic(cursor_position, true, bufnr, opts, opts.namespace)
end end
--- Return the position of the next diagnostic in the current buffer. --- Return the position of the next diagnostic in the current buffer.
--- ---
---@param opts? vim.diagnostic.GotoOpts ---@param opts? vim.diagnostic.JumpOpts
---@return table|false : Next diagnostic position as a `(row, col)` tuple or false if no next ---@return table|false : Next diagnostic position as a `(row, col)` tuple or false if no next
--- diagnostic. --- diagnostic.
---@deprecated
function M.get_next_pos(opts) function M.get_next_pos(opts)
vim.deprecate(
'vim.diagnostic.get_next_pos()',
'access the lnum and col fields from get_next() instead',
'0.13'
)
local next = M.get_next(opts) local next = M.get_next(opts)
if not next then if not next then
return false return false
@@ -1187,12 +1213,21 @@ end
--- @field severity? vim.diagnostic.SeverityFilter --- @field severity? vim.diagnostic.SeverityFilter
--- Configuration table with the following keys: --- Configuration table with the following keys:
--- @class vim.diagnostic.GotoOpts : vim.diagnostic.GetOpts --- @class vim.diagnostic.JumpOpts : vim.diagnostic.GetOpts
--- ---
--- Cursor position as a `(row, col)` tuple. --- The diagnostic to jump to. Mutually exclusive with {count}, {namespace},
--- See |nvim_win_get_cursor()|. --- and {severity}.
--- (default: current cursor position) --- @field diagnostic? vim.Diagnostic
--- @field cursor_position? {[1]:integer,[2]:integer} ---
--- The number of diagnostics to move by, starting from {pos}. A positive
--- integer moves forward by {count} diagnostics, while a negative integer moves
--- backward by {count} diagnostics. Mutually exclusive with {diagnostic}.
--- @field count? integer
---
--- Cursor position as a `(row, col)` tuple. See |nvim_win_get_cursor()|. Used
--- to find the nearest diagnostic when {count} is used. Only used when {count}
--- is non-nil. Default is the current cursor position.
--- @field pos? {[1]:integer,[2]:integer}
--- ---
--- Whether to loop around file or not. Similar to 'wrapscan'. --- Whether to loop around file or not. Similar to 'wrapscan'.
--- (default: `true`) --- (default: `true`)
@@ -1214,13 +1249,69 @@ end
--- ---
--- Window ID --- Window ID
--- (default: `0`) --- (default: `0`)
--- @field win_id? integer --- @field winid? integer
--- Move to a diagnostic.
---
--- @param opts vim.diagnostic.JumpOpts
--- @return vim.Diagnostic? # The diagnostic that was moved to.
function M.jump(opts)
-- One of "diagnostic" or "count" must be provided
assert(
opts.diagnostic or opts.count,
'One of "diagnostic" or "count" must be specified in the options to vim.diagnostic.jump()'
)
if opts.diagnostic then
goto_diagnostic(opts.diagnostic, opts)
return opts.diagnostic
end
local count = opts.count
if count == 0 then
return nil
end
-- Support deprecated cursor_position alias
if opts.cursor_position then
vim.deprecate('opts.cursor_position', 'opts.pos', '0.13')
opts.pos = opts.cursor_position
opts.cursor_position = nil
end
-- Copy the opts table so that we can modify it
local opts_ = vim.deepcopy(opts, true)
local diag = nil
while count ~= 0 do
local next = next_diagnostic(count > 0, opts_)
if not next then
break
end
-- Update cursor position
opts_.pos = { next.lnum + 1, next.col }
if count > 0 then
count = count - 1
else
count = count + 1
end
diag = next
end
goto_diagnostic(diag, opts)
return diag
end
--- Move to the next diagnostic. --- Move to the next diagnostic.
--- ---
---@param opts? vim.diagnostic.GotoOpts ---@param opts? vim.diagnostic.JumpOpts
---@deprecated
function M.goto_next(opts) function M.goto_next(opts)
diagnostic_move_pos(opts, M.get_next_pos(opts)) vim.deprecate('vim.diagnostic.goto_next()', 'vim.diagnostic.jump()', '0.13')
goto_diagnostic(M.get_next(opts), opts)
end end
M.handlers.signs = { M.handlers.signs = {
@@ -1688,7 +1779,7 @@ end
--- ---
---@param opts vim.diagnostic.Opts.Float? ---@param opts vim.diagnostic.Opts.Float?
---@return integer? float_bufnr ---@return integer? float_bufnr
---@return integer? win_id ---@return integer? winid
function M.open_float(opts, ...) function M.open_float(opts, ...)
-- Support old (bufnr, opts) signature -- Support old (bufnr, opts) signature
local bufnr --- @type integer? local bufnr --- @type integer?

View File

@@ -843,7 +843,7 @@ describe('vim.diagnostic', function()
end) end)
end) end)
describe('get_next_pos()', function() describe('get_next()', function()
it('can find the next pos with only one namespace', function() it('can find the next pos with only one namespace', function()
eq( eq(
{ 1, 1 }, { 1, 1 },
@@ -852,7 +852,8 @@ describe('vim.diagnostic', function()
make_error('Diagnostic #1', 1, 1, 1, 1), make_error('Diagnostic #1', 1, 1, 1, 1),
}) })
vim.api.nvim_win_set_buf(0, diagnostic_bufnr) vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
return vim.diagnostic.get_next_pos() local next = vim.diagnostic.get_next()
return { next.lnum, next.col }
]] ]]
) )
end) end)
@@ -867,7 +868,8 @@ describe('vim.diagnostic', function()
}) })
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, {3, 1}) vim.api.nvim_win_set_cursor(0, {3, 1})
return vim.diagnostic.get_next_pos { namespace = diagnostic_ns } local next = vim.diagnostic.get_next({ namespace = diagnostic_ns })
return { next.lnum, next.col }
]] ]]
) )
end) end)
@@ -881,21 +883,23 @@ describe('vim.diagnostic', function()
}) })
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, {3, 1}) vim.api.nvim_win_set_cursor(0, {3, 1})
return vim.diagnostic.get_next_pos { namespace = diagnostic_ns } local next = vim.diagnostic.get_next({ namespace = diagnostic_ns })
return { next.lnum, next.col }
]] ]]
) )
end) end)
it('will not cycle when wrap is off', function() it('will not cycle when wrap is off', function()
eq( eq(
false, vim.NIL,
exec_lua [[ exec_lua [[
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
make_error('Diagnostic #1', 1, 1, 1, 1), make_error('Diagnostic #1', 1, 1, 1, 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, {3, 1}) vim.api.nvim_win_set_cursor(0, {3, 1})
return vim.diagnostic.get_next_pos { namespace = diagnostic_ns, wrap = false } local next = vim.diagnostic.get_next({ namespace = diagnostic_ns, wrap = false })
return next
]] ]]
) )
end) end)
@@ -909,7 +913,8 @@ describe('vim.diagnostic', function()
}) })
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, {vim.api.nvim_buf_line_count(0), 1}) vim.api.nvim_win_set_cursor(0, {vim.api.nvim_buf_line_count(0), 1})
return vim.diagnostic.get_prev_pos { namespace = diagnostic_ns } local prev = vim.diagnostic.get_prev({ namespace = diagnostic_ns })
return { prev.lnum, prev.col }
]] ]]
) )
end) end)
@@ -924,8 +929,9 @@ describe('vim.diagnostic', function()
}) })
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.jump({ count = 1, float = false })
return vim.diagnostic.get_next_pos { namespace = diagnostic_ns } local next = vim.diagnostic.get_next({ namespace = diagnostic_ns })
return { next.lnum, next.col }
]] ]]
) )
end) end)
@@ -940,8 +946,9 @@ describe('vim.diagnostic', function()
}) })
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.jump({ count = 1, float = false })
return vim.diagnostic.get_next_pos { namespace = diagnostic_ns } local next = vim.diagnostic.get_next({ namespace = diagnostic_ns })
return { next.lnum, next.col }
]] ]]
) )
end) end)
@@ -1044,8 +1051,8 @@ describe('vim.diagnostic', function()
end) end)
end) end)
describe('get_prev_pos()', function() describe('get_prev()', function()
it('can find the prev pos with only one namespace', function() it('can find the previous diagnostic with only one namespace', function()
eq( eq(
{ 1, 1 }, { 1, 1 },
exec_lua [[ exec_lua [[
@@ -1054,12 +1061,13 @@ describe('vim.diagnostic', function()
}) })
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, {3, 1}) vim.api.nvim_win_set_cursor(0, {3, 1})
return vim.diagnostic.get_prev_pos() local prev = vim.diagnostic.get_prev()
return { prev.lnum, prev.col }
]] ]]
) )
end) end)
it('can find prev pos with two errors', function() it('can find the previous diagnostic with two errors', function()
eq( eq(
{ 1, 1 }, { 1, 1 },
exec_lua [[ exec_lua [[
@@ -1069,7 +1077,8 @@ describe('vim.diagnostic', function()
}) })
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, {3, 1}) vim.api.nvim_win_set_cursor(0, {3, 1})
return vim.diagnostic.get_prev_pos { namespace = diagnostic_ns } local prev = vim.diagnostic.get_prev({ namespace = diagnostic_ns })
return { prev.lnum, prev.col }
]] ]]
) )
end) end)
@@ -1083,21 +1092,23 @@ describe('vim.diagnostic', function()
}) })
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, {3, 1}) vim.api.nvim_win_set_cursor(0, {3, 1})
return vim.diagnostic.get_prev_pos { namespace = diagnostic_ns } local prev = vim.diagnostic.get_prev({ namespace = diagnostic_ns })
return { prev.lnum, prev.col }
]] ]]
) )
end) end)
it('respects wrap parameter', function() it('respects wrap parameter', function()
eq( eq(
false, vim.NIL,
exec_lua [[ exec_lua [[
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
make_error('Diagnostic #2', 4, 4, 4, 4), make_error('Diagnostic #2', 4, 4, 4, 4),
}) })
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, {3, 1}) vim.api.nvim_win_set_cursor(0, {3, 1})
return vim.diagnostic.get_prev_pos { namespace = diagnostic_ns, wrap = false} local prev = vim.diagnostic.get_prev({ namespace = diagnostic_ns, wrap = false})
return prev
]] ]]
) )
end) end)
@@ -1126,6 +1137,118 @@ describe('vim.diagnostic', function()
end) end)
end) end)
describe('jump()', function()
before_each(function()
exec_lua([[
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
make_error('Diagnostic #1', 0, 0, 0, 2),
make_error('Diagnostic #2', 1, 1, 1, 4),
make_warning('Diagnostic #3', 2, -1, 2, -1),
make_info('Diagnostic #4', 3, 0, 3, 3),
})
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
]])
end)
it('can move forward', function()
eq(
{ 2, 1 },
exec_lua([[
vim.api.nvim_win_set_cursor(0, { 1, 0 })
vim.diagnostic.jump({ count = 1 })
return vim.api.nvim_win_get_cursor(0)
]])
)
eq(
{ 4, 0 },
exec_lua([[
vim.api.nvim_win_set_cursor(0, { 1, 0 })
vim.diagnostic.jump({ count = 3 })
return vim.api.nvim_win_get_cursor(0)
]])
)
eq(
{ 4, 0 },
exec_lua([[
vim.api.nvim_win_set_cursor(0, { 1, 0 })
vim.diagnostic.jump({ count = math.huge, wrap = false })
return vim.api.nvim_win_get_cursor(0)
]])
)
end)
it('can move backward', function()
eq(
{ 3, 0 },
exec_lua([[
vim.api.nvim_win_set_cursor(0, { 4, 0 })
vim.diagnostic.jump({ count = -1 })
return vim.api.nvim_win_get_cursor(0)
]])
)
eq(
{ 1, 0 },
exec_lua([[
vim.api.nvim_win_set_cursor(0, { 4, 0 })
vim.diagnostic.jump({ count = -3 })
return vim.api.nvim_win_get_cursor(0)
]])
)
eq(
{ 1, 0 },
exec_lua([[
vim.api.nvim_win_set_cursor(0, { 4, 0 })
vim.diagnostic.jump({ count = -math.huge, wrap = false })
return vim.api.nvim_win_get_cursor(0)
]])
)
end)
it('can filter by severity', function()
eq(
{ 3, 0 },
exec_lua([[
vim.api.nvim_win_set_cursor(0, { 1, 0 })
vim.diagnostic.jump({ count = 1, severity = vim.diagnostic.severity.WARN })
return vim.api.nvim_win_get_cursor(0)
]])
)
eq(
{ 3, 0 },
exec_lua([[
vim.api.nvim_win_set_cursor(0, { 1, 0 })
vim.diagnostic.jump({ count = 9999, severity = vim.diagnostic.severity.WARN })
return vim.api.nvim_win_get_cursor(0)
]])
)
end)
it('can wrap', function()
eq(
{ 1, 0 },
exec_lua([[
vim.api.nvim_win_set_cursor(0, { 4, 0 })
vim.diagnostic.jump({ count = 1, wrap = true })
return vim.api.nvim_win_get_cursor(0)
]])
)
eq(
{ 4, 0 },
exec_lua([[
vim.api.nvim_win_set_cursor(0, { 1, 0 })
vim.diagnostic.jump({ count = -1, wrap = true })
return vim.api.nvim_win_get_cursor(0)
]])
)
end)
end)
describe('get()', function() describe('get()', function()
it('returns an empty table when no diagnostics are present', function() it('returns an empty table when no diagnostics are present', function()
eq({}, exec_lua [[return vim.diagnostic.get(diagnostic_bufnr, {namespace=diagnostic_ns})]]) eq({}, exec_lua [[return vim.diagnostic.get(diagnostic_bufnr, {namespace=diagnostic_ns})]])