aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Anders <8965202+gpanders@users.noreply.github.com>2021-10-19 11:45:51 -0600
committerGitHub <noreply@github.com>2021-10-19 11:45:51 -0600
commit064411ea7ff825aed3d4e01207914ed61d7ee79d (patch)
treef654858daef98f0dc6fb485414d25d6edb5879b9
parentaa4f0879e35c43b186cf51c50f28847dd2df256c (diff)
downloadrneovim-064411ea7ff825aed3d4e01207914ed61d7ee79d.tar.gz
rneovim-064411ea7ff825aed3d4e01207914ed61d7ee79d.tar.bz2
rneovim-064411ea7ff825aed3d4e01207914ed61d7ee79d.zip
refactor(diagnostic)!: replace 'show_*' functions with 'open_float' (#16057)
'show_line_diagnostics()' and 'show_position_diagnostics()' are almost identical; they differ only in the fact that the latter also accepts a column to form a full position, rather than just a line. This is not enough to justify two separate interfaces for this common functionality. Renaming this to simply 'show_diagnostics()' is one step forward, but that is also not a good name as the '_diagnostics()' suffix is redundant. However, we cannot name it simply 'show()' since that function already exists with entirely different semantics. Instead, combine these two into a single 'open_float()' function that handles all of the cases of showing diagnostics in a floating window. Also add a "float" key to 'vim.diagnostic.config()' to provide global values of configuration options that can be overridden ephemerally. This makes the float API consistent with the rest of the diagnostic API. BREAKING CHANGE
-rw-r--r--runtime/doc/diagnostic.txt113
-rw-r--r--runtime/lua/vim/diagnostic.lua281
-rw-r--r--runtime/lua/vim/lsp/diagnostic.lua21
-rw-r--r--test/functional/lua/diagnostic_spec.lua145
4 files changed, 331 insertions, 229 deletions
diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt
index 17d317522b..4d1e5ac997 100644
--- a/runtime/doc/diagnostic.txt
+++ b/runtime/doc/diagnostic.txt
@@ -262,12 +262,12 @@ config({opts}, {namespace}) *vim.diagnostic.config()*
For example, if a user enables virtual text globally with >
- vim.diagnostic.config({virt_text = true})
+ vim.diagnostic.config({virtual_text = true})
<
and a diagnostic producer sets diagnostics with >
- vim.diagnostic.set(ns, 0, diagnostics, {virt_text = false})
+ vim.diagnostic.set(ns, 0, diagnostics, {virtual_text = false})
<
then virtual text will not be enabled for those diagnostics.
@@ -302,7 +302,7 @@ config({opts}, {namespace}) *vim.diagnostic.config()*
• format: (function) A function that takes
a diagnostic as input and returns a
string. The return value is the text used
- to display the diagnostic. Example:>
+ to display the diagnostic. Example: >
function(diagnostic)
if diagnostic.severity == vim.diagnostic.severity.ERROR then
@@ -324,6 +324,18 @@ config({opts}, {namespace}) *vim.diagnostic.config()*
Otherwise, all signs use the same
priority.
+ • float: Options for floating windows:
+ • severity: See |diagnostic-severity|.
+ • show_header: (boolean, default true) Show
+ "Diagnostics:" header
+ • source: (string) Include the diagnostic
+ source in the message. One of "always" or
+ "if_many".
+ • format: (function) A function that takes
+ a diagnostic as input and returns a
+ string. The return value is the text used
+ to display the diagnostic.
+
• update_in_insert: (default false) Update
diagnostics in Insert mode (if false,
diagnostics are updated on InsertLeave)
@@ -442,12 +454,10 @@ goto_next({opts}) *vim.diagnostic.goto_next()*
• wrap: (boolean, default true) Whether to loop
around file or not. Similar to 'wrapscan'.
• severity: See |diagnostic-severity|.
- • enable_popup: (boolean, default true) Call
- |vim.diagnostic.show_line_diagnostics()| on
- jump.
- • popup_opts: (table) Table to pass as {opts}
- parameter to
- |vim.diagnostic.show_line_diagnostics()|
+ • float: (boolean or table, 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()|.
• win_id: (number, default 0) Window ID
goto_prev({opts}) *vim.diagnostic.goto_prev()*
@@ -508,6 +518,46 @@ match({str}, {pat}, {groups}, {severity_map}, {defaults})
diagnostic |diagnostic-structure| or `nil` if {pat} fails
to match {str}.
+open_float({bufnr}, {opts}) *vim.diagnostic.open_float()*
+ Show diagnostics in a floating window.
+
+ Parameters: ~
+ {bufnr} number|nil Buffer number. Defaults to the current
+ buffer.
+ {opts} table|nil Configuration table with the same keys
+ as |vim.lsp.util.open_floating_preview()| in
+ addition to the following:
+ • namespace: (number) Limit diagnostics to the
+ given namespace
+ • scope: (string, default "buffer") Show
+ diagnostics from the whole buffer ("buffer"),
+ the current cursor line ("line"), or the
+ current cursor position ("cursor").
+ • pos: (number or table) If {scope} is "line" or
+ "cursor", use this position rather than the
+ cursor position. If a number, interpreted as a
+ line number; otherwise, a (row, col) tuple.
+ • severity_sort: (default false) Sort diagnostics
+ by severity. Overrides the setting from
+ |vim.diagnostic.config()|.
+ • severity: See |diagnostic-severity|. Overrides
+ the setting from |vim.diagnostic.config()|.
+ • show_header: (boolean, default true) Show
+ "Diagnostics:" header. Overrides the setting
+ from |vim.diagnostic.config()|.
+ • source: (string) Include the diagnostic source
+ in the message. One of "always" or "if_many".
+ Overrides the setting from
+ |vim.diagnostic.config()|.
+ • format: (function) A function that takes a
+ diagnostic as input and returns a string. The
+ return value is the text used to display the
+ diagnostic. Overrides the setting from
+ |vim.diagnostic.config()|.
+
+ Return: ~
+ tuple ({float_bufnr}, {win_id})
+
reset({namespace}, {bufnr}) *vim.diagnostic.reset()*
Remove all diagnostics from the given namespace.
@@ -581,51 +631,6 @@ show({namespace}, {bufnr}, {diagnostics}, {opts})
{opts} table|nil Display options. See
|vim.diagnostic.config()|.
- *vim.diagnostic.show_line_diagnostics()*
-show_line_diagnostics({opts}, {bufnr}, {lnum})
- Open a floating window with the diagnostics from the given
- line.
-
- Parameters: ~
- {opts} table Configuration table. See
- |vim.diagnostic.show_position_diagnostics()|.
- {bufnr} number|nil Buffer number. Defaults to the current
- buffer.
- {lnum} number|nil Line number. Defaults to line number
- of cursor.
-
- Return: ~
- tuple ({popup_bufnr}, {win_id})
-
- *vim.diagnostic.show_position_diagnostics()*
-show_position_diagnostics({opts}, {bufnr}, {position})
- Open a floating window with the diagnostics at the given
- position.
-
- Parameters: ~
- {opts} table|nil Configuration table with the same
- keys as |vim.lsp.util.open_floating_preview()|
- in addition to the following:
- • namespace: (number) Limit diagnostics to the
- given namespace
- • severity: See |diagnostic-severity|.
- • show_header: (boolean, default true) Show
- "Diagnostics:" header
- • source: (string) Include the diagnostic
- source in the message. One of "always" or
- "if_many".
- • format: (function) A function that takes a
- diagnostic as input and returns a string.
- The return value is the text used to display
- the diagnostic.
- {bufnr} number|nil Buffer number. Defaults to the
- current buffer.
- {position} table|nil The (0,0)-indexed position. Defaults
- to the current cursor position.
-
- Return: ~
- tuple ({popup_bufnr}, {win_id})
-
toqflist({diagnostics}) *vim.diagnostic.toqflist()*
Convert a list of diagnostics to a list of quickfix items that
can be passed to |setqflist()| or |setloclist()|.
diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua
index 326932d982..f5ca034abc 100644
--- a/runtime/lua/vim/diagnostic.lua
+++ b/runtime/lua/vim/diagnostic.lua
@@ -19,6 +19,7 @@ local global_diagnostic_options = {
signs = true,
underline = true,
virtual_text = true,
+ float = true,
update_in_insert = false,
severity_sort = false,
}
@@ -119,8 +120,8 @@ end
---@private
local function enabled_value(option, namespace)
- local ns = get_namespace(namespace)
- if type(ns.opts[option]) == "table" then
+ local ns = namespace and get_namespace(namespace) or {}
+ if ns.opts and type(ns.opts[option]) == "table" then
return ns.opts[option]
end
@@ -153,8 +154,9 @@ end
---@private
local function get_resolved_options(opts, namespace, bufnr)
- local ns = get_namespace(namespace)
- local resolved = vim.tbl_extend('keep', opts or {}, ns.opts, global_diagnostic_options)
+ local ns = namespace and get_namespace(namespace) or {}
+ -- Do not use tbl_deep_extend so that an empty table can be used to reset to default values
+ local resolved = vim.tbl_extend('keep', opts or {}, ns.opts or {}, global_diagnostic_options)
for k in pairs(global_diagnostic_options) do
if resolved[k] ~= nil then
resolved[k] = resolve_optional_value(k, resolved[k], namespace, bufnr)
@@ -354,19 +356,15 @@ local function schedule_display(namespace, bufnr, args)
local key = make_augroup_key(namespace, bufnr)
if not registered_autocmds[key] then
- vim.cmd(string.format("augroup %s", key))
- vim.cmd(" au!")
- vim.cmd(
- string.format(
- [[autocmd %s <buffer=%s> lua vim.diagnostic._execute_scheduled_display(%s, %s)]],
- table.concat(insert_leave_auto_cmds, ","),
- bufnr,
- namespace,
- bufnr
- )
- )
- vim.cmd("augroup END")
-
+ vim.cmd(string.format([[augroup %s
+ au!
+ autocmd %s <buffer=%s> lua vim.diagnostic._execute_scheduled_display(%s, %s)
+ augroup END]],
+ key,
+ table.concat(insert_leave_auto_cmds, ","),
+ bufnr,
+ namespace,
+ bufnr))
registered_autocmds[key] = true
end
end
@@ -376,77 +374,14 @@ local function clear_scheduled_display(namespace, bufnr)
local key = make_augroup_key(namespace, bufnr)
if registered_autocmds[key] then
- vim.cmd(string.format("augroup %s", key))
- vim.cmd(" au!")
- vim.cmd("augroup END")
-
+ vim.cmd(string.format([[augroup %s
+ au!
+ augroup END]], key))
registered_autocmds[key] = nil
end
end
---@private
---- Open a floating window with the provided diagnostics
----@param opts table Configuration table
---- - show_header (boolean, default true): Show "Diagnostics:" header
---- - all opts for |vim.util.open_floating_preview()| can be used here
----@param diagnostics table: The diagnostics to display
----@return table {popup_bufnr, win_id}
-local function show_diagnostics(opts, diagnostics)
- if not diagnostics or vim.tbl_isempty(diagnostics) then
- return
- end
- local lines = {}
- local highlights = {}
- local show_header = vim.F.if_nil(opts.show_header, true)
- if show_header then
- table.insert(lines, "Diagnostics:")
- table.insert(highlights, {0, "Bold"})
- end
-
- if opts.format then
- diagnostics = reformat_diagnostics(opts.format, diagnostics)
- end
-
- if opts.source then
- diagnostics = prefix_source(opts.source, diagnostics)
- end
-
- -- Use global setting for severity_sort since 'show_diagnostics' is namespace
- -- independent
- local severity_sort = global_diagnostic_options.severity_sort
- if severity_sort then
- if type(severity_sort) == "table" and severity_sort.reverse then
- table.sort(diagnostics, function(a, b) return a.severity > b.severity end)
- else
- table.sort(diagnostics, function(a, b) return a.severity < b.severity end)
- end
- end
-
- for i, diagnostic in ipairs(diagnostics) do
- local prefix = string.format("%d. ", i)
- local hiname = floating_highlight_map[diagnostic.severity]
- assert(hiname, 'unknown severity: ' .. tostring(diagnostic.severity))
-
- local message_lines = vim.split(diagnostic.message, '\n', true)
- table.insert(lines, prefix..message_lines[1])
- table.insert(highlights, {#prefix, hiname})
- for j = 2, #message_lines do
- table.insert(lines, string.rep(' ', #prefix) .. message_lines[j])
- table.insert(highlights, {0, hiname})
- end
- end
-
- local popup_bufnr, winnr = require('vim.lsp.util').open_floating_preview(lines, 'plaintext', opts)
- for i, hi in ipairs(highlights) do
- local prefixlen, hiname = unpack(hi)
- -- Start highlight after the prefix
- vim.api.nvim_buf_add_highlight(popup_bufnr, -1, hiname, i-1, prefixlen, -1)
- end
-
- return popup_bufnr, winnr
-end
-
----@private
local function set_list(loclist, opts)
opts = opts or {}
local open = vim.F.if_nil(opts.open, true)
@@ -469,6 +404,7 @@ local function set_list(loclist, opts)
end
---@private
+--- To (slightly) improve performance, modifies diagnostics in place.
local function clamp_line_numbers(bufnr, diagnostics)
local buf_line_count = vim.api.nvim_buf_line_count(bufnr)
if buf_line_count == 0 then
@@ -526,7 +462,7 @@ end
local function diagnostic_move_pos(opts, pos)
opts = opts or {}
- local enable_popup = vim.F.if_nil(opts.enable_popup, true)
+ local float = vim.F.if_nil(opts.float, true)
local win_id = opts.win_id or vim.api.nvim_get_current_win()
if not pos then
@@ -539,10 +475,13 @@ local function diagnostic_move_pos(opts, pos)
vim.api.nvim_win_set_cursor(win_id, {pos[1] + 1, pos[2]})
- if enable_popup then
- -- This is a bit weird... I'm surprised that we need to wait til the next tick to do this.
+ if float then
+ local float_opts = type(float) == "table" and float or {}
vim.schedule(function()
- M.show_position_diagnostics(opts.popup_opts, vim.api.nvim_win_get_buf(win_id))
+ M.open_float(
+ vim.api.nvim_win_get_buf(win_id),
+ vim.tbl_extend("keep", float_opts, {scope="cursor"})
+ )
end)
end
end
@@ -561,12 +500,12 @@ end
---
--- For example, if a user enables virtual text globally with
--- <pre>
---- vim.diagnostic.config({virt_text = true})
+--- vim.diagnostic.config({virtual_text = true})
--- </pre>
---
--- and a diagnostic producer sets diagnostics with
--- <pre>
---- vim.diagnostic.set(ns, 0, diagnostics, {virt_text = false})
+--- vim.diagnostic.set(ns, 0, diagnostics, {virtual_text = false})
--- </pre>
---
--- then virtual text will not be enabled for those diagnostics.
@@ -603,6 +542,13 @@ end
--- * priority: (number, default 10) Base priority to use for signs. When
--- {severity_sort} is used, the priority of a sign is adjusted based on
--- its severity. Otherwise, all signs use the same priority.
+--- - float: Options for floating windows:
+--- * severity: See |diagnostic-severity|.
+--- * show_header: (boolean, default true) Show "Diagnostics:" header
+--- * source: (string) Include the diagnostic source in
+--- the message. One of "always" or "if_many".
+--- * format: (function) A function that takes a diagnostic as input and returns a
+--- string. The return value is the text used to display the diagnostic.
--- - update_in_insert: (default false) Update diagnostics in Insert mode (if false,
--- diagnostics are updated on InsertLeave)
--- - severity_sort: (default false) Sort diagnostics by severity. This affects the order in
@@ -825,10 +771,9 @@ end
--- |nvim_win_get_cursor()|. Defaults to the current cursor position.
--- - wrap: (boolean, default true) Whether to loop around file or not. Similar to 'wrapscan'.
--- - severity: See |diagnostic-severity|.
---- - enable_popup: (boolean, default true) Call |vim.diagnostic.show_line_diagnostics()|
---- on jump.
---- - popup_opts: (table) Table to pass as {opts} parameter to
---- |vim.diagnostic.show_line_diagnostics()|
+--- - float: (boolean or table, 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()|.
--- - win_id: (number, default 0) Window ID
function M.goto_next(opts)
return diagnostic_move_pos(
@@ -1144,68 +1089,128 @@ function M.show(namespace, bufnr, diagnostics, opts)
save_extmarks(namespace, bufnr)
end
---- Open a floating window with the diagnostics at the given position.
+--- Show diagnostics in a floating window.
---
+---@param bufnr number|nil Buffer number. Defaults to the current buffer.
---@param opts table|nil Configuration table with the same keys as
--- |vim.lsp.util.open_floating_preview()| in addition to the following:
--- - namespace: (number) Limit diagnostics to the given namespace
---- - severity: See |diagnostic-severity|.
---- - show_header: (boolean, default true) Show "Diagnostics:" header
---- - source: (string) Include the diagnostic source in
---- the message. One of "always" or "if_many".
+--- - scope: (string, default "buffer") Show diagnostics from the whole buffer ("buffer"),
+--- the current cursor line ("line"), or the current cursor position ("cursor").
+--- - pos: (number or table) If {scope} is "line" or "cursor", use this position rather
+--- than the cursor position. If a number, interpreted as a line number;
+--- otherwise, a (row, col) tuple.
+--- - severity_sort: (default false) Sort diagnostics by severity. Overrides the setting
+--- from |vim.diagnostic.config()|.
+--- - severity: See |diagnostic-severity|. Overrides the setting from
+--- |vim.diagnostic.config()|.
+--- - show_header: (boolean, default true) Show "Diagnostics:" header. Overrides the
+--- setting from |vim.diagnostic.config()|.
+--- - source: (string) Include the diagnostic source in the message. One of "always" or
+--- "if_many". Overrides the setting from |vim.diagnostic.config()|.
--- - format: (function) A function that takes a diagnostic as input and returns a
--- string. The return value is the text used to display the diagnostic.
----@param bufnr number|nil Buffer number. Defaults to the current buffer.
----@param position table|nil The (0,0)-indexed position. Defaults to the current cursor position.
----@return tuple ({popup_bufnr}, {win_id})
-function M.show_position_diagnostics(opts, bufnr, position)
+--- Overrides the setting from |vim.diagnostic.config()|.
+---@return tuple ({float_bufnr}, {win_id})
+function M.open_float(bufnr, opts)
vim.validate {
- opts = { opts, 't', true },
bufnr = { bufnr, 'n', true },
- position = { position, 't', true },
+ opts = { opts, 't', true },
}
opts = opts or {}
-
- opts.focus_id = "position_diagnostics"
bufnr = get_bufnr(bufnr)
- if not position then
- local curr_position = vim.api.nvim_win_get_cursor(0)
- curr_position[1] = curr_position[1] - 1
- position = curr_position
- end
- local match_position_predicate = function(diag)
- return position[1] == diag.lnum and
- position[2] >= diag.col and
- (position[2] <= diag.end_col or position[1] < diag.end_lnum)
+ local scope = opts.scope or "buffer"
+ local lnum, col
+ if scope == "line" or scope == "cursor" then
+ if not opts.pos then
+ local pos = vim.api.nvim_win_get_cursor(0)
+ lnum = pos[1] - 1
+ col = pos[2]
+ elseif type(opts.pos) == "number" then
+ lnum = opts.pos
+ elseif type(opts.pos) == "table" then
+ lnum, col = unpack(opts.pos)
+ else
+ error("Invalid value for option 'pos'")
+ end
+ elseif scope ~= "buffer" then
+ error("Invalid value for option 'scope'")
end
+
local diagnostics = M.get(bufnr, opts)
clamp_line_numbers(bufnr, diagnostics)
- local position_diagnostics = vim.tbl_filter(match_position_predicate, diagnostics)
- return show_diagnostics(opts, position_diagnostics)
-end
---- Open a floating window with the diagnostics from the given line.
----
----@param opts table Configuration table. See |vim.diagnostic.show_position_diagnostics()|.
----@param bufnr number|nil Buffer number. Defaults to the current buffer.
----@param lnum number|nil Line number. Defaults to line number of cursor.
----@return tuple ({popup_bufnr}, {win_id})
-function M.show_line_diagnostics(opts, bufnr, lnum)
- vim.validate {
- opts = { opts, 't', true },
- bufnr = { bufnr, 'n', true },
- lnum = { lnum, 'n', true },
- }
+ if scope == "line" then
+ diagnostics = vim.tbl_filter(function(d)
+ return d.lnum == lnum
+ end, diagnostics)
+ elseif scope == "cursor" then
+ diagnostics = vim.tbl_filter(function(d)
+ return d.lnum == lnum and d.col <= col and (d.end_col >= col or d.end_lnum > lnum)
+ end, diagnostics)
+ end
- opts = opts or {}
- opts.focus_id = "line_diagnostics"
- bufnr = get_bufnr(bufnr)
- local diagnostics = M.get(bufnr, opts)
- clamp_line_numbers(bufnr, diagnostics)
- lnum = lnum or (vim.api.nvim_win_get_cursor(0)[1] - 1)
- local line_diagnostics = diagnostic_lines(diagnostics)[lnum]
- return show_diagnostics(opts, line_diagnostics)
+ if vim.tbl_isempty(diagnostics) then
+ return
+ end
+
+ local severity_sort = vim.F.if_nil(opts.severity_sort, global_diagnostic_options.severity_sort)
+ if severity_sort then
+ if type(severity_sort) == "table" and severity_sort.reverse then
+ table.sort(diagnostics, function(a, b) return a.severity > b.severity end)
+ else
+ table.sort(diagnostics, function(a, b) return a.severity < b.severity end)
+ end
+ end
+
+ do
+ -- Resolve options with user settings from vim.diagnostic.config
+ -- Unlike the other decoration functions (e.g. set_virtual_text, set_signs, etc.) `open_float`
+ -- does not have a dedicated table for configuration options; instead, the options are mixed in
+ -- with its `opts` table which also includes "keyword" parameters. So we create a dedicated
+ -- options table that inherits missing keys from the global configuration before resolving.
+ local t = global_diagnostic_options.float
+ local float_opts = vim.tbl_extend("keep", opts, type(t) == "table" and t or {})
+ opts = get_resolved_options({ float = float_opts }, nil, bufnr).float
+ end
+
+ local lines = {}
+ local highlights = {}
+ local show_header = vim.F.if_nil(opts.show_header, true)
+ if show_header then
+ table.insert(lines, "Diagnostics:")
+ table.insert(highlights, {0, "Bold"})
+ end
+
+ if opts.format then
+ diagnostics = reformat_diagnostics(opts.format, diagnostics)
+ end
+
+ if opts.source then
+ diagnostics = prefix_source(opts.source, diagnostics)
+ end
+
+ for i, diagnostic in ipairs(diagnostics) do
+ local prefix = string.format("%d. ", i)
+ local hiname = floating_highlight_map[diagnostic.severity]
+ local message_lines = vim.split(diagnostic.message, '\n')
+ table.insert(lines, prefix..message_lines[1])
+ table.insert(highlights, {#prefix, hiname})
+ for j = 2, #message_lines do
+ table.insert(lines, string.rep(' ', #prefix) .. message_lines[j])
+ table.insert(highlights, {0, hiname})
+ end
+ end
+
+ local float_bufnr, winnr = require('vim.lsp.util').open_floating_preview(lines, 'plaintext', opts)
+ for i, hi in ipairs(highlights) do
+ local prefixlen, hiname = unpack(hi)
+ -- Start highlight after the prefix
+ vim.api.nvim_buf_add_highlight(float_bufnr, -1, hiname, i-1, prefixlen, -1)
+ end
+
+ return float_bufnr, winnr
end
--- Remove all diagnostics from the given namespace.
diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua
index 0e63c0dd29..8fb7971c5a 100644
--- a/runtime/lua/vim/lsp/diagnostic.lua
+++ b/runtime/lua/vim/lsp/diagnostic.lua
@@ -551,14 +551,15 @@ end
---@param position table|nil The (0,0)-indexed position
---@return table {popup_bufnr, win_id}
function M.show_position_diagnostics(opts, buf_nr, position)
- if opts then
- if opts.severity then
- opts.severity = severity_lsp_to_vim(opts.severity)
- elseif opts.severity_limit then
- opts.severity = {min=severity_lsp_to_vim(opts.severity_limit)}
- end
+ opts = opts or {}
+ opts.where = "cursor"
+ opts.pos = position
+ if opts.severity then
+ opts.severity = severity_lsp_to_vim(opts.severity)
+ elseif opts.severity_limit then
+ opts.severity = {min=severity_lsp_to_vim(opts.severity_limit)}
end
- return vim.diagnostic.show_position_diagnostics(opts, buf_nr, position)
+ return vim.diagnostic.open_float(buf_nr, opts)
end
--- Open a floating window with the diagnostics from {line_nr}
@@ -573,11 +574,13 @@ end
---@param client_id number|nil the client id
---@return table {popup_bufnr, win_id}
function M.show_line_diagnostics(opts, buf_nr, line_nr, client_id)
+ opts = opts or {}
+ opts.where = "line"
+ opts.pos = line_nr
if client_id then
- opts = opts or {}
opts.namespace = M.get_namespace(client_id)
end
- return vim.diagnostic.show_line_diagnostics(opts, buf_nr, line_nr)
+ return vim.diagnostic.open_float(buf_nr, opts)
end
--- Redraw diagnostics for the given buffer and client
diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua
index 33469597a1..e49453ab76 100644
--- a/test/functional/lua/diagnostic_spec.lua
+++ b/test/functional/lua/diagnostic_spec.lua
@@ -968,8 +968,87 @@ describe('vim.diagnostic', function()
end)
end)
- describe('show_line_diagnostics()', function()
- it('creates floating window and returns popup bufnr and winnr if current line contains diagnostics', function()
+ describe('open_float()', function()
+ it('can show diagnostics from the whole buffer', function()
+ eq({'1. Syntax error', '2. Some warning'}, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error", 0, 1, 0, 3),
+ make_warning("Some warning", 1, 1, 1, 3),
+ }
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ local float_bufnr, winnr = vim.diagnostic.open_float(0, {show_header = false})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+ end)
+
+ it('can show diagnostics from a single line', function()
+ -- Using cursor position
+ eq({'1. Some warning'}, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error", 0, 1, 0, 3),
+ make_warning("Some warning", 1, 1, 1, 3),
+ }
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ vim.api.nvim_win_set_cursor(0, {2, 1})
+ local float_bufnr, winnr = vim.diagnostic.open_float(0, {show_header=false, scope="line"})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+
+ -- With specified position
+ eq({'1. Some warning'}, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error", 0, 1, 0, 3),
+ make_warning("Some warning", 1, 1, 1, 3),
+ }
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ vim.api.nvim_win_set_cursor(0, {1, 1})
+ local float_bufnr, winnr = vim.diagnostic.open_float(0, {show_header=false, scope="line", pos=1})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+ end)
+
+ it('can show diagnostics from a specific position', function()
+ -- Using cursor position
+ eq({'1. Syntax error'}, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error", 1, 1, 1, 2),
+ make_warning("Some warning", 1, 3, 1, 4),
+ }
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ vim.api.nvim_win_set_cursor(0, {2, 2})
+ local float_bufnr, winnr = vim.diagnostic.open_float(0, {show_header=false, scope="cursor"})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+
+ -- With specified position
+ eq({'1. Some warning'}, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error", 1, 1, 1, 2),
+ make_warning("Some warning", 1, 3, 1, 4),
+ }
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ vim.api.nvim_win_set_cursor(0, {1, 1})
+ local float_bufnr, winnr = vim.diagnostic.open_float(0, {show_header=false, scope="cursor", pos={1,3}})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+ end)
+
+ it('creates floating window and returns float bufnr and winnr if current line contains diagnostics', function()
-- Two lines:
-- Diagnostic:
-- 1. <msg>
@@ -979,8 +1058,10 @@ describe('vim.diagnostic', function()
}
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
- local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics()
- return #vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false)
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, {scope="line"})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return #lines
]])
end)
@@ -996,8 +1077,10 @@ describe('vim.diagnostic', function()
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, buf_1_diagnostics)
vim.diagnostic.set(other_ns, other_bufnr, buf_2_diagnostics)
- local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics()
- return #vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false)
+ local float_bufnr, winnr = vim.diagnostic.open_float()
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return #lines
]])
end)
@@ -1012,12 +1095,14 @@ describe('vim.diagnostic', function()
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, ns_1_diagnostics)
vim.diagnostic.set(other_ns, diagnostic_bufnr, ns_2_diagnostics)
- local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics({namespace = diagnostic_ns})
- return #vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false)
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, {namespace = diagnostic_ns})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return #lines
]])
end)
- it('creates floating window and returns popup bufnr and winnr without header, if requested', function()
+ it('creates floating window and returns float bufnr and winnr without header, if requested', function()
-- One line (since no header):
-- 1. <msg>
eq(1, exec_lua [[
@@ -1026,8 +1111,10 @@ describe('vim.diagnostic', function()
}
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
- local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics {show_header = false}
- return #vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false)
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, {show_header = false})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return #lines
]])
end)
@@ -1038,8 +1125,10 @@ describe('vim.diagnostic', function()
}
vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
- local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics({show_header = false}, diagnostic_bufnr, 5)
- return #vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false)
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, {show_header = false, scope = "line", pos = 5})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return #lines
]])
end)
@@ -1051,21 +1140,21 @@ describe('vim.diagnostic', function()
make_error("Syntax error", 0, 1, 0, 3, "source x"),
}
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
- local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics {
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, {
show_header = false,
source = "if_many",
- }
- local lines = vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false)
+ })
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
vim.api.nvim_win_close(winnr, true)
return lines
]])
eq({"1. source x: Syntax error"}, exec_lua [[
- local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics {
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, {
show_header = false,
source = "always",
- }
- local lines = vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false)
+ })
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
vim.api.nvim_win_close(winnr, true)
return lines
]])
@@ -1076,11 +1165,11 @@ describe('vim.diagnostic', function()
make_error("Another error", 0, 1, 0, 3, "source y"),
}
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
- local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics {
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, {
show_header = false,
source = "if_many",
- }
- local lines = vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false)
+ })
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
vim.api.nvim_win_close(winnr, true)
return lines
]])
@@ -1101,24 +1190,24 @@ describe('vim.diagnostic', function()
vim.diagnostic.config({severity_sort = false})
- local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics { show_header = false }
- local lines = vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false)
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, { show_header = false })
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
vim.api.nvim_win_close(winnr, true)
return lines
]])
eq({"1. Syntax error", "2. Error", "3. Warning", "4. Info"}, exec_lua [[
vim.diagnostic.config({severity_sort = true})
- local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics { show_header = false }
- local lines = vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false)
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, { show_header = false })
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
vim.api.nvim_win_close(winnr, true)
return lines
]])
eq({"1. Info", "2. Warning", "3. Error", "4. Syntax error"}, exec_lua [[
vim.diagnostic.config({severity_sort = { reverse = true } })
- local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics { show_header = false }
- local lines = vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false)
+ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, { show_header = false })
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
vim.api.nvim_win_close(winnr, true)
return lines
]])