diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2024-11-25 19:15:05 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2024-11-25 19:27:38 +0000 |
commit | c5d770d311841ea5230426cc4c868e8db27300a8 (patch) | |
tree | dd21f70127b4b8b5f109baefc8ecc5016f507c91 /runtime/lua/vim/lsp.lua | |
parent | 9be89f131f87608f224f0ee06d199fcd09d32176 (diff) | |
parent | 081beb3659bd6d8efc3e977a160b1e72becbd8a2 (diff) | |
download | rneovim-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.lua | 95 |
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} |