feat(lsp)!: multiple client support for vim.lsp.buf.hover()

Deprecate `vim.lsp.handlers.hover` and `vim.lsp.handlers['textDocument/hover']`
This commit is contained in:
Lewis Russell
2024-10-24 16:47:41 +01:00
parent 1471dfc859
commit 8260e4860b
7 changed files with 104 additions and 34 deletions

View File

@@ -20,6 +20,9 @@ local function client_positional_params(params)
end
end
--- @class vim.lsp.buf.hover.Opts : vim.lsp.util.open_floating_preview.Opts
--- @field silent? boolean
--- Displays hover information about the symbol under the cursor in a floating
--- window. The window will be dismissed on cursor move.
--- Calling the function twice will jump into the floating window
@@ -27,8 +30,78 @@ end
--- In the floating window, all commands and mappings are available as usual,
--- except that "q" dismisses the window.
--- You can scroll the contents the same as you would any other buffer.
function M.hover()
lsp.buf_request(0, ms.textDocument_hover, client_positional_params())
--- @param config? vim.lsp.buf.hover.Opts
function M.hover(config)
config = config or {}
config.focus_id = ms.textDocument_hover
lsp.buf_request_all(0, ms.textDocument_hover, client_positional_params(), function(results, ctx)
if api.nvim_get_current_buf() ~= ctx.bufnr then
-- Ignore result since buffer changed. This happens for slow language servers.
return
end
-- Filter errors from results
local results1 = {} --- @type table<integer,lsp.Hover>
for client_id, resp in pairs(results) do
local err, result = resp.err, resp.result
if err then
lsp.log.error(err.code, err.message)
elseif result then
results1[client_id] = result
end
end
if #results1 == 0 then
if config.silent ~= true then
vim.notify('No information available')
end
return
end
local contents = {} --- @type string[]
local nresults = #vim.tbl_keys(results1)
local format = 'markdown'
for client_id, result in pairs(results1) do
if nresults > 1 then
-- Show client name if there are multiple clients
contents[#contents + 1] = string.format('# %s', lsp.get_client_by_id(client_id).name)
end
if type(result.contents) == 'table' and result.contents.kind == 'plaintext' then
if #results1 == 1 then
format = 'plaintext'
contents = vim.split(result.contents.value or '', '\n', { trimempty = true })
else
-- Surround plaintext with ``` to get correct formatting
contents[#contents + 1] = '```'
vim.list_extend(
contents,
vim.split(result.contents.value or '', '\n', { trimempty = true })
)
contents[#contents + 1] = '```'
end
else
vim.list_extend(contents, util.convert_input_to_markdown_lines(result.contents))
end
contents[#contents + 1] = '---'
end
-- Remove last linebreak ('---')
contents[#contents] = nil
if vim.tbl_isempty(contents) then
if config.silent ~= true then
vim.notify('No information available')
end
return
end
lsp.util.open_floating_preview(contents, format, config)
end)
end
local function request_with_opts(name, params, opts)