diff options
-rw-r--r-- | runtime/doc/deprecated.txt | 17 | ||||
-rw-r--r-- | runtime/doc/diagnostic.txt | 91 | ||||
-rw-r--r-- | runtime/lua/vim/diagnostic.lua | 193 | ||||
-rw-r--r-- | test/functional/lua/diagnostic_spec.lua | 289 |
4 files changed, 401 insertions, 189 deletions
diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt index be220fc307..6c6585d76e 100644 --- a/runtime/doc/deprecated.txt +++ b/runtime/doc/deprecated.txt @@ -22,6 +22,20 @@ API LUA - 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* @@ -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_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 - *vim.lsp.buf.server_ready()* Use |LspAttach| instead, depending on your use-case. "Server ready" is not diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt index 36616b9a0d..be9e54d6cd 100644 --- a/runtime/doc/diagnostic.txt +++ b/runtime/doc/diagnostic.txt @@ -378,28 +378,37 @@ Lua module: vim.diagnostic *diagnostic-api* • {severity}? (`vim.diagnostic.SeverityFilter`) See |diagnostic-severity|. -*vim.diagnostic.GotoOpts* +*vim.diagnostic.JumpOpts* Extends: |vim.diagnostic.GetOpts| Configuration table with the following keys: Fields: ~ - • {cursor_position}? (`{[1]:integer,[2]:integer}`, default: current cursor position) - Cursor position as a `(row, col)` tuple. See - |nvim_win_get_cursor()|. - • {wrap}? (`boolean`, default: `true`) Whether to loop - around file or not. Similar to 'wrapscan'. - • {severity}? (`vim.diagnostic.SeverityFilter`) See - |diagnostic-severity|. - • {float}? (`boolean|vim.diagnostic.Opts.Float`, default: - `true`) If `true`, call - |vim.diagnostic.open_float()| after moving. If a - table, pass the table as the {opts} parameter to - |vim.diagnostic.open_float()|. Unless overridden, - the float will show diagnostics at the new cursor - position (as if "cursor" were passed to the - "scope" option). - • {win_id}? (`integer`, default: `0`) Window ID + • {diagnostic}? (`vim.Diagnostic`) The diagnostic to jump to. Mutually + exclusive with {count}, {namespace}, and {severity}. + See |vim.Diagnostic|. + • {count}? (`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}. + • {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 + |diagnostic-severity|. + • {float}? (`boolean|vim.diagnostic.Opts.Float`, default: `true`) + If `true`, call |vim.diagnostic.open_float()| after + moving. If a table, pass the table as the {opts} + parameter to |vim.diagnostic.open_float()|. Unless + overridden, the float will show diagnostics at the new + cursor position (as if "cursor" were passed to the + "scope" option). + • {winid}? (`integer`, default: `0`) Window ID *vim.diagnostic.NS* @@ -678,52 +687,20 @@ get_next({opts}) *vim.diagnostic.get_next()* Get the next diagnostic closest to the cursor position. Parameters: ~ - • {opts} (`vim.diagnostic.GotoOpts?`) See |vim.diagnostic.GotoOpts|. + • {opts} (`vim.diagnostic.JumpOpts?`) See |vim.diagnostic.JumpOpts|. Return: ~ (`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 the previous diagnostic closest to the cursor position. Parameters: ~ - • {opts} (`vim.diagnostic.GotoOpts?`) See |vim.diagnostic.GotoOpts|. + • {opts} (`vim.diagnostic.JumpOpts?`) See |vim.diagnostic.JumpOpts|. Return: ~ (`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 currently displayed diagnostics. @@ -753,6 +730,16 @@ is_enabled({filter}) *vim.diagnostic.is_enabled()* Return: ~ (`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()* match({str}, {pat}, {groups}, {severity_map}, {defaults}) Parse a diagnostic from a string. @@ -792,7 +779,7 @@ open_float({opts}) *vim.diagnostic.open_float()* Return (multiple): ~ (`integer?`) float_bufnr - (`integer?`) win_id + (`integer?`) winid reset({namespace}, {bufnr}) *vim.diagnostic.reset()* Remove all diagnostics from the given namespace. diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 348204abb7..8e68e9608a 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -835,21 +835,36 @@ local function filter_highest(diagnostics) end end ---- @param position {[1]: integer, [2]: integer} --- @param search_forward boolean ---- @param bufnr integer ---- @param opts vim.diagnostic.GotoOpts ---- @param namespace integer[]|integer +--- @param opts vim.diagnostic.JumpOpts? --- @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 - bufnr = get_bufnr(bufnr) - local wrap = if_nil(opts.wrap, true) - local get_opts = vim.deepcopy(opts) - get_opts.namespace = get_opts.namespace or namespace + local wrap = if_nil(opts.wrap, true) - local diagnostics = get_diagnostics(bufnr, get_opts, true) + local diagnostics = get_diagnostics(bufnr, opts, true) if opts._highest then filter_highest(diagnostics) @@ -902,32 +917,41 @@ local function next_diagnostic(position, search_forward, bufnr, opts, namespace) end end ---- @param opts vim.diagnostic.GotoOpts? ---- @param pos {[1]:integer,[2]:integer}|false -local function diagnostic_move_pos(opts, pos) - opts = opts or {} - - local float = if_nil(opts.float, true) - local win_id = opts.win_id or api.nvim_get_current_win() - - if not pos then +--- Move the cursor to the given diagnostic. +--- +--- @param diagnostic vim.Diagnostic? +--- @param opts vim.diagnostic.JumpOpts? +local function goto_diagnostic(diagnostic, opts) + if not diagnostic then api.nvim_echo({ { 'No more valid diagnostics to move to', 'WarningMsg' } }, true, {}) return 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 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 vim.cmd('normal! zv') end) + local float = if_nil(opts.float, true) if float then local float_opts = type(float) == 'table' and float or {} vim.schedule(function() 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', focus = false, })) @@ -1114,24 +1138,24 @@ end --- Get the previous diagnostic closest to the cursor position. --- ----@param opts? vim.diagnostic.GotoOpts +---@param opts? vim.diagnostic.JumpOpts ---@return vim.Diagnostic? : Previous diagnostic function M.get_prev(opts) - opts = opts or {} - - 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) + return next_diagnostic(false, opts) end --- 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 --- or `false` if there is no prior diagnostic. +---@deprecated 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) if not prev then return false @@ -1141,31 +1165,33 @@ function M.get_prev_pos(opts) end --- 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) - 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 --- Get the next diagnostic closest to the cursor position. --- ----@param opts? vim.diagnostic.GotoOpts +---@param opts? vim.diagnostic.JumpOpts ---@return vim.Diagnostic? : Next diagnostic function M.get_next(opts) - opts = opts or {} - - 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) + return next_diagnostic(true, opts) end --- 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 --- diagnostic. +---@deprecated 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) if not next then return false @@ -1187,12 +1213,21 @@ end --- @field severity? vim.diagnostic.SeverityFilter --- Configuration table with the following keys: ---- @class vim.diagnostic.GotoOpts : vim.diagnostic.GetOpts +--- @class vim.diagnostic.JumpOpts : vim.diagnostic.GetOpts +--- +--- The diagnostic to jump to. Mutually exclusive with {count}, {namespace}, +--- and {severity}. +--- @field diagnostic? vim.Diagnostic +--- +--- 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()|. ---- (default: current cursor position) ---- @field cursor_position? {[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. +--- @field pos? {[1]:integer,[2]:integer} --- --- Whether to loop around file or not. Similar to 'wrapscan'. --- (default: `true`) @@ -1214,13 +1249,69 @@ end --- --- Window ID --- (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. --- ----@param opts? vim.diagnostic.GotoOpts +---@param opts? vim.diagnostic.JumpOpts +---@deprecated 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 M.handlers.signs = { @@ -1688,7 +1779,7 @@ end --- ---@param opts vim.diagnostic.Opts.Float? ---@return integer? float_bufnr ----@return integer? win_id +---@return integer? winid function M.open_float(opts, ...) -- Support old (bufnr, opts) signature local bufnr --- @type integer? diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index 05082bc132..76246fc2d1 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -843,17 +843,18 @@ describe('vim.diagnostic', function() end) end) - describe('get_next_pos()', function() + describe('get_next()', function() it('can find the next pos with only one namespace', function() eq( { 1, 1 }, exec_lua [[ - vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { - make_error('Diagnostic #1', 1, 1, 1, 1), - }) - vim.api.nvim_win_set_buf(0, diagnostic_bufnr) - return vim.diagnostic.get_next_pos() - ]] + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error('Diagnostic #1', 1, 1, 1, 1), + }) + vim.api.nvim_win_set_buf(0, diagnostic_bufnr) + local next = vim.diagnostic.get_next() + return { next.lnum, next.col } + ]] ) end) @@ -861,14 +862,15 @@ describe('vim.diagnostic', function() eq( { 4, 4 }, exec_lua [[ - vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { - make_error('Diagnostic #1', 1, 1, 1, 1), - make_error('Diagnostic #2', 4, 4, 4, 4), - }) - vim.api.nvim_win_set_buf(0, diagnostic_bufnr) - vim.api.nvim_win_set_cursor(0, {3, 1}) - return vim.diagnostic.get_next_pos { namespace = diagnostic_ns } - ]] + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error('Diagnostic #1', 1, 1, 1, 1), + make_error('Diagnostic #2', 4, 4, 4, 4), + }) + vim.api.nvim_win_set_buf(0, diagnostic_bufnr) + vim.api.nvim_win_set_cursor(0, {3, 1}) + local next = vim.diagnostic.get_next({ namespace = diagnostic_ns }) + return { next.lnum, next.col } + ]] ) end) @@ -876,27 +878,29 @@ describe('vim.diagnostic', function() eq( { 1, 1 }, exec_lua [[ - vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { - make_error('Diagnostic #1', 1, 1, 1, 1), - }) - vim.api.nvim_win_set_buf(0, diagnostic_bufnr) - vim.api.nvim_win_set_cursor(0, {3, 1}) - return vim.diagnostic.get_next_pos { namespace = diagnostic_ns } - ]] + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error('Diagnostic #1', 1, 1, 1, 1), + }) + vim.api.nvim_win_set_buf(0, diagnostic_bufnr) + vim.api.nvim_win_set_cursor(0, {3, 1}) + local next = vim.diagnostic.get_next({ namespace = diagnostic_ns }) + return { next.lnum, next.col } + ]] ) end) it('will not cycle when wrap is off', function() eq( - false, + vim.NIL, exec_lua [[ - vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { - make_error('Diagnostic #1', 1, 1, 1, 1), - }) - vim.api.nvim_win_set_buf(0, diagnostic_bufnr) - vim.api.nvim_win_set_cursor(0, {3, 1}) - return vim.diagnostic.get_next_pos { namespace = diagnostic_ns, wrap = false } - ]] + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error('Diagnostic #1', 1, 1, 1, 1), + }) + vim.api.nvim_win_set_buf(0, diagnostic_bufnr) + vim.api.nvim_win_set_cursor(0, {3, 1}) + local next = vim.diagnostic.get_next({ namespace = diagnostic_ns, wrap = false }) + return next + ]] ) end) @@ -904,13 +908,14 @@ describe('vim.diagnostic', function() eq( { 4, 4 }, exec_lua [[ - vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { - make_error('Diagnostic #2', 4, 4, 4, 4), - }) - vim.api.nvim_win_set_buf(0, diagnostic_bufnr) - vim.api.nvim_win_set_cursor(0, {vim.api.nvim_buf_line_count(0), 1}) - return vim.diagnostic.get_prev_pos { namespace = diagnostic_ns } - ]] + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error('Diagnostic #2', 4, 4, 4, 4), + }) + vim.api.nvim_win_set_buf(0, diagnostic_bufnr) + vim.api.nvim_win_set_cursor(0, {vim.api.nvim_buf_line_count(0), 1}) + local prev = vim.diagnostic.get_prev({ namespace = diagnostic_ns }) + return { prev.lnum, prev.col } + ]] ) end) @@ -918,15 +923,16 @@ describe('vim.diagnostic', function() eq( { 4, 0 }, exec_lua [[ - vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { - make_error('Diagnostic #1', 3, 9001, 3, 9001), - make_error('Diagnostic #2', 4, 0, 4, 0), - }) - vim.api.nvim_win_set_buf(0, diagnostic_bufnr) - vim.api.nvim_win_set_cursor(0, {1, 1}) - vim.diagnostic.goto_next { float = false } - return vim.diagnostic.get_next_pos { namespace = diagnostic_ns } - ]] + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error('Diagnostic #1', 3, 9001, 3, 9001), + make_error('Diagnostic #2', 4, 0, 4, 0), + }) + vim.api.nvim_win_set_buf(0, diagnostic_bufnr) + vim.api.nvim_win_set_cursor(0, {1, 1}) + vim.diagnostic.jump({ count = 1, float = false }) + local next = vim.diagnostic.get_next({ namespace = diagnostic_ns }) + return { next.lnum, next.col } + ]] ) end) @@ -935,13 +941,14 @@ describe('vim.diagnostic', function() { 4, 0 }, exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { - make_error('Diagnostic #1', 3, 9001, 3, 9001), - make_error('Diagnostic #2', 4, -1, 4, -1), + make_error('Diagnostic #1', 3, 9001, 3, 9001), + make_error('Diagnostic #2', 4, -1, 4, -1), }) vim.api.nvim_win_set_buf(0, diagnostic_bufnr) vim.api.nvim_win_set_cursor(0, {1, 1}) - vim.diagnostic.goto_next { float = false } - return vim.diagnostic.get_next_pos { namespace = diagnostic_ns } + vim.diagnostic.jump({ count = 1, float = false }) + local next = vim.diagnostic.get_next({ namespace = diagnostic_ns }) + return { next.lnum, next.col } ]] ) end) @@ -1044,33 +1051,35 @@ describe('vim.diagnostic', function() end) end) - describe('get_prev_pos()', function() - it('can find the prev pos with only one namespace', function() + describe('get_prev()', function() + it('can find the previous diagnostic with only one namespace', function() eq( { 1, 1 }, exec_lua [[ - vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { - make_error('Diagnostic #1', 1, 1, 1, 1), - }) - vim.api.nvim_win_set_buf(0, diagnostic_bufnr) - vim.api.nvim_win_set_cursor(0, {3, 1}) - return vim.diagnostic.get_prev_pos() - ]] + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error('Diagnostic #1', 1, 1, 1, 1), + }) + vim.api.nvim_win_set_buf(0, diagnostic_bufnr) + vim.api.nvim_win_set_cursor(0, {3, 1}) + local prev = vim.diagnostic.get_prev() + return { prev.lnum, prev.col } + ]] ) end) - it('can find prev pos with two errors', function() + it('can find the previous diagnostic with two errors', function() eq( { 1, 1 }, exec_lua [[ - vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { - make_error('Diagnostic #1', 1, 1, 1, 1), - make_error('Diagnostic #2', 4, 4, 4, 4), - }) - vim.api.nvim_win_set_buf(0, diagnostic_bufnr) - vim.api.nvim_win_set_cursor(0, {3, 1}) - return vim.diagnostic.get_prev_pos { namespace = diagnostic_ns } - ]] + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error('Diagnostic #1', 1, 1, 1, 1), + make_error('Diagnostic #2', 4, 4, 4, 4), + }) + vim.api.nvim_win_set_buf(0, diagnostic_bufnr) + vim.api.nvim_win_set_cursor(0, {3, 1}) + local prev = vim.diagnostic.get_prev({ namespace = diagnostic_ns }) + return { prev.lnum, prev.col } + ]] ) end) @@ -1078,27 +1087,29 @@ describe('vim.diagnostic', function() eq( { 4, 4 }, exec_lua [[ - vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { - make_error('Diagnostic #2', 4, 4, 4, 4), - }) - vim.api.nvim_win_set_buf(0, diagnostic_bufnr) - vim.api.nvim_win_set_cursor(0, {3, 1}) - return vim.diagnostic.get_prev_pos { namespace = diagnostic_ns } - ]] + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error('Diagnostic #2', 4, 4, 4, 4), + }) + vim.api.nvim_win_set_buf(0, diagnostic_bufnr) + vim.api.nvim_win_set_cursor(0, {3, 1}) + local prev = vim.diagnostic.get_prev({ namespace = diagnostic_ns }) + return { prev.lnum, prev.col } + ]] ) end) it('respects wrap parameter', function() eq( - false, + vim.NIL, exec_lua [[ - vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { - make_error('Diagnostic #2', 4, 4, 4, 4), - }) - vim.api.nvim_win_set_buf(0, diagnostic_bufnr) - vim.api.nvim_win_set_cursor(0, {3, 1}) - return vim.diagnostic.get_prev_pos { namespace = diagnostic_ns, wrap = false} - ]] + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error('Diagnostic #2', 4, 4, 4, 4), + }) + vim.api.nvim_win_set_buf(0, diagnostic_bufnr) + vim.api.nvim_win_set_cursor(0, {3, 1}) + local prev = vim.diagnostic.get_prev({ namespace = diagnostic_ns, wrap = false}) + return prev + ]] ) end) @@ -1126,6 +1137,118 @@ describe('vim.diagnostic', function() 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() it('returns an empty table when no diagnostics are present', function() eq({}, exec_lua [[return vim.diagnostic.get(diagnostic_bufnr, {namespace=diagnostic_ns})]]) |