aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/lsp.lua
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2024-11-25 19:15:05 +0000
committerJosh Rahm <joshuarahm@gmail.com>2024-11-25 19:27:38 +0000
commitc5d770d311841ea5230426cc4c868e8db27300a8 (patch)
treedd21f70127b4b8b5f109baefc8ecc5016f507c91 /runtime/lua/vim/lsp.lua
parent9be89f131f87608f224f0ee06d199fcd09d32176 (diff)
parent081beb3659bd6d8efc3e977a160b1e72becbd8a2 (diff)
downloadrneovim-c5d770d311841ea5230426cc4c868e8db27300a8.tar.gz
rneovim-c5d770d311841ea5230426cc4c868e8db27300a8.tar.bz2
rneovim-c5d770d311841ea5230426cc4c868e8db27300a8.zip
Merge remote-tracking branch 'upstream/master' into mix_20240309
Diffstat (limited to 'runtime/lua/vim/lsp.lua')
-rw-r--r--runtime/lua/vim/lsp.lua95
1 files changed, 46 insertions, 49 deletions
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 60677554ce..0de3b4ee4d 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -3,7 +3,6 @@ local validate = vim.validate
local lsp = vim._defer_require('vim.lsp', {
_changetracking = ..., --- @module 'vim.lsp._changetracking'
- _dynamic = ..., --- @module 'vim.lsp._dynamic'
_snippet_grammar = ..., --- @module 'vim.lsp._snippet_grammar'
_tagfunc = ..., --- @module 'vim.lsp._tagfunc'
_watchfiles = ..., --- @module 'vim.lsp._watchfiles'
@@ -31,6 +30,13 @@ local changetracking = lsp._changetracking
---@nodoc
lsp.rpc_response_error = lsp.rpc.rpc_response_error
+lsp._resolve_to_request = {
+ [ms.codeAction_resolve] = ms.textDocument_codeAction,
+ [ms.codeLens_resolve] = ms.textDocument_codeLens,
+ [ms.documentLink_resolve] = ms.textDocument_documentLink,
+ [ms.inlayHint_resolve] = ms.textDocument_inlayHint,
+}
+
-- maps request name to the required server_capability in the client.
lsp._request_name_to_capability = {
[ms.callHierarchy_incomingCalls] = { 'callHierarchyProvider' },
@@ -86,7 +92,7 @@ lsp._request_name_to_capability = {
---@param bufnr (integer|nil) Buffer number to resolve. Defaults to current buffer
---@return integer bufnr
local function resolve_bufnr(bufnr)
- validate({ bufnr = { bufnr, 'n', true } })
+ validate('bufnr', bufnr, 'number', true)
if bufnr == nil or bufnr == 0 then
return api.nvim_get_current_buf()
end
@@ -189,9 +195,10 @@ local function reuse_client_default(client, config)
end
if config.root_dir then
+ local root = vim.uri_from_fname(config.root_dir)
for _, dir in ipairs(client.workspace_folders or {}) do
-- note: do not need to check client.root_dir since that should be client.workspace_folders[1]
- if config.root_dir == dir.name then
+ if root == dir.uri then
return true
end
end
@@ -235,9 +242,9 @@ end
--- - `name` arbitrary name for the LSP client. Should be unique per language server.
--- - `cmd` command string[] or function, described at |vim.lsp.start_client()|.
--- - `root_dir` path to the project root. By default this is used to decide if an existing client
---- should be re-used. The example above uses |vim.fs.root()| and |vim.fs.dirname()| to detect
---- the root by traversing the file system upwards starting from the current directory until
---- either a `pyproject.toml` or `setup.py` file is found.
+--- should be re-used. The example above uses |vim.fs.root()| to detect the root by traversing
+--- the file system upwards starting from the current directory until either a `pyproject.toml`
+--- or `setup.py` file is found.
--- - `workspace_folders` list of `{ uri:string, name: string }` tables specifying the project root
--- folders used by the language server. If `nil` the property is derived from `root_dir` for
--- convenience.
@@ -630,10 +637,8 @@ end
---@param client_id (integer) Client id
---@return boolean success `true` if client was attached successfully; `false` otherwise
function lsp.buf_attach_client(bufnr, client_id)
- validate({
- bufnr = { bufnr, 'n', true },
- client_id = { client_id, 'n' },
- })
+ validate('bufnr', bufnr, 'number', true)
+ validate('client_id', client_id, 'number')
bufnr = resolve_bufnr(bufnr)
if not api.nvim_buf_is_loaded(bufnr) then
log.warn(string.format('buf_attach_client called on unloaded buffer (id: %d): ', bufnr))
@@ -669,10 +674,8 @@ end
---@param bufnr integer Buffer handle, or 0 for current
---@param client_id integer Client id
function lsp.buf_detach_client(bufnr, client_id)
- validate({
- bufnr = { bufnr, 'n', true },
- client_id = { client_id, 'n' },
- })
+ validate('bufnr', bufnr, 'number', true)
+ validate('client_id', client_id, 'number')
bufnr = resolve_bufnr(bufnr)
local client = all_clients[client_id]
@@ -773,7 +776,7 @@ end
---@param filter? vim.lsp.get_clients.Filter
---@return vim.lsp.Client[]: List of |vim.lsp.Client| objects
function lsp.get_clients(filter)
- validate({ filter = { filter, 't', true } })
+ validate('filter', filter, 'table', true)
filter = filter or {}
@@ -858,7 +861,7 @@ api.nvim_create_autocmd('VimLeavePre', {
---
---@param bufnr (integer) Buffer handle, or 0 for current.
---@param method (string) LSP method name
----@param params table|nil Parameters to send to the server
+---@param params? table|(fun(client: vim.lsp.Client, bufnr: integer): table?) Parameters to send to the server
---@param handler? lsp.Handler See |lsp-handler|
--- If nil, follows resolution strategy defined in |lsp-handler-configuration|
---@param on_unsupported? fun()
@@ -870,12 +873,10 @@ api.nvim_create_autocmd('VimLeavePre', {
---cancel all the requests. You could instead
---iterate all clients and call their `cancel_request()` methods.
function lsp.buf_request(bufnr, method, params, handler, on_unsupported)
- validate({
- bufnr = { bufnr, 'n', true },
- method = { method, 's' },
- handler = { handler, 'f', true },
- on_unsupported = { on_unsupported, 'f', true },
- })
+ validate('bufnr', bufnr, 'number', true)
+ validate('method', method, 'string')
+ validate('handler', handler, 'function', true)
+ validate('on_unsupported', on_unsupported, 'function', true)
bufnr = resolve_bufnr(bufnr)
local method_supported = false
@@ -885,7 +886,8 @@ function lsp.buf_request(bufnr, method, params, handler, on_unsupported)
if client.supports_method(method, { bufnr = bufnr }) then
method_supported = true
- local request_success, request_id = client.request(method, params, handler, bufnr)
+ local cparams = type(params) == 'function' and params(client, bufnr) or params --[[@as table?]]
+ local request_success, request_id = client.request(method, cparams, handler, bufnr)
-- This could only fail if the client shut down in the time since we looked
-- it up and we did the request, which should be rare.
if request_success then
@@ -920,35 +922,31 @@ end
---
---@param bufnr (integer) Buffer handle, or 0 for current.
---@param method (string) LSP method name
----@param params (table|nil) Parameters to send to the server
----@param handler fun(results: table<integer, {error: lsp.ResponseError?, result: any}>) (function)
+---@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.
---@return function cancel Function that cancels all requests.
function lsp.buf_request_all(bufnr, method, params, handler)
- local results = {} --- @type table<integer,{error: lsp.ResponseError?, result: any}>
- local result_count = 0
- local expected_result_count = 0
-
- local set_expected_result_count = once(function()
- for _, client in ipairs(lsp.get_clients({ bufnr = bufnr })) do
- if client.supports_method(method, { bufnr = bufnr }) then
- expected_result_count = expected_result_count + 1
- end
+ local results = {} --- @type table<integer,{err: lsp.ResponseError?, result: any}>
+ local remaining --- @type integer?
+
+ local _, cancel = lsp.buf_request(bufnr, method, params, function(err, result, ctx, config)
+ if not remaining then
+ -- Calculate as late as possible in case a client is removed during the request
+ remaining = #lsp.get_clients({ bufnr = bufnr, method = method })
end
- end)
- local function _sync_handler(err, result, ctx)
- results[ctx.client_id] = { error = err, result = result }
- result_count = result_count + 1
- set_expected_result_count()
+ -- The error key is deprecated and will be removed in 0.13
+ results[ctx.client_id] = { err = err, error = err, result = result }
+ remaining = remaining - 1
- if result_count >= expected_result_count then
- handler(results)
+ if remaining == 0 then
+ handler(results, ctx, config)
end
- end
-
- local _, cancel = lsp.buf_request(bufnr, method, params, _sync_handler)
+ end)
return cancel
end
@@ -992,10 +990,8 @@ end
---
---@return boolean success true if any client returns true; false otherwise
function lsp.buf_notify(bufnr, method, params)
- validate({
- bufnr = { bufnr, 'n', true },
- method = { method, 's' },
- })
+ validate('bufnr', bufnr, 'number', true)
+ validate('method', method, 'string')
local resp = false
for _, client in ipairs(lsp.get_clients({ bufnr = bufnr })) do
if client.rpc.notify(method, params) then
@@ -1056,7 +1052,7 @@ function lsp.formatexpr(opts)
if client.supports_method(ms.textDocument_rangeFormatting) then
local params = util.make_formatting_params()
local end_line = vim.fn.getline(end_lnum) --[[@as string]]
- local end_col = util._str_utfindex_enc(end_line, nil, client.offset_encoding)
+ local end_col = vim.str_utfindex(end_line, client.offset_encoding)
--- @cast params +lsp.DocumentRangeFormattingParams
params.range = {
start = {
@@ -1175,6 +1171,7 @@ function lsp.for_each_buffer_client(bufnr, fn)
end
end
+--- @deprecated
--- Function to manage overriding defaults for LSP handlers.
---@param handler (lsp.Handler) See |lsp-handler|
---@param override_config (table) Table containing the keys to override behavior of the {handler}