From 30ca6d23a9c77175a76a4cd59da81de83d9253af Mon Sep 17 00:00:00 2001 From: Raphael Date: Thu, 8 Sep 2022 23:09:32 +0800 Subject: fix(lsp): when buffer detach remove buffer from client attached buffers (#20081) Co-authored-by: Mathias Fussenegger --- runtime/lua/vim/lsp.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'runtime/lua/vim/lsp.lua') diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 1dc1a045fd..051127c9c6 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -1644,6 +1644,7 @@ function lsp.buf_attach_client(bufnr, client_id) if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'openClose') then client.notify('textDocument/didClose', params) end + client.attached_buffers[bufnr] = nil end) util.buf_versions[bufnr] = nil all_buffer_active_clients[bufnr] = nil -- cgit From 9b4cab012662514af6fda3648d544633e1d73d4b Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Sat, 10 Sep 2022 18:56:29 -0600 Subject: fix(lsp): schedule removal of client object (#20148) The execution of the LspDetach autocommands in the LSP client's on_exit function are scheduled on the event loop to avoid making API calls in a fast context; however, this means that by the time the LspDetach autocommands finally run the client object has already been deleted. To address this, we also schedule the deletion of the client on the event loop so that it is guaranteed to occur after all of the LspDetach autocommands have fired. --- runtime/lua/vim/lsp.lua | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'runtime/lua/vim/lsp.lua') diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 051127c9c6..22933d8143 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -1147,33 +1147,34 @@ function lsp.start_client(config) local namespace = vim.lsp.diagnostic.get_namespace(client_id) vim.diagnostic.reset(namespace, bufnr) - end) - client_ids[client_id] = nil - end - if vim.tbl_isempty(client_ids) then - vim.schedule(function() - unset_defaults(bufnr) + client_ids[client_id] = nil + if vim.tbl_isempty(client_ids) then + unset_defaults(bufnr) + end end) end end - local client = active_clients[client_id] and active_clients[client_id] - or uninitialized_clients[client_id] - active_clients[client_id] = nil - uninitialized_clients[client_id] = nil - -- Client can be absent if executable starts, but initialize fails - -- init/attach won't have happened - if client then - changetracking.reset(client) - end - if code ~= 0 or (signal ~= 0 and signal ~= 15) then - local msg = - string.format('Client %s quit with exit code %s and signal %s', client_id, code, signal) - vim.schedule(function() + -- Schedule the deletion of the client object so that it exists in the execution of LspDetach + -- autocommands + vim.schedule(function() + local client = active_clients[client_id] and active_clients[client_id] + or uninitialized_clients[client_id] + active_clients[client_id] = nil + uninitialized_clients[client_id] = nil + + -- Client can be absent if executable starts, but initialize fails + -- init/attach won't have happened + if client then + changetracking.reset(client) + end + if code ~= 0 or (signal ~= 0 and signal ~= 15) then + local msg = + string.format('Client %s quit with exit code %s and signal %s', client_id, code, signal) vim.notify(msg, vim.log.levels.WARN) - end) - end + end + end) end -- Start the RPC client. -- cgit From 63be7651829f8b77c4974d08ebe09f7775e41a8a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 25 Sep 2022 19:58:27 -0400 Subject: fix(docs): invalid :help links #20345 Fix those naughty single quotes. closes #20159 --- runtime/lua/vim/lsp.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'runtime/lua/vim/lsp.lua') diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 22933d8143..a64facf214 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -823,7 +823,7 @@ end --- }) --- --- ---- See |lsp.start_client| for all available options. The most important are: +--- See |vim.lsp.start_client()| for all available options. The most important are: --- --- `name` is an arbitrary name for the LSP client. It should be unique per --- language server. @@ -834,7 +834,7 @@ end --- --- `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.find| and |vim.fs.dirname| to detect the +--- The example above uses |vim.fs.find()| 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. @@ -849,11 +849,11 @@ end --- --- --- To ensure a language server is only started for languages it can handle, ---- make sure to call |vim.lsp.start| within a |FileType| autocmd. +--- make sure to call |vim.lsp.start()| within a |FileType| autocmd. --- Either use |:au|, |nvim_create_autocmd()| or put the call in a --- `ftplugin/.lua` (See |ftplugin-name|) --- ----@param config table Same configuration as documented in |lsp.start_client()| +---@param config table Same configuration as documented in |vim.lsp.start_client()| ---@param opts nil|table Optional keyword arguments: --- - reuse_client (fun(client: client, config: table): boolean) --- Predicate used to decide if a client should be re-used. @@ -902,12 +902,12 @@ end --- --- ---@param cmd: (table|string|fun(dispatchers: table):table) command string or ---- list treated like |jobstart|. The command must launch the language server +--- list treated like |jobstart()|. The command must launch the language server --- process. `cmd` can also be a function that creates an RPC client. --- The function receives a dispatchers table and must return a table with the --- functions `request`, `notify`, `is_closing` and `terminate` ---- See |vim.lsp.rpc.request| and |vim.lsp.rpc.notify| ---- For TCP there is a built-in rpc client factory: |vim.lsp.rpc.connect| +--- See |vim.lsp.rpc.request()| and |vim.lsp.rpc.notify()| +--- For TCP there is a built-in rpc client factory: |vim.lsp.rpc.connect()| --- ---@param cmd_cwd: (string, default=|getcwd()|) Directory to launch --- the `cmd` process. Not related to `root_dir`. @@ -963,7 +963,7 @@ end ---@param on_error Callback with parameters (code, ...), invoked --- when the client operation throws an error. `code` is a number describing --- the error. Other arguments may be passed depending on the error kind. See ---- |vim.lsp.rpc.client_errors| for possible errors. +--- `vim.lsp.rpc.client_errors` for possible errors. --- Use `vim.lsp.rpc.client_errors[code]` to get human-friendly name. --- ---@param before_init Callback with parameters (initialize_params, config) @@ -999,8 +999,8 @@ end --- notifications to the server by the given number in milliseconds. No debounce --- occurs if nil --- - exit_timeout (number|boolean, default false): Milliseconds to wait for server to ---- exit cleanly after sending the 'shutdown' request before sending kill -15. ---- If set to false, nvim exits immediately after sending the 'shutdown' request to the server. +--- exit cleanly after sending the "shutdown" request before sending kill -15. +--- If set to false, nvim exits immediately after sending the "shutdown" request to the server. --- ---@param root_dir string Directory where the LSP --- server will base its workspaceFolders, rootUri, and rootPath @@ -1078,7 +1078,7 @@ function lsp.start_client(config) --- ---@param code (number) Error code ---@param err (...) Other arguments may be passed depending on the error kind - ---@see |vim.lsp.rpc.client_errors| for possible errors. Use + ---@see `vim.lsp.rpc.client_errors` for possible errors. Use ---`vim.lsp.rpc.client_errors[code]` to get a human-friendly name. function dispatch.on_error(code, err) local _ = log.error() -- cgit From b075f49d9229b3e58a4d6677ed8e01db60687fa3 Mon Sep 17 00:00:00 2001 From: August Masquelier <31262046+levouh@users.noreply.github.com> Date: Tue, 4 Oct 2022 12:44:19 -0600 Subject: feat(lsp): add bufnr option to lsp.start (#20473) --- runtime/lua/vim/lsp.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'runtime/lua/vim/lsp.lua') diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index a64facf214..349c662258 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -860,6 +860,9 @@ end --- Used on all running clients. --- The default implementation re-uses a client if name --- and root_dir matches. +--- - bufnr (number) +--- Buffer handle to attach to if starting or re-using a +--- client (0 for current). ---@return number|nil client_id function lsp.start(config, opts) opts = opts or {} @@ -871,7 +874,10 @@ function lsp.start(config, opts) if not config.name and type(config.cmd) == 'table' then config.name = config.cmd[1] and vim.fs.basename(config.cmd[1]) or nil end - local bufnr = api.nvim_get_current_buf() + local bufnr = opts.bufnr + if bufnr == nil or bufnr == 0 then + bufnr = api.nvim_get_current_buf() + end for _, clients in ipairs({ uninitialized_clients, lsp.get_active_clients() }) do for _, client in pairs(clients) do if reuse_client(client, config) then -- cgit From 8c2226fc30931690186390d86f963cd43e6947ef Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Sun, 9 Oct 2022 12:40:56 +0200 Subject: fix(lua): properly configure luacheck and remove `local vim = ...` lines (#20551) --- runtime/lua/vim/lsp.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'runtime/lua/vim/lsp.lua') diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 349c662258..199964e24e 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -5,7 +5,6 @@ local protocol = require('vim.lsp.protocol') local util = require('vim.lsp.util') local sync = require('vim.lsp.sync') -local vim = vim local api = vim.api local nvim_err_writeln, nvim_buf_get_lines, nvim_command, nvim_buf_get_option, nvim_exec_autocmds = api.nvim_err_writeln, -- cgit From e5cb3104d07228de4f2614c425355e8f2f99507d Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 14 Oct 2022 11:01:13 -0400 Subject: docs: fix/remove invalid URLs #20647 --- runtime/lua/vim/lsp.lua | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) (limited to 'runtime/lua/vim/lsp.lua') diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 199964e24e..d717275ae4 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -824,23 +824,16 @@ end --- --- See |vim.lsp.start_client()| for all available options. The most important are: --- ---- `name` is an arbitrary name for the LSP client. It should be unique per ---- language server. ---- ---- `cmd` the command as list - used to start the language server. ---- The command must be present in the `$PATH` environment variable or an ---- absolute path to the executable. Shell constructs like `~` are *NOT* expanded. ---- ---- `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.find()| 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. ---- ---- `workspace_folders` a list of { uri:string, name: string } tables. ---- The project root folders used by the language server. ---- If `nil` the property is derived from the `root_dir` for convenience. +--- - `name` arbitrary name for the LSP client. Should be unique per language server. +--- - `cmd` command (in list form) used to start the language server. Must be absolute, or found on +--- `$PATH`. Shell constructs like `~` are not expanded. +--- - `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.find()| 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. +--- - `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. --- --- Language servers use this information to discover metadata like the --- dependencies of your project and they tend to index the contents within the -- cgit From 0b05bd87c04f9cde5c84a062453619349e370795 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Wed, 23 Nov 2022 12:31:49 +0100 Subject: docs(gen): support language annotation in docstrings --- runtime/lua/vim/lsp.lua | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'runtime/lua/vim/lsp.lua') diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index d717275ae4..5bbe4aeba9 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -813,8 +813,7 @@ end --- Attaches the current buffer to the client. --- --- Example: ---- ----
+--- 
lua
 --- vim.lsp.start({
 ---    name = 'my-server-name',
 ---    cmd = {'name-of-language-server-executable'},
@@ -1754,8 +1753,7 @@ end
 ---
 --- You can also use the `stop()` function on a |vim.lsp.client| object.
 --- To stop all clients:
----
---- 
+--- 
lua
 --- vim.lsp.stop_client(vim.lsp.get_active_clients())
 --- 
--- @@ -2239,7 +2237,7 @@ end ---@param fn function Function to run on each client attached to buffer --- {bufnr}. The function takes the client, client ID, and --- buffer number as arguments. Example: ----
+---             
lua
 ---               vim.lsp.for_each_buffer_client(0, function(client, client_id, bufnr)
 ---                 print(vim.inspect(client))
 ---               end)
-- 
cgit 


From 01a8cd0432a272c41e882af96ee8488a4105bd32 Mon Sep 17 00:00:00 2001
From: Raphael 
Date: Sun, 4 Dec 2022 21:56:04 +0800
Subject: fix(lsp): remove workspaceFolders field (#21284)

---
 runtime/lua/vim/lsp.lua | 2 --
 1 file changed, 2 deletions(-)

(limited to 'runtime/lua/vim/lsp.lua')

diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 5bbe4aeba9..9595f0b12c 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -1285,8 +1285,6 @@ function lsp.start_client(config)
       client.initialized = true
       uninitialized_clients[client_id] = nil
       client.workspace_folders = workspace_folders
-      -- TODO(mjlbach): Backwards compatibility, to be removed in 0.7
-      client.workspaceFolders = client.workspace_folders
 
       -- These are the cleaned up capabilities we use for dynamically deciding
       -- when to send certain events to clients.
-- 
cgit 


From 54305443b9cd5ac2c2220f12e01a653e8064c3a4 Mon Sep 17 00:00:00 2001
From: Mathias Fußenegger 
Date: Thu, 8 Dec 2022 10:55:01 +0100
Subject: feat(lsp): support willSave & willSaveWaitUntil capability (#21315)

`willSaveWaitUntil` allows servers to respond with text edits before
saving a document. That is used by some language servers to format a
document or apply quick fixes like removing unused imports.
---
 runtime/lua/vim/lsp.lua | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

(limited to 'runtime/lua/vim/lsp.lua')

diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 9595f0b12c..9c42e9df52 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -1611,9 +1611,37 @@ function lsp.buf_attach_client(bufnr, client_id)
     all_buffer_active_clients[bufnr] = buffer_client_ids
 
     local uri = vim.uri_from_bufnr(bufnr)
-    local augroup = ('lsp_c_%d_b_%d_did_save'):format(client_id, bufnr)
+    local augroup = ('lsp_c_%d_b_%d_save'):format(client_id, bufnr)
+    local group = api.nvim_create_augroup(augroup, { clear = true })
+    api.nvim_create_autocmd('BufWritePre', {
+      group = group,
+      buffer = bufnr,
+      desc = 'vim.lsp: textDocument/willSave',
+      callback = function(ctx)
+        for_each_buffer_client(ctx.buf, function(client)
+          local params = {
+            textDocument = {
+              uri = uri,
+            },
+            reason = protocol.TextDocumentSaveReason.Manual,
+          }
+          if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'willSave') then
+            client.notify('textDocument/willSave', params)
+          end
+          if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'willSaveWaitUntil') then
+            local result, err =
+              client.request_sync('textDocument/willSaveWaitUntil', params, 1000, ctx.buf)
+            if result and result.result then
+              util.apply_text_edits(result.result, ctx.buf, client.offset_encoding)
+            elseif err then
+              log.error(vim.inspect(err))
+            end
+          end
+        end)
+      end,
+    })
     api.nvim_create_autocmd('BufWritePost', {
-      group = api.nvim_create_augroup(augroup, { clear = true }),
+      group = group,
       buffer = bufnr,
       desc = 'vim.lsp: textDocument/didSave handler',
       callback = function(ctx)
-- 
cgit 


From 9f035559defd9d575f37fd825954610065d9cf96 Mon Sep 17 00:00:00 2001
From: John Drouhard 
Date: Wed, 23 Nov 2022 10:06:36 -0600
Subject: feat(lsp): initial support for semantic token highlighting

* credit to @smolck and @theHamsta for their contributions in laying the
  groundwork for this feature and for their work on some of the helper
  utility functions and tests
---
 runtime/lua/vim/lsp.lua | 9 +++++++++
 1 file changed, 9 insertions(+)

(limited to 'runtime/lua/vim/lsp.lua')

diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 9c42e9df52..3d3c856fcb 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -4,6 +4,7 @@ local lsp_rpc = require('vim.lsp.rpc')
 local protocol = require('vim.lsp.protocol')
 local util = require('vim.lsp.util')
 local sync = require('vim.lsp.sync')
+local semantic_tokens = require('vim.lsp.semantic_tokens')
 
 local api = vim.api
 local nvim_err_writeln, nvim_buf_get_lines, nvim_command, nvim_buf_get_option, nvim_exec_autocmds =
@@ -25,6 +26,7 @@ local lsp = {
   buf = require('vim.lsp.buf'),
   diagnostic = require('vim.lsp.diagnostic'),
   codelens = require('vim.lsp.codelens'),
+  semantic_tokens = semantic_tokens,
   util = util,
 
   -- Allow raw RPC access.
@@ -56,6 +58,8 @@ lsp._request_name_to_capability = {
   ['textDocument/formatting'] = { 'documentFormattingProvider' },
   ['textDocument/completion'] = { 'completionProvider' },
   ['textDocument/documentHighlight'] = { 'documentHighlightProvider' },
+  ['textDocument/semanticTokens/full'] = { 'semanticTokensProvider' },
+  ['textDocument/semanticTokens/full/delta'] = { 'semanticTokensProvider' },
 }
 
 -- TODO improve handling of scratch buffers with LSP attached.
@@ -1526,6 +1530,11 @@ function lsp.start_client(config)
       -- TODO(ashkan) handle errors.
       pcall(config.on_attach, client, bufnr)
     end
+
+    if vim.tbl_get(client.server_capabilities, 'semanticTokensProvider', 'full') then
+      semantic_tokens.start(bufnr, client.id)
+    end
+
     client.attached_buffers[bufnr] = true
   end
 
-- 
cgit 


From 5e6a288ce7ee079e7695525f2e9e99d071ccdfbf Mon Sep 17 00:00:00 2001
From: jdrouhard 
Date: Fri, 9 Dec 2022 04:54:09 -0600
Subject: fix(lsp): followup fixes for semantic tokens support (#21357)

1. The algorithm for applying edits was slightly incorrect. It needs to
   preserve the original token list as the edits are applied instead of
   mutating it as it iterates. From the spec:

   Semantic token edits behave conceptually like text edits on
   documents: if an edit description consists of n edits all n edits are
   based on the same state Sm of the number array. They will move the
   number array from state Sm to Sm+1.

2. Schedule the semantic token engine start() call in the
   client._on_attach() function so that users who schedule_wrap() their
   config.on_attach() functions (like nvim-lspconfig does) can still
   disable semantic tokens by deleting the semanticTokensProvider from
   their server capabilities.
---
 runtime/lua/vim/lsp.lua | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

(limited to 'runtime/lua/vim/lsp.lua')

diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 3d3c856fcb..f3ee484024 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -1531,9 +1531,14 @@ function lsp.start_client(config)
       pcall(config.on_attach, client, bufnr)
     end
 
-    if vim.tbl_get(client.server_capabilities, 'semanticTokensProvider', 'full') then
-      semantic_tokens.start(bufnr, client.id)
-    end
+    -- schedule the initialization of semantic tokens to give the above
+    -- on_attach and LspAttach callbacks the ability to schedule wrap the
+    -- opt-out (deleting the semanticTokensProvider from capabilities)
+    vim.schedule(function()
+      if vim.tbl_get(client.server_capabilities, 'semanticTokensProvider', 'full') then
+        semantic_tokens.start(bufnr, client.id)
+      end
+    end)
 
     client.attached_buffers[bufnr] = true
   end
-- 
cgit 


From 49df92da9459bea9eec356d23cea20a0a2383d68 Mon Sep 17 00:00:00 2001
From: Mathias Fußenegger 
Date: Fri, 9 Dec 2022 19:18:31 +0100
Subject: fix(lsp): correct some type annotations (#21365)

---
 runtime/lua/vim/lsp.lua | 66 ++++++++++++++++++++++++++++---------------------
 1 file changed, 38 insertions(+), 28 deletions(-)

(limited to 'runtime/lua/vim/lsp.lua')

diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index f3ee484024..dc5008399e 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -67,7 +67,7 @@ lsp._request_name_to_capability = {
 ---@private
 --- Concatenates and writes a list of strings to the Vim error buffer.
 ---
----@param {...} (List of strings) List to write to the buffer
+---@param {...} table[] List to write to the buffer
 local function err_message(...)
   nvim_err_writeln(table.concat(vim.tbl_flatten({ ... })))
   nvim_command('redraw')
@@ -76,7 +76,7 @@ end
 ---@private
 --- Returns the buffer number for the given {bufnr}.
 ---
----@param bufnr (number) Buffer number to resolve. Defaults to the current
+---@param bufnr (number|nil) Buffer number to resolve. Defaults to the current
 ---buffer if not given.
 ---@returns bufnr (number) Number of requested buffer
 local function resolve_bufnr(bufnr)
@@ -244,9 +244,9 @@ end
 ---@private
 --- Augments a validator function with support for optional (nil) values.
 ---
----@param fn (function(v)) The original validator function; should return a
+---@param fn (fun(v)) The original validator function; should return a
 ---bool.
----@returns (function(v)) The augmented function. Also returns true if {v} is
+---@returns (fun(v)) The augmented function. Also returns true if {v} is
 ---`nil`.
 local function optional_validator(fn)
   return function(v)
@@ -1366,7 +1366,7 @@ function lsp.start_client(config)
   ---
   ---@param method (string) LSP method name.
   ---@param params (table) LSP request params.
-  ---@param handler (function, optional) Response |lsp-handler| for this method.
+  ---@param handler (function|nil) Response |lsp-handler| for this method.
   ---@param bufnr (number) Buffer handle (0 for current).
   ---@returns ({status}, [request_id]): {status} is a bool indicating
   ---whether the request was successful. If it is `false`, then it will
@@ -1377,8 +1377,10 @@ function lsp.start_client(config)
   ---@see |vim.lsp.buf_request()|
   function client.request(method, params, handler, bufnr)
     if not handler then
-      handler = resolve_handler(method)
-        or error(string.format('not found: %q request handler for client %q.', method, client.name))
+      handler = assert(
+        resolve_handler(method),
+        string.format('not found: %q request handler for client %q.', method, client.name)
+      )
     end
     -- Ensure pending didChange notifications are sent so that the server doesn't operate on a stale state
     changetracking.flush(client, bufnr)
@@ -1396,7 +1398,7 @@ function lsp.start_client(config)
       nvim_exec_autocmds('User', { pattern = 'LspRequest', modeline = false })
     end)
 
-    if success then
+    if success and request_id then
       client.requests[request_id] = { type = 'pending', bufnr = bufnr, method = method }
       nvim_exec_autocmds('User', { pattern = 'LspRequest', modeline = false })
     end
@@ -1411,8 +1413,8 @@ function lsp.start_client(config)
   ---
   ---@param method (string) LSP method name.
   ---@param params (table) LSP request params.
-  ---@param timeout_ms (number, optional, default=1000) Maximum time in
-  ---milliseconds to wait for a result.
+  ---@param timeout_ms (number|nil) Maximum time in milliseconds to wait for
+  ---                               a result. Defaults to 1000
   ---@param bufnr (number) Buffer handle (0 for current).
   ---@returns { err=err, result=result }, a dictionary, where `err` and `result` come from the |lsp-handler|.
   ---On timeout, cancel or error, returns `(nil, err)` where `err` is a
@@ -1435,7 +1437,9 @@ function lsp.start_client(config)
     end, 10)
 
     if not wait_result then
-      client.cancel_request(request_id)
+      if request_id then
+        client.cancel_request(request_id)
+      end
       return nil, wait_result_reason[reason]
     end
     return request_result
@@ -1800,7 +1804,7 @@ end
 --- By default asks the server to shutdown, unless stop was requested
 --- already for this client, then force-shutdown is attempted.
 ---
----@param client_id client id or |vim.lsp.client| object, or list thereof
+---@param client_id number|table id or |vim.lsp.client| object, or list thereof
 ---@param force boolean (optional) shutdown forcefully
 function lsp.stop_client(client_id, force)
   local ids = type(client_id) == 'table' and client_id or { client_id }
@@ -1815,10 +1819,16 @@ function lsp.stop_client(client_id, force)
   end
 end
 
+---@class vim.lsp.get_active_clients.filter
+---@field id number|nil Match clients by id
+---@field bufnr number|nil match clients attached to the given buffer
+---@field name number|nil match clients by name
+
 --- Get active clients.
 ---
----@param filter (table|nil) A table with key-value pairs used to filter the
----              returned clients. The available keys are:
+---@param filter vim.lsp.get_active_clients.filter|nil (table|nil) A table with
+---              key-value pairs used to filter the returned clients.
+---              The available keys are:
 ---               - id (number): Only return clients with the given id
 ---               - bufnr (number): Only return clients attached to this buffer
 ---               - name (string): Only return clients with the given name
@@ -1966,7 +1976,7 @@ end
 ---
 ---@param bufnr (number) Buffer handle, or 0 for current.
 ---@param method (string) LSP method name
----@param params (optional, table) Parameters to send to the server
+---@param params (table|nil) Parameters to send to the server
 ---@param callback (function) The callback to call when all requests are finished.
 --  Unlike `buf_request`, this will collect all the responses from each server instead of handling them.
 --  A map of client_id:request_result will be provided to the callback
@@ -2008,9 +2018,9 @@ end
 ---
 ---@param bufnr (number) Buffer handle, or 0 for current.
 ---@param method (string) LSP method name
----@param params (optional, table) Parameters to send to the server
----@param timeout_ms (optional, number, default=1000) Maximum time in
----      milliseconds to wait for a result.
+---@param params (table|nil) Parameters to send to the server
+---@param timeout_ms (number|nil) Maximum time in milliseconds to wait for a
+---                               result. Defaults to 1000
 ---
 ---@returns Map of client_id:request_result. On timeout, cancel or error,
 ---        returns `(nil, err)` where `err` is a string describing the failure
@@ -2035,9 +2045,9 @@ function lsp.buf_request_sync(bufnr, method, params, timeout_ms)
 end
 
 --- Send a notification to a server
----@param bufnr [number] (optional): The number of the buffer
----@param method [string]: Name of the request method
----@param params [string]: Arguments to send to the server
+---@param bufnr (number|nil) The number of the buffer
+---@param method (string) Name of the request method
+---@param params (string) Arguments to send to the server
 ---
 ---@returns true if any client returns true; false otherwise
 function lsp.buf_notify(bufnr, method, params)
@@ -2078,8 +2088,8 @@ end
 ---@see |complete-items|
 ---@see |CompleteDone|
 ---
----@param findstart 0 or 1, decides behavior
----@param base If findstart=0, text to match against
+---@param findstart number 0 or 1, decides behavior
+---@param base number findstart=0, text to match against
 ---
 ---@returns (number) Decided by {findstart}:
 --- - findstart=0: column where the completion starts, or -2 or -3
@@ -2208,8 +2218,8 @@ end
 --- Otherwise, uses "workspace/symbol". If no results are returned from
 --- any LSP servers, falls back to using built-in tags.
 ---
----@param pattern Pattern used to find a workspace symbol
----@param flags See |tag-function|
+---@param pattern string Pattern used to find a workspace symbol
+---@param flags string See |tag-function|
 ---
 ---@returns A list of matching tags
 function lsp.tagfunc(...)
@@ -2218,7 +2228,7 @@ end
 
 ---Checks whether a client is stopped.
 ---
----@param client_id (Number)
+---@param client_id (number)
 ---@returns true if client is stopped, false otherwise.
 function lsp.client_is_stopped(client_id)
   return active_clients[client_id] == nil
@@ -2227,7 +2237,7 @@ end
 --- Gets a map of client_id:client pairs for the given buffer, where each value
 --- is a |vim.lsp.client| object.
 ---
----@param bufnr (optional, number): Buffer handle, or 0 for current
+---@param bufnr (number|nil): Buffer handle, or 0 for current
 ---@returns (table) Table of (client_id, client) pairs
 ---@deprecated Use |vim.lsp.get_active_clients()| instead.
 function lsp.buf_get_clients(bufnr)
@@ -2256,7 +2266,7 @@ lsp.log_levels = log.levels
 ---
 ---@see |vim.lsp.log_levels|
 ---
----@param level [number|string] the case insensitive level name or number
+---@param level (number|string) the case insensitive level name or number
 function lsp.set_log_level(level)
   if type(level) == 'string' or type(level) == 'number' then
     log.set_level(level)
-- 
cgit 


From f62c30ad0d53fe79bbb00087609d76101371d122 Mon Sep 17 00:00:00 2001
From: Raphael 
Date: Fri, 30 Dec 2022 23:42:18 +0800
Subject: fix(lsp): fix nil client access in get_active_clients (#21524)

Fixes https://github.com/neovim/neovim/issues/21523
---
 runtime/lua/vim/lsp.lua | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'runtime/lua/vim/lsp.lua')

diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index dc5008399e..ad0e599f61 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -1845,7 +1845,8 @@ function lsp.get_active_clients(filter)
   for client_id in pairs(t) do
     local client = active_clients[client_id]
     if
-      (filter.id == nil or client.id == filter.id)
+      client
+      and (filter.id == nil or client.id == filter.id)
       and (filter.name == nil or client.name == filter.name)
     then
       clients[#clients + 1] = client
-- 
cgit 


From 5b22b32e50858b781eb2658ba099eaffaa5ea13b Mon Sep 17 00:00:00 2001
From: Christian Segundo 
Date: Tue, 3 Jan 2023 13:44:44 +0100
Subject: fix(lsp): change vim.lsp.get_active_clients.filter name annotation to
 string (#21624)

---
 runtime/lua/vim/lsp.lua | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'runtime/lua/vim/lsp.lua')

diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index ad0e599f61..1d99283dd9 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -1822,7 +1822,7 @@ end
 ---@class vim.lsp.get_active_clients.filter
 ---@field id number|nil Match clients by id
 ---@field bufnr number|nil match clients attached to the given buffer
----@field name number|nil match clients by name
+---@field name string|nil match clients by name
 
 --- Get active clients.
 ---
-- 
cgit 


From e35b9020b16985eee26e942f9a3f6b045bc3809b Mon Sep 17 00:00:00 2001
From: notomo 
Date: Wed, 4 Jan 2023 20:48:41 +0900
Subject: docs(lua): adjust some type annotations

---
 runtime/lua/vim/lsp.lua | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'runtime/lua/vim/lsp.lua')

diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 1d99283dd9..13f8c81dfb 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -1805,7 +1805,7 @@ end
 --- already for this client, then force-shutdown is attempted.
 ---
 ---@param client_id number|table id or |vim.lsp.client| object, or list thereof
----@param force boolean (optional) shutdown forcefully
+---@param force boolean|nil shutdown forcefully
 function lsp.stop_client(client_id, force)
   local ids = type(client_id) == 'table' and client_id or { client_id }
   for _, id in ipairs(ids) do
-- 
cgit 


From a37c686d21c1ad4e50f455e989642d38435d41ba Mon Sep 17 00:00:00 2001
From: Chris Kipp 
Date: Wed, 11 Jan 2023 20:17:10 +0100
Subject: docs(lsp): update buf_notify and rpc.notify params types (#21753)

Small, but I was getting warnings about my usage of
`vim.lsp.buf_notify(bufnr, method, {example = example})` since the docs
say that `params` must be a string, however this can really be anything
when it's passed to `rpc.notify` since we just end up calling
`vim.json.encode(payload)` on it. This fixes the docs in those two
places and regenerates them.
---
 runtime/lua/vim/lsp.lua | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'runtime/lua/vim/lsp.lua')

diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 13f8c81dfb..cfd6c938f7 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -2048,7 +2048,7 @@ end
 --- Send a notification to a server
 ---@param bufnr (number|nil) The number of the buffer
 ---@param method (string) Name of the request method
----@param params (string) Arguments to send to the server
+---@param params (any) Arguments to send to the server
 ---
 ---@returns true if any client returns true; false otherwise
 function lsp.buf_notify(bufnr, method, params)
-- 
cgit