From f03b1622ad1b8e2df16504631f05e7577e217854 Mon Sep 17 00:00:00 2001 From: Mathias Fußenegger Date: Sat, 25 May 2024 21:22:41 +0200 Subject: fix(lsp): handle nil root_dir in health check (#29007) The root directory could show up as something like: Root directory: ~/path/to/cwd/v:null Despite being `nil` --- runtime/lua/vim/lsp/client.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'runtime/lua/vim/lsp/client.lua') diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index 4beb7fefda..58ea7d02b3 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -182,7 +182,7 @@ local validate = vim.validate --- It can be `null` if the client supports workspace folders but none are --- configured. --- @field workspace_folders lsp.WorkspaceFolder[]? ---- @field root_dir string +--- @field root_dir string? --- --- @field attached_buffers table --- @@ -470,7 +470,6 @@ function Client.create(config) _on_exit_cbs = ensure_list(config.on_exit), _on_attach_cbs = ensure_list(config.on_attach), _on_error_cb = config.on_error, - _root_dir = config.root_dir, _trace = get_trace(config.trace), --- Contains $/progress report messages. -- cgit From ff097f2091e7a970e5b12960683b4dade5563040 Mon Sep 17 00:00:00 2001 From: Maria José Solano Date: Sun, 4 Feb 2024 14:13:23 -0800 Subject: feat(lsp): completion side effects --- runtime/lua/vim/lsp/client.lua | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'runtime/lua/vim/lsp/client.lua') diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index 4beb7fefda..c8616bf728 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -869,7 +869,8 @@ end --- @param command lsp.Command --- @param context? {bufnr: integer} --- @param handler? lsp.Handler only called if a server command -function Client:_exec_cmd(command, context, handler) +--- @param on_unsupported? function handler invoked when the command is not supported by the client. +function Client:_exec_cmd(command, context, handler, on_unsupported) context = vim.deepcopy(context or {}, true) --[[@as lsp.HandlerContext]] context.bufnr = context.bufnr or api.nvim_get_current_buf() context.client_id = self.id @@ -883,14 +884,18 @@ function Client:_exec_cmd(command, context, handler) local command_provider = self.server_capabilities.executeCommandProvider local commands = type(command_provider) == 'table' and command_provider.commands or {} if not vim.list_contains(commands, cmdname) then - vim.notify_once( - string.format( - 'Language server `%s` does not support command `%s`. This command may require a client extension.', - self.name, - cmdname - ), - vim.log.levels.WARN - ) + if on_unsupported then + on_unsupported() + else + vim.notify_once( + string.format( + 'Language server `%s` does not support command `%s`. This command may require a client extension.', + self.name, + cmdname + ), + vim.log.levels.WARN + ) + end return end -- Not using command directly to exclude extra properties, -- cgit From 5c33815448e11b514678f39cecc74e68131d4628 Mon Sep 17 00:00:00 2001 From: Mathias Fußenegger Date: Thu, 30 May 2024 10:46:26 +0200 Subject: refactor(lsp): replace util.buf_versions with changedtick (#28943) `lsp.util.buf_versions` was already derived from changedtick (`on_lines` from `buf_attach` synced the version) As far as I can tell there is no need to keep track of the state in a separate table. --- runtime/lua/vim/lsp/client.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'runtime/lua/vim/lsp/client.lua') diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index 327cd19125..b28fe2f797 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -673,8 +673,8 @@ function Client:_request(method, params, handler, bufnr) end -- Ensure pending didChange notifications are sent so that the server doesn't operate on a stale state changetracking.flush(self, bufnr) - local version = lsp.util.buf_versions[bufnr] bufnr = resolve_bufnr(bufnr) + local version = vim.b[bufnr].changedtick log.debug(self._log_prefix, 'client.request', self.id, method, params, handler, bufnr) local success, request_id = self.rpc.request(method, params, function(err, result) local context = { @@ -922,14 +922,13 @@ function Client:_text_document_did_open_handler(bufnr) local params = { textDocument = { - version = 0, + version = vim.b[bufnr].changedtick, uri = vim.uri_from_bufnr(bufnr), languageId = self.get_language_id(bufnr, filetype), text = lsp._buf_get_full_text(bufnr), }, } self.notify(ms.textDocument_didOpen, params) - lsp.util.buf_versions[bufnr] = params.textDocument.version -- Next chance we get, we should re-do the diagnostics vim.schedule(function() -- cgit From 6e45cd7f0026ee33b8c397b810dcfe5b4678bbd8 Mon Sep 17 00:00:00 2001 From: Mathias Fußenegger Date: Fri, 7 Jun 2024 11:36:46 +0200 Subject: fix(lsp): revert buf_versions deprecation/replacement (#29217) * Revert "fix(lsp): account for changedtick version gap on modified reset (#29170)" This reverts commit 2e6d295f799c27372e5c0c44727fa613c81717fd. * Revert "refactor(lsp): replace util.buf_versions with changedtick (#28943)" This reverts commit 5c33815448e11b514678f39cecc74e68131d4628. --- runtime/lua/vim/lsp/client.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim/lsp/client.lua') diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index b28fe2f797..327cd19125 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -673,8 +673,8 @@ function Client:_request(method, params, handler, bufnr) end -- Ensure pending didChange notifications are sent so that the server doesn't operate on a stale state changetracking.flush(self, bufnr) + local version = lsp.util.buf_versions[bufnr] bufnr = resolve_bufnr(bufnr) - local version = vim.b[bufnr].changedtick log.debug(self._log_prefix, 'client.request', self.id, method, params, handler, bufnr) local success, request_id = self.rpc.request(method, params, function(err, result) local context = { @@ -922,13 +922,14 @@ function Client:_text_document_did_open_handler(bufnr) local params = { textDocument = { - version = vim.b[bufnr].changedtick, + version = 0, uri = vim.uri_from_bufnr(bufnr), languageId = self.get_language_id(bufnr, filetype), text = lsp._buf_get_full_text(bufnr), }, } self.notify(ms.textDocument_didOpen, params) + lsp.util.buf_versions[bufnr] = params.textDocument.version -- Next chance we get, we should re-do the diagnostics vim.schedule(function() -- cgit From 5e49ef0af3cb8dba658e5d0dc6a807f8edebf590 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Tue, 11 Jun 2024 12:05:18 +0100 Subject: refactor(lua): improve type annotations --- runtime/lua/vim/lsp/client.lua | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'runtime/lua/vim/lsp/client.lua') diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index 327cd19125..d3ff918792 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -436,7 +436,7 @@ local function ensure_list(x) return { x } end ---- @package +--- @nodoc --- @param config vim.lsp.ClientConfig --- @return vim.lsp.Client? function Client.create(config) @@ -535,7 +535,7 @@ function Client:_run_callbacks(cbs, error_id, ...) end end ---- @package +--- @nodoc function Client:initialize() local config = self.config @@ -656,7 +656,7 @@ end --- @param method string LSP method name. --- @param params? table LSP request params. --- @param handler? lsp.Handler Response |lsp-handler| for this method. ---- @param bufnr? integer Buffer handle (0 for current). +--- @param bufnr integer Buffer handle (0 for current). --- @return boolean status, integer? request_id {status} is a bool indicating --- whether the request was successful. If it is `false`, then it will --- always be `false` (the client has shutdown). If it was @@ -861,7 +861,6 @@ function Client:_is_stopped() return self.rpc.is_closing() end ---- @package --- Execute a lsp command, either via client command function (if available) --- or via workspace/executeCommand (if supported by the server) --- @@ -906,7 +905,6 @@ function Client:_exec_cmd(command, context, handler, on_unsupported) self.request(ms.workspace_executeCommand, params, handler, context.bufnr) end ---- @package --- Default handler for the 'textDocument/didOpen' LSP notification. --- --- @param bufnr integer Number of the buffer, or 0 for current @@ -942,7 +940,6 @@ function Client:_text_document_did_open_handler(bufnr) end) end ---- @package --- Runs the on_attach function from the client's config if it was defined. --- @param bufnr integer Buffer number function Client:_on_attach(bufnr) @@ -1065,7 +1062,6 @@ function Client:_on_exit(code, signal) ) end ---- @package --- Add a directory to the workspace folders. --- @param dir string? function Client:_add_workspace_folder(dir) @@ -1088,7 +1084,6 @@ function Client:_add_workspace_folder(dir) vim.list_extend(self.workspace_folders, wf) end ---- @package --- Remove a directory to the workspace folders. --- @param dir string? function Client:_remove_workspace_folder(dir) -- cgit From 0a9c81d70964f905112857900fbaa6aae590a96d Mon Sep 17 00:00:00 2001 From: Ilia Choly Date: Fri, 14 Jun 2024 05:03:58 -0400 Subject: refactor(lsp): use metatable for buf_versions (#29304) This reduces the number of nil checks around buf_versions usage Test changes were lifted from 5c33815 Co-authored-by: Mathias Fussenegger --- runtime/lua/vim/lsp/client.lua | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'runtime/lua/vim/lsp/client.lua') diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index d3ff918792..8cdfdd4b90 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -916,18 +916,16 @@ function Client:_text_document_did_open_handler(bufnr) if not api.nvim_buf_is_loaded(bufnr) then return end - local filetype = vim.bo[bufnr].filetype - local params = { + local filetype = vim.bo[bufnr].filetype + self.notify(ms.textDocument_didOpen, { textDocument = { - version = 0, + version = lsp.util.buf_versions[bufnr], uri = vim.uri_from_bufnr(bufnr), languageId = self.get_language_id(bufnr, filetype), text = lsp._buf_get_full_text(bufnr), }, - } - self.notify(ms.textDocument_didOpen, params) - lsp.util.buf_versions[bufnr] = params.textDocument.version + }) -- Next chance we get, we should re-do the diagnostics vim.schedule(function() -- cgit From 737f58e23230ea14f1648ac1fc7f442ea0f8563c Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 20 Sep 2024 07:34:50 +0200 Subject: refactor(api)!: rename Dictionary => Dict In the api_info() output: :new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val') ... {'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1} The `ArrayOf(Integer, 2)` return type didn't break clients when we added it, which is evidence that clients don't use the `return_type` field, thus renaming Dictionary => Dict in api_info() is not (in practice) a breaking change. --- runtime/lua/vim/lsp/client.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'runtime/lua/vim/lsp/client.lua') diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index 8cdfdd4b90..e3c82f4169 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -233,11 +233,11 @@ local validate = vim.validate --- --- Sends a request to the server and synchronously waits for the response. --- This is a wrapper around {client.request} ---- Returns: { err=err, result=result }, a dictionary, where `err` and `result` +--- Returns: { err=err, result=result }, a dict, where `err` and `result` --- come from the |lsp-handler|. On timeout, cancel or error, returns `(nil, --- err)` where `err` is a string describing the failure reason. If the request --- was unsuccessful returns `nil`. ---- @field request_sync fun(method: string, params: table?, timeout_ms: integer?, bufnr: integer): {err: lsp.ResponseError|nil, result:any}|nil, string|nil err # a dictionary, where +--- @field request_sync fun(method: string, params: table?, timeout_ms: integer?, bufnr: integer): {err: lsp.ResponseError|nil, result:any}|nil, string|nil err # a dict --- --- Sends a notification to an LSP server. --- Returns: a boolean to indicate if the notification was successful. If @@ -738,7 +738,7 @@ end --- @param timeout_ms (integer|nil) Maximum time in milliseconds to wait for --- a result. Defaults to 1000 --- @param bufnr (integer) Buffer handle (0 for current). ---- @return {err: lsp.ResponseError|nil, result:any}|nil, string|nil err # a dictionary, where +--- @return {err: lsp.ResponseError|nil, result:any}|nil, string|nil err # a dict, where --- `err` and `result` come from the |lsp-handler|. --- On timeout, cancel or error, returns `(nil, err)` where `err` is a --- string describing the failure reason. If the request was unsuccessful -- cgit