aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLewis Russell <lewis6991@gmail.com>2024-10-24 16:47:41 +0100
committerLewis Russell <lewis6991@gmail.com>2024-10-29 09:06:05 +0000
commit8260e4860b27a54a061bd8e2a9da23069993953a (patch)
tree0fdf62a8755a54c40e191dba3d629cb5e8c21ecb
parent1471dfc85964a9d95c216619d715bfe449d97c19 (diff)
downloadrneovim-8260e4860b27a54a061bd8e2a9da23069993953a.tar.gz
rneovim-8260e4860b27a54a061bd8e2a9da23069993953a.tar.bz2
rneovim-8260e4860b27a54a061bd8e2a9da23069993953a.zip
feat(lsp)!: multiple client support for vim.lsp.buf.hover()
Deprecate `vim.lsp.handlers.hover` and `vim.lsp.handlers['textDocument/hover']`
-rw-r--r--runtime/doc/deprecated.txt2
-rw-r--r--runtime/doc/lsp.txt38
-rw-r--r--runtime/doc/news.txt11
-rw-r--r--runtime/lua/vim/lsp.lua4
-rw-r--r--runtime/lua/vim/lsp/_meta.lua1
-rw-r--r--runtime/lua/vim/lsp/buf.lua77
-rw-r--r--runtime/lua/vim/lsp/handlers.lua5
7 files changed, 104 insertions, 34 deletions
diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt
index 61666f4fe2..c768f30da2 100644
--- a/runtime/doc/deprecated.txt
+++ b/runtime/doc/deprecated.txt
@@ -47,6 +47,8 @@ LSP
• *vim.lsp.util.jump_to_location*
• *vim.lsp.buf.execute_command* Use |Client:exec_cmd()| 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*
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index ab59c66912..300a58b681 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -702,7 +702,10 @@ buf_request_all({bufnr}, {method}, {params}, {handler})
Parameters: ~
• {bufnr} (`integer`) Buffer handle, or 0 for current.
• {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
completed. Server results are passed as a
`client_id:result` map.
@@ -1268,6 +1271,13 @@ Lua module: vim.lsp.buf *lsp-buf*
• {title}? (`string`) Title for the list.
• {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()*
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
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
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
@@ -1393,6 +1403,9 @@ hover() *vim.lsp.buf.hover()*
mappings are available as usual, except that "q" dismisses the window. You
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()*
Lists all the implementations for the symbol under the cursor in the
quickfix window.
@@ -1812,27 +1825,6 @@ stop({bufnr}, {client_id}) *vim.lsp.semantic_tokens.stop()*
==============================================================================
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()*
signature_help({_}, {result}, {ctx}, {config})
|lsp-handler| for the method "textDocument/signatureHelp".
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index 0ec08ac324..508d47e59f 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -79,13 +79,10 @@ LSP
customizing the transformation of an LSP CompletionItem to |complete-items|.
• |vim.lsp.diagnostic.from()| can be used to convert a list of
|vim.Diagnostic| objects into their LSP diagnostic representation.
-• |vim.lsp.buf.references()| now handles multiple clients but no longer
- triggers the global `textDocument/references` handler from
- `vim.lsp.handlers`
-• |vim.lsp.buf.declaration()|, |vim.lsp.buf.definition()|,
- |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.references()|, |vim.lsp.buf.declaration()|, |vim.lsp.buf.definition()|,
+ |vim.lsp.buf.type_definition()|, |vim.lsp.buf.implementation()| and
+ |vim.lsp.buf.hover()| 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
client request.
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 4065785c5a..685dcae851 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -915,7 +915,9 @@ end
---
---@param bufnr (integer) Buffer handle, or 0 for current.
---@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)
--- Handler called after all requests are completed. Server results are passed as
--- a `client_id:result` map.
diff --git a/runtime/lua/vim/lsp/_meta.lua b/runtime/lua/vim/lsp/_meta.lua
index be3222828d..589a49c003 100644
--- a/runtime/lua/vim/lsp/_meta.lua
+++ b/runtime/lua/vim/lsp/_meta.lua
@@ -2,6 +2,7 @@
error('Cannot require a meta file')
---@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
---@field method string
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua
index 5f50e361c4..dd06b1b6c0 100644
--- a/runtime/lua/vim/lsp/buf.lua
+++ b/runtime/lua/vim/lsp/buf.lua
@@ -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)
diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua
index a905f76fda..ad827cfd34 100644
--- a/runtime/lua/vim/lsp/handlers.lua
+++ b/runtime/lua/vim/lsp/handlers.lua
@@ -317,7 +317,7 @@ M[ms.textDocument_formatting] = function(_, result, ctx, _)
util.apply_text_edits(result, ctx.bufnr, client.offset_encoding)
end
---- @deprecated
+--- @deprecated remove in 0.13
--- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion
M[ms.textDocument_completion] = function(_, result, _, _)
if vim.tbl_isempty(result or {}) then
@@ -334,6 +334,7 @@ M[ms.textDocument_completion] = function(_, result, _, _)
vim.fn.complete(textMatch + 1, matches)
end
+--- @deprecated
--- |lsp-handler| for the method "textDocument/hover"
---
--- ```lua
@@ -384,7 +385,9 @@ function M.hover(_, result, ctx, config)
return util.open_floating_preview(contents, format, config)
end
+--- @deprecated remove in 0.13
--- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_hover
+--- @diagnostic disable-next-line: deprecated
M[ms.textDocument_hover] = M.hover
local sig_help_ns = api.nvim_create_namespace('vim_lsp_signature_help')