diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2024-11-19 22:57:13 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2024-11-19 22:57:13 +0000 |
commit | 9be89f131f87608f224f0ee06d199fcd09d32176 (patch) | |
tree | 11022dcfa9e08cb4ac5581b16734196128688d48 /runtime/lua/vim/lsp.lua | |
parent | ff7ed8f586589d620a806c3758fac4a47a8e7e15 (diff) | |
parent | 88085c2e80a7e3ac29aabb6b5420377eed99b8b6 (diff) | |
download | rneovim-9be89f131f87608f224f0ee06d199fcd09d32176.tar.gz rneovim-9be89f131f87608f224f0ee06d199fcd09d32176.tar.bz2 rneovim-9be89f131f87608f224f0ee06d199fcd09d32176.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 | 113 |
1 files changed, 64 insertions, 49 deletions
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 1592fd3151..60677554ce 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' - _completion = ..., --- @module 'vim.lsp._completion' _dynamic = ..., --- @module 'vim.lsp._dynamic' _snippet_grammar = ..., --- @module 'vim.lsp._snippet_grammar' _tagfunc = ..., --- @module 'vim.lsp._tagfunc' @@ -11,6 +10,7 @@ local lsp = vim._defer_require('vim.lsp', { buf = ..., --- @module 'vim.lsp.buf' client = ..., --- @module 'vim.lsp.client' codelens = ..., --- @module 'vim.lsp.codelens' + completion = ..., --- @module 'vim.lsp.completion' diagnostic = ..., --- @module 'vim.lsp.diagnostic' handlers = ..., --- @module 'vim.lsp.handlers' inlay_hint = ..., --- @module 'vim.lsp.inlay_hint' @@ -33,43 +33,50 @@ lsp.rpc_response_error = lsp.rpc.rpc_response_error -- maps request name to the required server_capability in the client. lsp._request_name_to_capability = { - [ms.textDocument_hover] = { 'hoverProvider' }, - [ms.textDocument_signatureHelp] = { 'signatureHelpProvider' }, - [ms.textDocument_definition] = { 'definitionProvider' }, - [ms.textDocument_implementation] = { 'implementationProvider' }, - [ms.textDocument_declaration] = { 'declarationProvider' }, - [ms.textDocument_typeDefinition] = { 'typeDefinitionProvider' }, - [ms.textDocument_documentSymbol] = { 'documentSymbolProvider' }, - [ms.textDocument_prepareCallHierarchy] = { 'callHierarchyProvider' }, [ms.callHierarchy_incomingCalls] = { 'callHierarchyProvider' }, [ms.callHierarchy_outgoingCalls] = { 'callHierarchyProvider' }, - [ms.textDocument_prepareTypeHierarchy] = { 'typeHierarchyProvider' }, - [ms.typeHierarchy_subtypes] = { 'typeHierarchyProvider' }, - [ms.typeHierarchy_supertypes] = { 'typeHierarchyProvider' }, - [ms.textDocument_rename] = { 'renameProvider' }, - [ms.textDocument_prepareRename] = { 'renameProvider', 'prepareProvider' }, + [ms.codeAction_resolve] = { 'codeActionProvider', 'resolveProvider' }, + [ms.codeLens_resolve] = { 'codeLensProvider', 'resolveProvider' }, + [ms.documentLink_resolve] = { 'documentLinkProvider', 'resolveProvider' }, + [ms.inlayHint_resolve] = { 'inlayHintProvider', 'resolveProvider' }, [ms.textDocument_codeAction] = { 'codeActionProvider' }, [ms.textDocument_codeLens] = { 'codeLensProvider' }, - [ms.codeLens_resolve] = { 'codeLensProvider', 'resolveProvider' }, - [ms.codeAction_resolve] = { 'codeActionProvider', 'resolveProvider' }, - [ms.workspace_executeCommand] = { 'executeCommandProvider' }, - [ms.workspace_symbol] = { 'workspaceSymbolProvider' }, - [ms.textDocument_references] = { 'referencesProvider' }, - [ms.textDocument_rangeFormatting] = { 'documentRangeFormattingProvider' }, - [ms.textDocument_formatting] = { 'documentFormattingProvider' }, [ms.textDocument_completion] = { 'completionProvider' }, - [ms.textDocument_documentHighlight] = { 'documentHighlightProvider' }, - [ms.textDocument_semanticTokens_full] = { 'semanticTokensProvider' }, - [ms.textDocument_semanticTokens_full_delta] = { 'semanticTokensProvider' }, - [ms.textDocument_inlayHint] = { 'inlayHintProvider' }, + [ms.textDocument_declaration] = { 'declarationProvider' }, + [ms.textDocument_definition] = { 'definitionProvider' }, [ms.textDocument_diagnostic] = { 'diagnosticProvider' }, - [ms.inlayHint_resolve] = { 'inlayHintProvider', 'resolveProvider' }, - [ms.textDocument_documentLink] = { 'documentLinkProvider' }, - [ms.documentLink_resolve] = { 'documentLinkProvider', 'resolveProvider' }, [ms.textDocument_didClose] = { 'textDocumentSync', 'openClose' }, [ms.textDocument_didOpen] = { 'textDocumentSync', 'openClose' }, - [ms.textDocument_willSave] = { 'textDocumentSync', 'willSave' }, + [ms.textDocument_documentColor] = { 'colorProvider' }, + [ms.textDocument_documentHighlight] = { 'documentHighlightProvider' }, + [ms.textDocument_documentLink] = { 'documentLinkProvider' }, + [ms.textDocument_documentSymbol] = { 'documentSymbolProvider' }, + [ms.textDocument_formatting] = { 'documentFormattingProvider' }, + [ms.textDocument_hover] = { 'hoverProvider' }, + [ms.textDocument_implementation] = { 'implementationProvider' }, + [ms.textDocument_inlayHint] = { 'inlayHintProvider' }, + [ms.textDocument_inlineValue] = { 'inlineValueProvider' }, + [ms.textDocument_linkedEditingRange] = { 'linkedEditingRangeProvider' }, + [ms.textDocument_moniker] = { 'monikerProvider' }, + [ms.textDocument_onTypeFormatting] = { 'documentOnTypeFormattingProvider' }, + [ms.textDocument_prepareCallHierarchy] = { 'callHierarchyProvider' }, + [ms.textDocument_prepareRename] = { 'renameProvider', 'prepareProvider' }, + [ms.textDocument_prepareTypeHierarchy] = { 'typeHierarchyProvider' }, + [ms.textDocument_rangeFormatting] = { 'documentRangeFormattingProvider' }, + [ms.textDocument_rangesFormatting] = { 'documentRangeFormattingProvider', 'rangesSupport' }, + [ms.textDocument_references] = { 'referencesProvider' }, + [ms.textDocument_rename] = { 'renameProvider' }, + [ms.textDocument_selectionRange] = { 'selectionRangeProvider' }, + [ms.textDocument_semanticTokens_full] = { 'semanticTokensProvider' }, + [ms.textDocument_semanticTokens_full_delta] = { 'semanticTokensProvider' }, + [ms.textDocument_signatureHelp] = { 'signatureHelpProvider' }, + [ms.textDocument_typeDefinition] = { 'typeDefinitionProvider' }, [ms.textDocument_willSaveWaitUntil] = { 'textDocumentSync', 'willSaveWaitUntil' }, + [ms.textDocument_willSave] = { 'textDocumentSync', 'willSave' }, + [ms.typeHierarchy_subtypes] = { 'typeHierarchyProvider' }, + [ms.typeHierarchy_supertypes] = { 'typeHierarchyProvider' }, + [ms.workspace_executeCommand] = { 'executeCommandProvider' }, + [ms.workspace_symbol] = { 'workspaceSymbolProvider' }, } -- TODO improve handling of scratch buffers with LSP attached. @@ -201,10 +208,10 @@ end --- Predicate used to decide if a client should be re-used. Used on all --- running clients. The default implementation re-uses a client if name and --- root_dir matches. ---- @field reuse_client fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean +--- @field reuse_client? fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean --- --- Buffer handle to attach to if starting or re-using a client (0 for current). ---- @field bufnr integer +--- @field bufnr? integer --- --- Suppress error reporting if the LSP server fails to start (default false). --- @field silent? boolean @@ -351,7 +358,7 @@ function lsp._set_defaults(client, bufnr) then vim.bo[bufnr].formatexpr = 'v:lua.vim.lsp.formatexpr()' end - api.nvim_buf_call(bufnr, function() + vim._with({ buf = bufnr }, function() if client.supports_method(ms.textDocument_hover) and is_empty_or_default(bufnr, 'keywordprg') @@ -377,9 +384,9 @@ local function reset_defaults(bufnr) if vim.bo[bufnr].formatexpr == 'v:lua.vim.lsp.formatexpr()' then vim.bo[bufnr].formatexpr = nil end - api.nvim_buf_call(bufnr, function() + vim._with({ buf = bufnr }, function() local keymap = vim.fn.maparg('K', 'n', false, true) - if keymap and keymap.callback == vim.lsp.buf.hover then + if keymap and keymap.callback == vim.lsp.buf.hover and keymap.buffer == 1 then vim.keymap.del('n', 'K', { buffer = bufnr }) end end) @@ -391,9 +398,9 @@ end local function on_client_exit(code, signal, client_id) local client = all_clients[client_id] - for bufnr in pairs(client.attached_buffers) do - vim.schedule(function() - if client and client.attached_buffers[bufnr] then + vim.schedule(function() + for bufnr in pairs(client.attached_buffers) do + if client and client.attached_buffers[bufnr] and api.nvim_buf_is_valid(bufnr) then api.nvim_exec_autocmds('LspDetach', { buffer = bufnr, modeline = false, @@ -401,15 +408,16 @@ local function on_client_exit(code, signal, client_id) }) end - local namespace = vim.lsp.diagnostic.get_namespace(client_id) - vim.diagnostic.reset(namespace, bufnr) client.attached_buffers[bufnr] = nil if #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 then reset_defaults(bufnr) end - end) - end + end + + local namespace = vim.lsp.diagnostic.get_namespace(client_id) + vim.diagnostic.reset(namespace) + end) local name = client.name or 'unknown' @@ -519,7 +527,6 @@ local function buf_detach_client(bufnr, client) end client.attached_buffers[bufnr] = nil - util.buf_versions[bufnr] = nil local namespace = lsp.diagnostic.get_namespace(client.id) vim.diagnostic.reset(namespace, bufnr) @@ -577,7 +584,8 @@ local function buf_attach(bufnr) api.nvim_buf_attach(bufnr, false, { on_lines = function(_, _, changedtick, firstline, lastline, new_lastline) if #lsp.get_clients({ bufnr = bufnr }) == 0 then - return true -- detach + -- detach if there are no clients + return #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 end util.buf_versions[bufnr] = changedtick changetracking.send_changes(bufnr, firstline, lastline, new_lastline) @@ -603,6 +611,7 @@ local function buf_attach(bufnr) buf_detach_client(bufnr, client) end attached_buffers[bufnr] = nil + util.buf_versions[bufnr] = nil end, -- TODO if we know all of the potential clients ahead of time, then we @@ -852,17 +861,20 @@ api.nvim_create_autocmd('VimLeavePre', { ---@param params table|nil 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() +--- The function to call when the buffer has no clients that support the given method. +--- Defaults to an `ERROR` level notification. ---@return table<integer, integer> client_request_ids Map of client-id:request-id pairs ---for all successful requests. ---@return function _cancel_all_requests Function which can be used to ---cancel all the requests. You could instead ---iterate all clients and call their `cancel_request()` methods. -function lsp.buf_request(bufnr, method, params, handler) +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 }, }) bufnr = resolve_bufnr(bufnr) @@ -884,7 +896,11 @@ function lsp.buf_request(bufnr, method, params, handler) -- if has client but no clients support the given method, notify the user if next(clients) and not method_supported then - vim.notify(lsp._unsupported_method(method), vim.log.levels.ERROR) + if on_unsupported == nil then + vim.notify(lsp._unsupported_method(method), vim.log.levels.ERROR) + else + on_unsupported() + end vim.cmd.redraw() return {}, function() end end @@ -1002,8 +1018,7 @@ end --- - findstart=0: column where the completion starts, or -2 or -3 --- - findstart=1: list of matches (actually just calls |complete()|) function lsp.omnifunc(findstart, base) - log.debug('omnifunc.findstart', { findstart = findstart, base = base }) - return vim.lsp._completion.omnifunc(findstart, base) + return vim.lsp.completion._omnifunc(findstart, base) end --- @class vim.lsp.formatexpr.Opts @@ -1016,7 +1031,7 @@ end --- Provides an interface between the built-in client and a `formatexpr` function. --- --- Currently only supports a single client. This can be set via ---- `setlocal formatexpr=v:lua.vim.lsp.formatexpr()` but will typically or in `on_attach` +--- `setlocal formatexpr=v:lua.vim.lsp.formatexpr()` or (more typically) in `on_attach` --- via `vim.bo[bufnr].formatexpr = 'v:lua.vim.lsp.formatexpr(#{timeout_ms:250})'`. --- ---@param opts? vim.lsp.formatexpr.Opts |