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

@ -47,6 +47,8 @@ LSP
• *vim.lsp.util.jump_to_location* • *vim.lsp.util.jump_to_location*
• *vim.lsp.buf.execute_command* Use |Client:exec_cmd()| instead. • *vim.lsp.buf.execute_command* Use |Client:exec_cmd()| instead.
• *vim.lsp.buf.completion* Use |vim.lsp.completion.trigger()| instead. • *vim.lsp.buf.completion* Use |vim.lsp.completion.trigger()| instead.
• vim.lsp.buf_request_all The `error` key has been renamed to `err` inside
the result parameter of the handler.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
DEPRECATED IN 0.10 *deprecated-0.10* DEPRECATED IN 0.10 *deprecated-0.10*

View File

@ -702,7 +702,10 @@ buf_request_all({bufnr}, {method}, {params}, {handler})
Parameters: ~ Parameters: ~
• {bufnr} (`integer`) Buffer handle, or 0 for current. • {bufnr} (`integer`) Buffer handle, or 0 for current.
• {method} (`string`) LSP method name • {method} (`string`) LSP method name
• {params} (`table?`) Parameters to send to the server • {params} (`table|(fun(client: vim.lsp.Client, bufnr: integer): table?)?`)
Parameters to send to the server. Can also be passed as a
function that returns the params table for cases where
parameters are specific to the client.
• {handler} (`function`) Handler called after all requests are • {handler} (`function`) Handler called after all requests are
completed. Server results are passed as a completed. Server results are passed as a
`client_id:result` map. `client_id:result` map.
@ -1268,6 +1271,13 @@ Lua module: vim.lsp.buf *lsp-buf*
• {title}? (`string`) Title for the list. • {title}? (`string`) Title for the list.
• {context}? (`table`) `ctx` from |lsp-handler| • {context}? (`table`) `ctx` from |lsp-handler|
*vim.lsp.buf.hover.Opts*
Extends: |vim.lsp.util.open_floating_preview.Opts|
Fields: ~
• {silent}? (`boolean`)
*vim.lsp.buf.add_workspace_folder()* *vim.lsp.buf.add_workspace_folder()*
add_workspace_folder({workspace_folder}) add_workspace_folder({workspace_folder})
@ -1385,7 +1395,7 @@ format({opts}) *vim.lsp.buf.format()*
contain `start` and `end` keys as described above, in which contain `start` and `end` keys as described above, in which
case `textDocument/rangesFormatting` support is required. case `textDocument/rangesFormatting` support is required.
hover() *vim.lsp.buf.hover()* hover({config}) *vim.lsp.buf.hover()*
Displays hover information about the symbol under the cursor in a floating Displays hover information about the symbol under the cursor in a floating
window. The window will be dismissed on cursor move. Calling the function window. The window will be dismissed on cursor move. Calling the function
twice will jump into the floating window (thus by default, "KK" will open twice will jump into the floating window (thus by default, "KK" will open
@ -1393,6 +1403,9 @@ hover() *vim.lsp.buf.hover()*
mappings are available as usual, except that "q" dismisses the window. You mappings are available as usual, except that "q" dismisses the window. You
can scroll the contents the same as you would any other buffer. can scroll the contents the same as you would any other buffer.
Parameters: ~
• {config} (`vim.lsp.buf.hover.Opts?`) See |vim.lsp.buf.hover.Opts|.
implementation({opts}) *vim.lsp.buf.implementation()* implementation({opts}) *vim.lsp.buf.implementation()*
Lists all the implementations for the symbol under the cursor in the Lists all the implementations for the symbol under the cursor in the
quickfix window. quickfix window.
@ -1812,27 +1825,6 @@ stop({bufnr}, {client_id}) *vim.lsp.semantic_tokens.stop()*
============================================================================== ==============================================================================
Lua module: vim.lsp.handlers *lsp-handlers* Lua module: vim.lsp.handlers *lsp-handlers*
hover({_}, {result}, {ctx}, {config}) *vim.lsp.handlers.hover()*
|lsp-handler| for the method "textDocument/hover" >lua
vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(
vim.lsp.handlers.hover, {
-- Use a sharp border with `FloatBorder` highlights
border = "single",
-- add the title in hover float window
title = "hover"
}
)
<
Parameters: ~
• {result} (`lsp.Hover`)
• {ctx} (`lsp.HandlerContext`)
• {config} (`table`) Configuration table.
• border: (default=nil)
• Add borders to the floating window
• See |vim.lsp.util.open_floating_preview()| for more
options.
*vim.lsp.handlers.signature_help()* *vim.lsp.handlers.signature_help()*
signature_help({_}, {result}, {ctx}, {config}) signature_help({_}, {result}, {ctx}, {config})
|lsp-handler| for the method "textDocument/signatureHelp". |lsp-handler| for the method "textDocument/signatureHelp".

View File

@ -79,13 +79,10 @@ LSP
customizing the transformation of an LSP CompletionItem to |complete-items|. customizing the transformation of an LSP CompletionItem to |complete-items|.
• |vim.lsp.diagnostic.from()| can be used to convert a list of • |vim.lsp.diagnostic.from()| can be used to convert a list of
|vim.Diagnostic| objects into their LSP diagnostic representation. |vim.Diagnostic| objects into their LSP diagnostic representation.
• |vim.lsp.buf.references()| now handles multiple clients but no longer • |vim.lsp.buf.references()|, |vim.lsp.buf.declaration()|, |vim.lsp.buf.definition()|,
triggers the global `textDocument/references` handler from |vim.lsp.buf.type_definition()|, |vim.lsp.buf.implementation()| and
`vim.lsp.handlers` |vim.lsp.buf.hover()| now support merging the results of multiple clients
• |vim.lsp.buf.declaration()|, |vim.lsp.buf.definition()|, but no longer trigger the global handlers from `vim.lsp.handlers`
|vim.lsp.buf.type_definition()| and |vim.lsp.buf.implementation()| now
support merging the results of multiple clients but no longer trigger the
global handlers from `vim.lsp.handlers`
• |vim.lsp.buf.typehierarchy()| now passes the correct params for each • |vim.lsp.buf.typehierarchy()| now passes the correct params for each
client request. client request.

View File

@ -915,7 +915,9 @@ end
--- ---
---@param bufnr (integer) Buffer handle, or 0 for current. ---@param bufnr (integer) Buffer handle, or 0 for current.
---@param method (string) LSP method name ---@param method (string) LSP method name
---@param params? table|(fun(client: vim.lsp.Client, bufnr: integer): table?) Parameters to send to the server ---@param params? table|(fun(client: vim.lsp.Client, bufnr: integer): table?) Parameters to send to the server.
--- Can also be passed as a function that returns the params table for cases where
--- parameters are specific to the client.
---@param handler lsp.MultiHandler (function) ---@param handler lsp.MultiHandler (function)
--- Handler called after all requests are completed. Server results are passed as --- Handler called after all requests are completed. Server results are passed as
--- a `client_id:result` map. --- a `client_id:result` map.

View File

@ -2,6 +2,7 @@
error('Cannot require a meta file') error('Cannot require a meta file')
---@alias lsp.Handler fun(err: lsp.ResponseError?, result: any, context: lsp.HandlerContext, config?: table): ...any ---@alias lsp.Handler fun(err: lsp.ResponseError?, result: any, context: lsp.HandlerContext, config?: table): ...any
---@alias lsp.MultiHandler fun(results: table<integer,{err: lsp.ResponseError?, result: any}>, context: lsp.HandlerContext, config?: table): ...any
---@class lsp.HandlerContext ---@class lsp.HandlerContext
---@field method string ---@field method string

View File

@ -20,6 +20,9 @@ local function client_positional_params(params)
end end
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 --- Displays hover information about the symbol under the cursor in a floating
--- window. The window will be dismissed on cursor move. --- window. The window will be dismissed on cursor move.
--- Calling the function twice will jump into the floating window --- 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, --- In the floating window, all commands and mappings are available as usual,
--- except that "q" dismisses the window. --- except that "q" dismisses the window.
--- You can scroll the contents the same as you would any other buffer. --- You can scroll the contents the same as you would any other buffer.
function M.hover() --- @param config? vim.lsp.buf.hover.Opts
lsp.buf_request(0, ms.textDocument_hover, client_positional_params()) 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 end
local function request_with_opts(name, params, opts) local function request_with_opts(name, params, opts)

View File

@ -317,7 +317,7 @@ M[ms.textDocument_formatting] = function(_, result, ctx, _)
util.apply_text_edits(result, ctx.bufnr, client.offset_encoding) util.apply_text_edits(result, ctx.bufnr, client.offset_encoding)
end end
--- @deprecated --- @deprecated remove in 0.13
--- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion --- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion
M[ms.textDocument_completion] = function(_, result, _, _) M[ms.textDocument_completion] = function(_, result, _, _)
if vim.tbl_isempty(result or {}) then if vim.tbl_isempty(result or {}) then
@ -334,6 +334,7 @@ M[ms.textDocument_completion] = function(_, result, _, _)
vim.fn.complete(textMatch + 1, matches) vim.fn.complete(textMatch + 1, matches)
end end
--- @deprecated
--- |lsp-handler| for the method "textDocument/hover" --- |lsp-handler| for the method "textDocument/hover"
--- ---
--- ```lua --- ```lua
@ -384,7 +385,9 @@ function M.hover(_, result, ctx, config)
return util.open_floating_preview(contents, format, config) return util.open_floating_preview(contents, format, config)
end end
--- @deprecated remove in 0.13
--- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_hover --- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_hover
--- @diagnostic disable-next-line: deprecated
M[ms.textDocument_hover] = M.hover M[ms.textDocument_hover] = M.hover
local sig_help_ns = api.nvim_create_namespace('vim_lsp_signature_help') local sig_help_ns = api.nvim_create_namespace('vim_lsp_signature_help')