feat(diagnostic): jump to related info location from open_float #34837

This commit allows users to jump to the location specified in a
diagnostic's `relatedInformation`, using `gf` from within the
`open_float` window. The cursor need only be on line that displays the
related info.
This commit is contained in:
Riley Bruins
2025-07-10 11:24:17 -07:00
committed by GitHub
parent 7bd4dfd209
commit 68e316e3f9
5 changed files with 113 additions and 6 deletions

View File

@ -1903,7 +1903,8 @@ Lua module: vim.lsp.diagnostic *lsp-diagnostic*
This module provides functionality for requesting LSP diagnostics for a
document/workspace and populating them using |vim.Diagnostic|s.
`DiagnosticRelatedInformation` is supported: it is included in the window
shown by |vim.diagnostic.open_float()|.
shown by |vim.diagnostic.open_float()|. When the cursor is on a line with
related information, |gf| jumps to the problem location.
from({diagnostics}) *vim.lsp.diagnostic.from()*

View File

@ -204,6 +204,9 @@ LSP
• LSP `DiagnosticRelatedInformation` is now shown in
|vim.diagnostic.open_float()|. It is read from the LSP diagnostic object
stored in the `user_data` field.
• When inside the float created by |vim.diagnostic.open_float()| and the
cursor is on a line with `DiagnosticRelatedInformation`, |gf| can be used to
jump to the problematic location.
LUA

View File

@ -2341,6 +2341,8 @@ function M.open_float(opts, ...)
end
end
---@type table<integer, lsp.Location>
local related_info_locations = {}
for i, diagnostic in ipairs(diagnostics) do
if type(prefix_opt) == 'function' then
--- @cast prefix_opt fun(...): string?, string?
@ -2378,15 +2380,16 @@ function M.open_float(opts, ...)
-- Below the diagnostic, show its LSP related information (if any) in the form of file name and
-- range, plus description.
for _, info in ipairs(related_info) do
-- TODO: Somehow allow users to open the location when their cursor is over it?
local file_name = vim.fs.basename(vim.uri_to_fname(info.location.uri))
local location = info.location
local file_name = vim.fs.basename(vim.uri_to_fname(location.uri))
local info_suffix = ': ' .. info.message
related_info_locations[#lines + 1] = info.location
lines[#lines + 1] = string.format(
'%s%s:%s:%s%s',
default_pre,
file_name,
info.location.range.start.line,
info.location.range.start.character,
location.range.start.line,
location.range.start.character,
info_suffix
)
highlights[#highlights + 1] = {
@ -2412,6 +2415,19 @@ function M.open_float(opts, ...)
local float_bufnr, winnr = vim.lsp.util.open_floating_preview(lines, 'plaintext', opts)
vim.bo[float_bufnr].path = vim.bo[bufnr].path
-- TODO: Handle this generally (like vim.ui.open()), rather than overriding gf.
vim.keymap.set('n', 'gf', function()
local cursor_row = api.nvim_win_get_cursor(0)[1]
local location = related_info_locations[cursor_row]
if location then
-- Split the window before calling `show_document` so the window doesn't disappear.
vim.cmd.split()
vim.lsp.util.show_document(location, 'utf-16', { focus = true })
else
vim.cmd.normal({ 'gf', bang = true })
end
end, { buffer = float_bufnr, remap = false })
--- @diagnostic disable-next-line: deprecated
local add_highlight = api.nvim_buf_add_highlight

View File

@ -1,6 +1,7 @@
---@brief This module provides functionality for requesting LSP diagnostics for a document/workspace
---and populating them using |vim.Diagnostic|s. `DiagnosticRelatedInformation` is supported: it is
---included in the window shown by |vim.diagnostic.open_float()|.
---included in the window shown by |vim.diagnostic.open_float()|. When the cursor is on a line with
---related information, |gf| jumps to the problem location.
local lsp = vim.lsp
local protocol = lsp.protocol