From 5732aa706c639b3d775573d91d1139f24624629c Mon Sep 17 00:00:00 2001 From: Jon Huhn Date: Sat, 25 Feb 2023 03:07:18 -0600 Subject: feat(lsp): implement workspace/didChangeWatchedFiles (#21293) --- runtime/lua/vim/lsp/handlers.lua | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 5096100a60..ee5b63d260 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -117,15 +117,35 @@ M['window/showMessageRequest'] = function(_, result) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#client_registerCapability -M['client/registerCapability'] = function(_, _, ctx) - local client_id = ctx.client_id - local warning_tpl = 'The language server %s triggers a registerCapability ' - .. 'handler despite dynamicRegistration set to false. ' - .. 'Report upstream, this warning is harmless' - local client = vim.lsp.get_client_by_id(client_id) - local client_name = client and client.name or string.format('id=%d', client_id) - local warning = string.format(warning_tpl, client_name) - log.warn(warning) +M['client/registerCapability'] = function(_, result, ctx) + local log_unsupported = false + for _, reg in ipairs(result.registrations) do + if reg.method == 'workspace/didChangeWatchedFiles' then + require('vim.lsp._watchfiles').register(reg, ctx) + else + log_unsupported = true + end + end + if log_unsupported then + local client_id = ctx.client_id + local warning_tpl = 'The language server %s triggers a registerCapability ' + .. 'handler despite dynamicRegistration set to false. ' + .. 'Report upstream, this warning is harmless' + local client = vim.lsp.get_client_by_id(client_id) + local client_name = client and client.name or string.format('id=%d', client_id) + local warning = string.format(warning_tpl, client_name) + log.warn(warning) + end + return vim.NIL +end + +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#client_unregisterCapability +M['client/unregisterCapability'] = function(_, result, ctx) + for _, unreg in ipairs(result.unregisterations) do + if unreg.method == 'workspace/didChangeWatchedFiles' then + require('vim.lsp._watchfiles').unregister(unreg, ctx) + end + end return vim.NIL end -- cgit From f0f27e9aef7c237dd55fbb5c2cd47c2f42d01742 Mon Sep 17 00:00:00 2001 From: Mathias Fussenegger Date: Sat, 25 Feb 2023 11:17:28 +0100 Subject: Revert "feat(lsp): implement workspace/didChangeWatchedFiles (#21293)" This reverts commit 5732aa706c639b3d775573d91d1139f24624629c. Causes editor to freeze in projects with many watcher registrations --- runtime/lua/vim/lsp/handlers.lua | 38 +++++++++----------------------------- 1 file changed, 9 insertions(+), 29 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index ee5b63d260..5096100a60 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -117,35 +117,15 @@ M['window/showMessageRequest'] = function(_, result) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#client_registerCapability -M['client/registerCapability'] = function(_, result, ctx) - local log_unsupported = false - for _, reg in ipairs(result.registrations) do - if reg.method == 'workspace/didChangeWatchedFiles' then - require('vim.lsp._watchfiles').register(reg, ctx) - else - log_unsupported = true - end - end - if log_unsupported then - local client_id = ctx.client_id - local warning_tpl = 'The language server %s triggers a registerCapability ' - .. 'handler despite dynamicRegistration set to false. ' - .. 'Report upstream, this warning is harmless' - local client = vim.lsp.get_client_by_id(client_id) - local client_name = client and client.name or string.format('id=%d', client_id) - local warning = string.format(warning_tpl, client_name) - log.warn(warning) - end - return vim.NIL -end - ---see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#client_unregisterCapability -M['client/unregisterCapability'] = function(_, result, ctx) - for _, unreg in ipairs(result.unregisterations) do - if unreg.method == 'workspace/didChangeWatchedFiles' then - require('vim.lsp._watchfiles').unregister(unreg, ctx) - end - end +M['client/registerCapability'] = function(_, _, ctx) + local client_id = ctx.client_id + local warning_tpl = 'The language server %s triggers a registerCapability ' + .. 'handler despite dynamicRegistration set to false. ' + .. 'Report upstream, this warning is harmless' + local client = vim.lsp.get_client_by_id(client_id) + local client_name = client and client.name or string.format('id=%d', client_id) + local warning = string.format(warning_tpl, client_name) + log.warn(warning) return vim.NIL end -- cgit From ac69ba5fa0081026f2c5e6e29d5788802479b7b9 Mon Sep 17 00:00:00 2001 From: Jon Huhn Date: Sun, 5 Mar 2023 00:52:27 -0600 Subject: feat(lsp): implement workspace/didChangeWatchedFiles (#22405) --- runtime/lua/vim/lsp/handlers.lua | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 5096100a60..ee5b63d260 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -117,15 +117,35 @@ M['window/showMessageRequest'] = function(_, result) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#client_registerCapability -M['client/registerCapability'] = function(_, _, ctx) - local client_id = ctx.client_id - local warning_tpl = 'The language server %s triggers a registerCapability ' - .. 'handler despite dynamicRegistration set to false. ' - .. 'Report upstream, this warning is harmless' - local client = vim.lsp.get_client_by_id(client_id) - local client_name = client and client.name or string.format('id=%d', client_id) - local warning = string.format(warning_tpl, client_name) - log.warn(warning) +M['client/registerCapability'] = function(_, result, ctx) + local log_unsupported = false + for _, reg in ipairs(result.registrations) do + if reg.method == 'workspace/didChangeWatchedFiles' then + require('vim.lsp._watchfiles').register(reg, ctx) + else + log_unsupported = true + end + end + if log_unsupported then + local client_id = ctx.client_id + local warning_tpl = 'The language server %s triggers a registerCapability ' + .. 'handler despite dynamicRegistration set to false. ' + .. 'Report upstream, this warning is harmless' + local client = vim.lsp.get_client_by_id(client_id) + local client_name = client and client.name or string.format('id=%d', client_id) + local warning = string.format(warning_tpl, client_name) + log.warn(warning) + end + return vim.NIL +end + +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#client_unregisterCapability +M['client/unregisterCapability'] = function(_, result, ctx) + for _, unreg in ipairs(result.unregisterations) do + if unreg.method == 'workspace/didChangeWatchedFiles' then + require('vim.lsp._watchfiles').unregister(unreg, ctx) + end + end return vim.NIL end -- cgit From 36ee10057ab9a93144975449cc5e27f9b96e0af3 Mon Sep 17 00:00:00 2001 From: Micah Halter Date: Sat, 25 Mar 2023 09:01:39 -0400 Subject: fix(lsp): add missing silent check in lsp hover handler (#22763) Fixup to #21531. --- runtime/lua/vim/lsp/handlers.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index ee5b63d260..d01f8e6159 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -364,7 +364,9 @@ function M.hover(_, result, ctx, config) local markdown_lines = util.convert_input_to_markdown_lines(result.contents) markdown_lines = util.trim_empty_lines(markdown_lines) if vim.tbl_isempty(markdown_lines) then - vim.notify('No information available') + if config.silent ~= true then + vim.notify('No information available') + end return end return util.open_floating_preview(markdown_lines, 'markdown', config) -- cgit From bfb28b62dab756ec76a73506c2070ddf491a0cdd Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Thu, 13 Apr 2023 15:29:13 -0600 Subject: refactor: remove modelines from Lua files Now that we have builtin EditorConfig support and a formatting check in CI, these are not necessary. --- runtime/lua/vim/lsp/handlers.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index d01f8e6159..71bef43bc1 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -644,4 +644,3 @@ for k, fn in pairs(M) do end return M --- vim:sw=2 ts=2 et -- cgit From 1fe1bb084d0099fc4f9bfdc11189485d0f74b75a Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Mon, 19 Dec 2022 16:37:45 +0000 Subject: refactor(options): deprecate nvim[_buf|_win]_[gs]et_option Co-authored-by: zeertzjq Co-authored-by: famiu --- runtime/lua/vim/lsp/handlers.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 71bef43bc1..8e926c4644 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -454,7 +454,7 @@ function M.signature_help(_, result, ctx, config) local client = vim.lsp.get_client_by_id(ctx.client_id) local triggers = vim.tbl_get(client.server_capabilities, 'signatureHelpProvider', 'triggerCharacters') - local ft = api.nvim_buf_get_option(ctx.bufnr, 'filetype') + local ft = vim.bo[ctx.bufnr].filetype local lines, hl = util.convert_signature_help_to_markdown_lines(result, ft, triggers) lines = util.trim_empty_lines(lines) if vim.tbl_isempty(lines) then -- cgit From ddd92a70d2aab5247895e89abaaa79c62ba7dbb4 Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Sun, 28 May 2023 07:51:28 +0200 Subject: feat(lsp): initial support for dynamic capabilities (#23681) - `client.dynamic_capabilities` is an object that tracks client register/unregister - `client.supports_method` will additionally check if a dynamic capability supports the method, taking document filters into account. But only if the client enabled `dynamicRegistration` for the capability - updated the default client capabilities to include dynamicRegistration for: - formatting - rangeFormatting - hover - codeAction - hover - rename --- runtime/lua/vim/lsp/handlers.lua | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 8e926c4644..5346160871 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -118,22 +118,30 @@ end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#client_registerCapability M['client/registerCapability'] = function(_, result, ctx) - local log_unsupported = false + local client_id = ctx.client_id + ---@type lsp.Client + local client = vim.lsp.get_client_by_id(client_id) + + client.dynamic_capabilities:register(result.registrations) + for bufnr, _ in ipairs(client.attached_buffers) do + vim.lsp._set_defaults(client, bufnr) + end + + ---@type string[] + local unsupported = {} for _, reg in ipairs(result.registrations) do if reg.method == 'workspace/didChangeWatchedFiles' then require('vim.lsp._watchfiles').register(reg, ctx) - else - log_unsupported = true + elseif not client.dynamic_capabilities:supports_registration(reg.method) then + unsupported[#unsupported + 1] = reg.method end end - if log_unsupported then - local client_id = ctx.client_id + if #unsupported > 0 then local warning_tpl = 'The language server %s triggers a registerCapability ' - .. 'handler despite dynamicRegistration set to false. ' + .. 'handler for %s despite dynamicRegistration set to false. ' .. 'Report upstream, this warning is harmless' - local client = vim.lsp.get_client_by_id(client_id) local client_name = client and client.name or string.format('id=%d', client_id) - local warning = string.format(warning_tpl, client_name) + local warning = string.format(warning_tpl, client_name, table.concat(unsupported, ', ')) log.warn(warning) end return vim.NIL @@ -141,6 +149,10 @@ end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#client_unregisterCapability M['client/unregisterCapability'] = function(_, result, ctx) + local client_id = ctx.client_id + local client = vim.lsp.get_client_by_id(client_id) + client.dynamic_capabilities:unregister(result.unregisterations) + for _, unreg in ipairs(result.unregisterations) do if unreg.method == 'workspace/didChangeWatchedFiles' then require('vim.lsp._watchfiles').unregister(unreg, ctx) -- cgit From e5e0bda41b640d324350c5147b956e37e9f8b32c Mon Sep 17 00:00:00 2001 From: Mathias Fußenegger Date: Fri, 9 Jun 2023 11:32:43 +0200 Subject: feat(lsp)!: add vim.lsp.status, client.progress and promote LspProgressUpdate (#23958) `client.messages` could grow unbounded because the default handler only added new messages, never removing them. A user either had to consume the messages by calling `vim.lsp.util.get_progress_messages` or by manually removing them from `client.messages.progress`. If they didn't do that, using LSP effectively leaked memory. To fix this, this deprecates the `messages` property and instead adds a `progress` ring buffer that only keeps at most 50 messages. In addition it deprecates `vim.lsp.util.get_progress_messages` in favour of a new `vim.lsp.status()` and also promotes the `LspProgressUpdate` user autocmd to a regular autocmd to allow users to pattern match on the progress kind. Also closes https://github.com/neovim/neovim/pull/20327 --- runtime/lua/vim/lsp/handlers.lua | 75 +++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 43 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 5346160871..19338ae8f0 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -9,7 +9,7 @@ local M = {} ---@private --- Writes to error buffer. ----@param ... (table of strings) Will be concatenated before being written +---@param ... string Will be concatenated before being written local function err_message(...) vim.notify(table.concat(vim.tbl_flatten({ ... })), vim.log.levels.ERROR) api.nvim_command('redraw') @@ -20,63 +20,52 @@ M['workspace/executeCommand'] = function(_, _, _, _) -- Error handling is done implicitly by wrapping all handlers; see end of this file end ----@private -local function progress_handler(_, result, ctx, _) - local client_id = ctx.client_id - local client = vim.lsp.get_client_by_id(client_id) - local client_name = client and client.name or string.format('id=%d', client_id) +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#progress +---@param result lsp.ProgressParams +---@param ctx lsp.HandlerContext +M['$/progress'] = function(_, result, ctx) + local client = vim.lsp.get_client_by_id(ctx.client_id) if not client then - err_message('LSP[', client_name, '] client has shut down during progress update') + err_message('LSP[id=', tostring(ctx.client_id), '] client has shut down during progress update') return vim.NIL end - local val = result.value -- unspecified yet - local token = result.token -- string or number + local kind = nil + local value = result.value - if type(val) ~= 'table' then - val = { content = val } - end - if val.kind then - if val.kind == 'begin' then - client.messages.progress[token] = { - title = val.title, - cancellable = val.cancellable, - message = val.message, - percentage = val.percentage, - } - elseif val.kind == 'report' then - client.messages.progress[token].cancellable = val.cancellable - client.messages.progress[token].message = val.message - client.messages.progress[token].percentage = val.percentage - elseif val.kind == 'end' then - if client.messages.progress[token] == nil then - err_message('LSP[', client_name, '] received `end` message with no corresponding `begin`') - else - client.messages.progress[token].message = val.message - client.messages.progress[token].done = true + if type(value) == 'table' then + kind = value.kind + -- Carry over title of `begin` messages to `report` and `end` messages + -- So that consumers always have it available, even if they consume a + -- subset of the full sequence + if kind == 'begin' then + client.progress.pending[result.token] = value.title + else + value.title = client.progress.pending[result.token] + if kind == 'end' then + client.progress.pending[result.token] = nil end end - else - client.messages.progress[token] = val - client.messages.progress[token].done = true end - api.nvim_exec_autocmds('User', { pattern = 'LspProgressUpdate', modeline = false }) -end + client.progress:push(result) ---see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#progress -M['$/progress'] = progress_handler + api.nvim_exec_autocmds('LspProgress', { + pattern = kind, + modeline = false, + data = { client_id = ctx.client_id, result = result }, + }) +end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_workDoneProgress_create +---@param result lsp.WorkDoneProgressCreateParams +---@param ctx lsp.HandlerContext M['window/workDoneProgress/create'] = function(_, result, ctx) - local client_id = ctx.client_id - local client = vim.lsp.get_client_by_id(client_id) - local token = result.token -- string or number - local client_name = client and client.name or string.format('id=%d', client_id) + local client = vim.lsp.get_client_by_id(ctx.client_id) if not client then - err_message('LSP[', client_name, '] client has shut down while creating progress report') + err_message('LSP[id=', tostring(ctx.client_id), '] client has shut down during progress update') return vim.NIL end - client.messages.progress[token] = {} + client.progress:push(result) return vim.NIL end -- cgit From 643546b82b4bc0c29ca869f81af868a019723d83 Mon Sep 17 00:00:00 2001 From: Chinmay Dalal Date: Sun, 11 Jun 2023 15:23:37 +0530 Subject: feat(lsp): add handlers for inlay hints (#23736) initial support; public API left for a follow-up PR --- runtime/lua/vim/lsp/handlers.lua | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 19338ae8f0..44a9a58aca 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -219,6 +219,10 @@ M['textDocument/codeLens'] = function(...) return require('vim.lsp.codelens').on_codelens(...) end +M['textDocument/inlayHint'] = function(...) + return require('vim.lsp._inlay_hint').on_inlayhint(...) +end + --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references M['textDocument/references'] = function(_, result, ctx, config) if not result or vim.tbl_isempty(result) then @@ -612,6 +616,28 @@ M['window/showDocument'] = function(_, result, ctx, _) return { success = success or false } end +---@see https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_inlayHint_refresh +M['workspace/inlayHint/refresh'] = function(err, _, ctx) + local inlay_hint = require('vim.lsp._inlay_hint') + if not inlay_hint.__explicit_buffers[ctx.bufnr] then + return vim.NIL + end + if err then + return vim.NIL + end + + for _, bufnr in ipairs(vim.lsp.get_buffers_by_client_id(ctx.client_id)) do + for _, winid in ipairs(api.nvim_list_wins()) do + if api.nvim_win_get_buf(winid) == bufnr then + inlay_hint.refresh({ bufnr = bufnr }) + break + end + end + end + + return vim.NIL +end + -- Add boilerplate error validation and logging for all of these. for k, fn in pairs(M) do M[k] = function(err, result, ctx, config) -- cgit From ca5de9306c00d07cce1daef1f0038c937098bc66 Mon Sep 17 00:00:00 2001 From: Chinmay Dalal Date: Tue, 20 Jun 2023 11:36:54 +0530 Subject: feat(lsp): inlay hints #23984 Add automatic refresh and a public interface on top of #23736 * add on_reload, on_detach handlers in `enable()` buf_attach, and LspDetach autocommand in case of manual detach * unify `__buffers` and `hint_cache_by_buf` * use callback bufnr in `on_lines` callback, bufstate: remove __index override * move user-facing functions into vim.lsp.buf, unify enable/disable/toggle Closes #18086 --- runtime/lua/vim/lsp/handlers.lua | 3 --- 1 file changed, 3 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 44a9a58aca..284e3ef2d0 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -619,9 +619,6 @@ end ---@see https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_inlayHint_refresh M['workspace/inlayHint/refresh'] = function(err, _, ctx) local inlay_hint = require('vim.lsp._inlay_hint') - if not inlay_hint.__explicit_buffers[ctx.bufnr] then - return vim.NIL - end if err then return vim.NIL end -- cgit From 37079fca58f396fd866dc7b7d87a0100c17ee760 Mon Sep 17 00:00:00 2001 From: Mathias Fußenegger Date: Fri, 30 Jun 2023 11:33:28 +0200 Subject: feat(lsp): move inlay_hint() to vim.lsp (#24130) Allows to keep more functions hidden and gives a path forward for further inlay_hint related functions - like applying textEdits. See https://github.com/neovim/neovim/pull/23984#pullrequestreview-1486624668 --- runtime/lua/vim/lsp/handlers.lua | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 284e3ef2d0..625a2ed282 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -220,7 +220,7 @@ M['textDocument/codeLens'] = function(...) end M['textDocument/inlayHint'] = function(...) - return require('vim.lsp._inlay_hint').on_inlayhint(...) + return require('vim.lsp.inlay_hint').on_inlayhint(...) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references @@ -617,22 +617,8 @@ M['window/showDocument'] = function(_, result, ctx, _) end ---@see https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_inlayHint_refresh -M['workspace/inlayHint/refresh'] = function(err, _, ctx) - local inlay_hint = require('vim.lsp._inlay_hint') - if err then - return vim.NIL - end - - for _, bufnr in ipairs(vim.lsp.get_buffers_by_client_id(ctx.client_id)) do - for _, winid in ipairs(api.nvim_list_wins()) do - if api.nvim_win_get_buf(winid) == bufnr then - inlay_hint.refresh({ bufnr = bufnr }) - break - end - end - end - - return vim.NIL +M['workspace/inlayHint/refresh'] = function(err, result, ctx, config) + return require('vim.lsp.inlay_hint').on_refresh(err, result, ctx, config) end -- Add boilerplate error validation and logging for all of these. -- cgit From af6e6ccf3dee815850639ec5613dda3442caa7d6 Mon Sep 17 00:00:00 2001 From: marshmallow Date: Sun, 30 Apr 2023 15:53:02 +1000 Subject: feat(vim.ui): vim.ui.open, "gx" without netrw MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mathias Fußenegger Co-authored-by: Justin M. Keyes Co-authored-by: ii14 <59243201+ii14@users.noreply.github.com> --- runtime/lua/vim/lsp/handlers.lua | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 625a2ed282..9b102c0f84 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -573,22 +573,15 @@ M['window/showDocument'] = function(_, result, ctx, _) if result.external then -- TODO(lvimuser): ask the user for confirmation - local cmd - if vim.fn.has('win32') == 1 then - cmd = { 'cmd.exe', '/c', 'start', '""', uri } - elseif vim.fn.has('macunix') == 1 then - cmd = { 'open', uri } - else - cmd = { 'xdg-open', uri } - end - local ret = vim.fn.system(cmd) - if vim.v.shell_error ~= 0 then + local ret = vim.ui.open(uri) + + if ret.code ~= 0 or ret == nil then return { success = false, error = { code = protocol.ErrorCodes.UnknownErrorCode, - message = ret, + message = ret and ret.stderr or 'No handler could be found', }, } end -- cgit From 67b2ed1004ae551c9fe1bbd29a86b5a301570800 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 2 Jul 2023 16:51:30 +0200 Subject: fix(gx): visual selection, expand env vars --- Rejected experiment: move vim.ui.open() to vim.env.open() Problem: `vim.ui` is where user-interface "providers" live, which can be overridden. It would also be useful to have a "providers" namespace for platform-specific features such as "open", clipboard, python, and the other providers listed in `:help providers`. We could overload `vim.ui` to serve that purpose as the single "providers" namespace, but `vim.ui.nodejs()` for example seems awkward. Solution: `vim.env` currently has too narrow of a purpose. Overload it to also be a namespace for `vim.env.open`. diff --git a/runtime/lua/vim/_meta.lua b/runtime/lua/vim/_meta.lua index 913f1fe20348..17d05ff37595 100644 --- a/runtime/lua/vim/_meta.lua +++ b/runtime/lua/vim/_meta.lua @@ -37,8 +37,28 @@ local options_info = setmetatable({}, { end, }) -vim.env = setmetatable({}, { - __index = function(_, k) +vim.env = setmetatable({ + open = setmetatable({}, { + __call = function(_, uri) + print('xxxxx'..uri) + return true + end, + __tostring = function() + local v = vim.fn.getenv('open') + if v == vim.NIL then + return nil + end + return v + end, + }) + }, + { + __index = function(t, k, ...) + if k == 'open' then + error() + -- vim.print({...}) + -- return rawget(t, k) + end local v = vim.fn.getenv(k) if v == vim.NIL then return nil --- runtime/lua/vim/lsp/handlers.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 9b102c0f84..79d3f7aab0 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -576,12 +576,12 @@ M['window/showDocument'] = function(_, result, ctx, _) local ret = vim.ui.open(uri) - if ret.code ~= 0 or ret == nil then + if ret == nil or ret.code ~= 0 then return { success = false, error = { code = protocol.ErrorCodes.UnknownErrorCode, - message = ret and ret.stderr or 'No handler could be found', + message = ret and ret.stderr or 'No handler found', }, } end @@ -593,7 +593,7 @@ M['window/showDocument'] = function(_, result, ctx, _) local client = vim.lsp.get_client_by_id(client_id) local client_name = client and client.name or string.format('id=%d', client_id) if not client then - err_message({ 'LSP[', client_name, '] client has shut down after sending ', ctx.method }) + err_message('LSP[', client_name, '] client has shut down after sending ', ctx.method) return vim.NIL end -- cgit From e644e7ce0b36dd5e75770f3faa0a84f15e2561e8 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 4 Jul 2023 23:33:23 +0200 Subject: fix(vim.ui.open): return (don't show) error message Problem: Showing an error via vim.notify() makes it awkward for callers such as lsp/handlers.lua to avoid showing redundant errors. Solution: Return the message instead of showing it. Let the caller decide whether and when to show the message. --- runtime/lua/vim/lsp/handlers.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 79d3f7aab0..70781cb7a6 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -573,15 +573,14 @@ M['window/showDocument'] = function(_, result, ctx, _) if result.external then -- TODO(lvimuser): ask the user for confirmation - - local ret = vim.ui.open(uri) + local ret, err = vim.ui.open(uri) if ret == nil or ret.code ~= 0 then return { success = false, error = { code = protocol.ErrorCodes.UnknownErrorCode, - message = ret and ret.stderr or 'No handler found', + message = ret and ret.stderr or err, }, } end -- cgit From 766f4978d6cb146511cf0b676c01e5327db46647 Mon Sep 17 00:00:00 2001 From: Raphael Date: Mon, 10 Jul 2023 19:38:15 +0800 Subject: fix(lint): lint warnings #24226 --- runtime/lua/vim/lsp/handlers.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 70781cb7a6..20c4d7458b 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -382,7 +382,7 @@ M['textDocument/hover'] = M.hover ---@private --- Jumps to a location. Used as a handler for multiple LSP methods. ----@param _ (not used) +---@param _ nil not used ---@param result (table) result of LSP method; a location or a list of locations. ---@param ctx (table) table containing the context of the request, including the method ---(`textDocument/definition` can return `Location` or `Location[]` @@ -496,8 +496,9 @@ end --- Displays call hierarchy in the quickfix window. --- ---@param direction `"from"` for incoming calls and `"to"` for outgoing calls ----@returns `CallHierarchyIncomingCall[]` if {direction} is `"from"`, ----@returns `CallHierarchyOutgoingCall[]` if {direction} is `"to"`, +---@return function +--- `CallHierarchyIncomingCall[]` if {direction} is `"from"`, +--- `CallHierarchyOutgoingCall[]` if {direction} is `"to"`, local make_call_hierarchy_handler = function(direction) return function(_, result) if not result then -- cgit From be74807eef13ff8c90d55cf8b22b01d6d33b1641 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Tue, 18 Jul 2023 15:42:30 +0100 Subject: docs(lua): more improvements (#24387) * docs(lua): teach lua2dox how to table * docs(lua): teach gen_vimdoc.py about local functions No more need to mark local functions with @private * docs(lua): mention @nodoc and @meta in dev-lua-doc * fixup! Co-authored-by: Justin M. Keyes --------- Co-authored-by: Justin M. Keyes --- runtime/lua/vim/lsp/handlers.lua | 3 --- 1 file changed, 3 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 20c4d7458b..ce3db68618 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -7,7 +7,6 @@ local M = {} -- FIXME: DOC: Expose in vimdocs ----@private --- Writes to error buffer. ---@param ... string Will be concatenated before being written local function err_message(...) @@ -246,7 +245,6 @@ M['textDocument/references'] = function(_, result, ctx, config) end end ----@private --- Return a function that converts LSP responses to list items and opens the list --- --- The returned function has an optional {config} parameter that accepts a table @@ -380,7 +378,6 @@ end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_hover M['textDocument/hover'] = M.hover ----@private --- Jumps to a location. Used as a handler for multiple LSP methods. ---@param _ nil not used ---@param result (table) result of LSP method; a location or a list of locations. -- cgit From 63b3408551561127f7845470eb51404bcd6f547b Mon Sep 17 00:00:00 2001 From: Chris AtLee Date: Thu, 20 Jul 2023 03:03:48 -0400 Subject: feat(lsp): implement textDocument/diagnostic (#24128) --- runtime/lua/vim/lsp/handlers.lua | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index ce3db68618..d887183972 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -214,6 +214,10 @@ M['textDocument/publishDiagnostics'] = function(...) return require('vim.lsp.diagnostic').on_publish_diagnostics(...) end +M['textDocument/diagnostic'] = function(...) + return require('vim.lsp.diagnostic').on_diagnostic(...) +end + M['textDocument/codeLens'] = function(...) return require('vim.lsp.codelens').on_codelens(...) end -- cgit From f1772272b4fda43c093fc495f54b5e7c11968d62 Mon Sep 17 00:00:00 2001 From: Raphael Date: Thu, 3 Aug 2023 19:03:48 +0800 Subject: refactor(lsp): use protocol.Methods instead of strings #24537 --- runtime/lua/vim/lsp/handlers.lua | 71 ++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 35 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index d887183972..6fe4b7f939 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -1,5 +1,6 @@ local log = require('vim.lsp.log') local protocol = require('vim.lsp.protocol') +local ms = protocol.Methods local util = require('vim.lsp.util') local api = vim.api @@ -15,14 +16,14 @@ local function err_message(...) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_executeCommand -M['workspace/executeCommand'] = function(_, _, _, _) +M[ms.workspace_executeCommand] = function(_, _, _, _) -- Error handling is done implicitly by wrapping all handlers; see end of this file end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#progress ---@param result lsp.ProgressParams ---@param ctx lsp.HandlerContext -M['$/progress'] = function(_, result, ctx) +M[ms.dollar_progress] = function(_, result, ctx) local client = vim.lsp.get_client_by_id(ctx.client_id) if not client then err_message('LSP[id=', tostring(ctx.client_id), '] client has shut down during progress update') @@ -58,7 +59,7 @@ end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_workDoneProgress_create ---@param result lsp.WorkDoneProgressCreateParams ---@param ctx lsp.HandlerContext -M['window/workDoneProgress/create'] = function(_, result, ctx) +M[ms.window_workDoneProgress_create] = function(_, result, ctx) local client = vim.lsp.get_client_by_id(ctx.client_id) if not client then err_message('LSP[id=', tostring(ctx.client_id), '] client has shut down during progress update') @@ -70,7 +71,7 @@ end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_showMessageRequest ---@param result lsp.ShowMessageRequestParams -M['window/showMessageRequest'] = function(_, result) +M[ms.window_showMessageRequest] = function(_, result) local actions = result.actions or {} local co, is_main = coroutine.running() if co and not is_main then @@ -105,7 +106,7 @@ M['window/showMessageRequest'] = function(_, result) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#client_registerCapability -M['client/registerCapability'] = function(_, result, ctx) +M[ms.client_registerCapability] = function(_, result, ctx) local client_id = ctx.client_id ---@type lsp.Client local client = vim.lsp.get_client_by_id(client_id) @@ -118,7 +119,7 @@ M['client/registerCapability'] = function(_, result, ctx) ---@type string[] local unsupported = {} for _, reg in ipairs(result.registrations) do - if reg.method == 'workspace/didChangeWatchedFiles' then + if reg.method == ms.workspace_didChangeWatchedFiles then require('vim.lsp._watchfiles').register(reg, ctx) elseif not client.dynamic_capabilities:supports_registration(reg.method) then unsupported[#unsupported + 1] = reg.method @@ -136,13 +137,13 @@ M['client/registerCapability'] = function(_, result, ctx) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#client_unregisterCapability -M['client/unregisterCapability'] = function(_, result, ctx) +M[ms.client_unregisterCapability] = function(_, result, ctx) local client_id = ctx.client_id local client = vim.lsp.get_client_by_id(client_id) client.dynamic_capabilities:unregister(result.unregisterations) for _, unreg in ipairs(result.unregisterations) do - if unreg.method == 'workspace/didChangeWatchedFiles' then + if unreg.method == ms.workspace_didChangeWatchedFiles then require('vim.lsp._watchfiles').unregister(unreg, ctx) end end @@ -150,7 +151,7 @@ M['client/unregisterCapability'] = function(_, result, ctx) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_applyEdit -M['workspace/applyEdit'] = function(_, workspace_edit, ctx) +M[ms.workspace_applyEdit] = function(_, workspace_edit, ctx) assert( workspace_edit, 'workspace/applyEdit must be called with `ApplyWorkspaceEditParams`. Server is violating the specification' @@ -170,7 +171,7 @@ M['workspace/applyEdit'] = function(_, workspace_edit, ctx) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_configuration -M['workspace/configuration'] = function(_, result, ctx) +M[ms.workspace_configuration] = function(_, result, ctx) local client_id = ctx.client_id local client = vim.lsp.get_client_by_id(client_id) if not client then @@ -200,7 +201,7 @@ M['workspace/configuration'] = function(_, result, ctx) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_workspaceFolders -M['workspace/workspaceFolders'] = function(_, _, ctx) +M[ms.workspace_workspaceFolders] = function(_, _, ctx) local client_id = ctx.client_id local client = vim.lsp.get_client_by_id(client_id) if not client then @@ -210,24 +211,24 @@ M['workspace/workspaceFolders'] = function(_, _, ctx) return client.workspace_folders or vim.NIL end -M['textDocument/publishDiagnostics'] = function(...) +M[ms.textDocument_publishDiagnostics] = function(...) return require('vim.lsp.diagnostic').on_publish_diagnostics(...) end -M['textDocument/diagnostic'] = function(...) +M[ms.textDocument_diagnostic] = function(...) return require('vim.lsp.diagnostic').on_diagnostic(...) end -M['textDocument/codeLens'] = function(...) +M[ms.textDocument_codeLens] = function(...) return require('vim.lsp.codelens').on_codelens(...) end -M['textDocument/inlayHint'] = function(...) +M[ms.textDocument_inlayHint] = function(...) return require('vim.lsp.inlay_hint').on_inlayhint(...) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references -M['textDocument/references'] = function(_, result, ctx, config) +M[ms.textDocument_references] = function(_, result, ctx, config) if not result or vim.tbl_isempty(result) then vim.notify('No references found') else @@ -283,7 +284,7 @@ local function response_to_list(map_result, entity, title_fn) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_documentSymbol -M['textDocument/documentSymbol'] = response_to_list( +M[ms.textDocument_documentSymbol] = response_to_list( util.symbols_to_items, 'document symbols', function(ctx) @@ -293,12 +294,12 @@ M['textDocument/documentSymbol'] = response_to_list( ) --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_symbol -M['workspace/symbol'] = response_to_list(util.symbols_to_items, 'symbols', function(ctx) +M[ms.workspace_symbol] = response_to_list(util.symbols_to_items, 'symbols', function(ctx) return string.format("Symbols matching '%s'", ctx.params.query) end) --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rename -M['textDocument/rename'] = function(_, result, ctx, _) +M[ms.textDocument_rename] = function(_, result, ctx, _) if not result then vim.notify("Language server couldn't provide rename result", vim.log.levels.INFO) return @@ -308,7 +309,7 @@ M['textDocument/rename'] = function(_, result, ctx, _) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rangeFormatting -M['textDocument/rangeFormatting'] = function(_, result, ctx, _) +M[ms.textDocument_rangeFormatting] = function(_, result, ctx, _) if not result then return end @@ -317,7 +318,7 @@ M['textDocument/rangeFormatting'] = function(_, result, ctx, _) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_formatting -M['textDocument/formatting'] = function(_, result, ctx, _) +M[ms.textDocument_formatting] = function(_, result, ctx, _) if not result then return end @@ -326,7 +327,7 @@ M['textDocument/formatting'] = function(_, result, ctx, _) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion -M['textDocument/completion'] = function(_, result, _, _) +M[ms.textDocument_completion] = function(_, result, _, _) if vim.tbl_isempty(result or {}) then return end @@ -380,7 +381,7 @@ function M.hover(_, result, ctx, config) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_hover -M['textDocument/hover'] = M.hover +M[ms.textDocument_hover] = M.hover --- Jumps to a location. Used as a handler for multiple LSP methods. ---@param _ nil not used @@ -420,13 +421,13 @@ local function location_handler(_, result, ctx, config) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_declaration -M['textDocument/declaration'] = location_handler +M[ms.textDocument_declaration] = location_handler --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_definition -M['textDocument/definition'] = location_handler +M[ms.textDocument_definition] = location_handler --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_typeDefinition -M['textDocument/typeDefinition'] = location_handler +M[ms.textDocument_typeDefinition] = location_handler --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_implementation -M['textDocument/implementation'] = location_handler +M[ms.textDocument_implementation] = location_handler --- |lsp-handler| for the method "textDocument/signatureHelp". --- The active parameter is highlighted with |hl-LspSignatureActiveParameter|. @@ -477,10 +478,10 @@ function M.signature_help(_, result, ctx, config) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_signatureHelp -M['textDocument/signatureHelp'] = M.signature_help +M[ms.textDocument_signatureHelp] = M.signature_help --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_documentHighlight -M['textDocument/documentHighlight'] = function(_, result, ctx, _) +M[ms.textDocument_documentHighlight] = function(_, result, ctx, _) if not result then return end @@ -523,13 +524,13 @@ local make_call_hierarchy_handler = function(direction) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#callHierarchy_incomingCalls -M['callHierarchy/incomingCalls'] = make_call_hierarchy_handler('from') +M[ms.callHierarchy_incomingCalls] = make_call_hierarchy_handler('from') --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#callHierarchy_outgoingCalls -M['callHierarchy/outgoingCalls'] = make_call_hierarchy_handler('to') +M[ms.callHierarchy_outgoingCalls] = make_call_hierarchy_handler('to') --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_logMessage -M['window/logMessage'] = function(_, result, ctx, _) +M[ms.window_logMessage] = function(_, result, ctx, _) local message_type = result.type local message = result.message local client_id = ctx.client_id @@ -551,7 +552,7 @@ M['window/logMessage'] = function(_, result, ctx, _) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_showMessage -M['window/showMessage'] = function(_, result, ctx, _) +M[ms.window_showMessage] = function(_, result, ctx, _) local message_type = result.type local message = result.message local client_id = ctx.client_id @@ -570,7 +571,7 @@ M['window/showMessage'] = function(_, result, ctx, _) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_showDocument -M['window/showDocument'] = function(_, result, ctx, _) +M[ms.window_showDocument] = function(_, result, ctx, _) local uri = result.uri if result.external then @@ -611,7 +612,7 @@ M['window/showDocument'] = function(_, result, ctx, _) end ---@see https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_inlayHint_refresh -M['workspace/inlayHint/refresh'] = function(err, result, ctx, config) +M[ms.workspace_inlayHint_refresh] = function(err, result, ctx, config) return require('vim.lsp.inlay_hint').on_refresh(err, result, ctx, config) end -- cgit From 597355deae2ebddcb8b930da9a8b45a65d05d09b Mon Sep 17 00:00:00 2001 From: TheBlob42 Date: Fri, 1 Sep 2023 13:31:05 +0200 Subject: fix(lsp): wrong iterator in registerCapability handler (#24971) --- runtime/lua/vim/lsp/handlers.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 6fe4b7f939..a6b70ac911 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -112,7 +112,7 @@ M[ms.client_registerCapability] = function(_, result, ctx) local client = vim.lsp.get_client_by_id(client_id) client.dynamic_capabilities:register(result.registrations) - for bufnr, _ in ipairs(client.attached_buffers) do + for bufnr, _ in pairs(client.attached_buffers) do vim.lsp._set_defaults(client, bufnr) end -- cgit From 5e3cf9fb4bc7f236c858f609ca83c57fb1779ab0 Mon Sep 17 00:00:00 2001 From: Grace Petryk Date: Sun, 10 Sep 2023 01:02:23 -0700 Subject: feat(lsp): improve control over placement of floating windows (#24494) --- runtime/lua/vim/lsp/handlers.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index a6b70ac911..81d4d6cceb 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -355,7 +355,7 @@ end ---@param config table Configuration table. --- - border: (default=nil) --- - Add borders to the floating window ---- - See |nvim_open_win()| +--- - See |vim.lsp.util.open_floating_preview()| for more options. function M.hover(_, result, ctx, config) config = config or {} config.focus_id = ctx.method @@ -442,7 +442,7 @@ M[ms.textDocument_implementation] = location_handler ---@param config table Configuration table. --- - border: (default=nil) --- - Add borders to the floating window ---- - See |nvim_open_win()| +--- - See |vim.lsp.util.open_floating_preview()| for more options function M.signature_help(_, result, ctx, config) config = config or {} config.focus_id = ctx.method -- cgit From 2e92065686f62851318150a315591c30b8306a4b Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Thu, 14 Sep 2023 08:23:01 -0500 Subject: docs: replace
 with ``` (#25136)

---
 runtime/lua/vim/lsp/handlers.lua | 43 +++++++++++++++++++++++-----------------
 1 file changed, 25 insertions(+), 18 deletions(-)

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

diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua
index 81d4d6cceb..4ea3dde81c 100644
--- a/runtime/lua/vim/lsp/handlers.lua
+++ b/runtime/lua/vim/lsp/handlers.lua
@@ -342,16 +342,18 @@ M[ms.textDocument_completion] = function(_, result, _, _)
 end
 
 --- |lsp-handler| for the method "textDocument/hover"
---- 
lua
----   vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(
----     vim.lsp.handlers.hover, {
----       -- Use a sharp border with `FloatBorder` highlights
----       border = "single",
----       -- add the title in hover float window
----       title = "hover"
----     }
----   )
---- 
+--- +--- ```lua +--- vim.lsp.handlers["textDocument/hover"] = vim.lsp.with( +--- vim.lsp.handlers.hover, { +--- -- Use a sharp border with `FloatBorder` highlights +--- border = "single", +--- -- add the title in hover float window +--- title = "hover" +--- } +--- ) +--- ``` +--- ---@param config table Configuration table. --- - border: (default=nil) --- - Add borders to the floating window @@ -430,15 +432,20 @@ M[ms.textDocument_typeDefinition] = location_handler M[ms.textDocument_implementation] = location_handler --- |lsp-handler| for the method "textDocument/signatureHelp". +--- --- The active parameter is highlighted with |hl-LspSignatureActiveParameter|. ----
lua
----   vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with(
----     vim.lsp.handlers.signature_help, {
----       -- Use a sharp border with `FloatBorder` highlights
----       border = "single"
----     }
----   )
---- 
+--- +--- ```lua +--- vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with( +--- vim.lsp.handlers.signature_help, { +--- -- Use a sharp border with `FloatBorder` highlights +--- border = "single" +--- } +--- ) +--- ``` +--- +---@param result table Response from the language server +---@param ctx table Client context ---@param config table Configuration table. --- - border: (default=nil) --- - Add borders to the floating window -- cgit From cfd4a9dfaf5fd900264a946ca33c4a4f26f66a49 Mon Sep 17 00:00:00 2001 From: Maria José Solano Date: Tue, 12 Sep 2023 20:51:21 -0700 Subject: feat(lsp): use treesitter for stylize markdown --- runtime/lua/vim/lsp/handlers.lua | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 4ea3dde81c..f8407be159 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -371,15 +371,22 @@ function M.hover(_, result, ctx, config) end return end - local markdown_lines = util.convert_input_to_markdown_lines(result.contents) - markdown_lines = util.trim_empty_lines(markdown_lines) - if vim.tbl_isempty(markdown_lines) then + local format = 'markdown' + local contents ---@type string[] + if type(result.contents) == 'table' and result.contents.kind == 'plaintext' then + format = 'plaintext' + contents = { result.contents.value or '' } + else + contents = util.convert_input_to_markdown_lines(result.contents) + end + contents = util.trim_empty_lines(contents) + if vim.tbl_isempty(contents) then if config.silent ~= true then vim.notify('No information available') end return end - return util.open_floating_preview(markdown_lines, 'markdown', config) + return util.open_floating_preview(contents, format, config) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_hover -- cgit From 5a363ccac8ff5889332bafbf68e7e8d20bca316c Mon Sep 17 00:00:00 2001 From: Maria José Solano Date: Mon, 18 Sep 2023 11:04:01 -0700 Subject: fix(lsp)!: deprecate trim_empty_lines --- runtime/lua/vim/lsp/handlers.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index f8407be159..d43d9a7cfa 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -375,11 +375,10 @@ function M.hover(_, result, ctx, config) local contents ---@type string[] if type(result.contents) == 'table' and result.contents.kind == 'plaintext' then format = 'plaintext' - contents = { result.contents.value or '' } + contents = vim.split(result.contents.value or '', '\n', { trimempty = true }) else contents = util.convert_input_to_markdown_lines(result.contents) end - contents = util.trim_empty_lines(contents) if vim.tbl_isempty(contents) then if config.silent ~= true then vim.notify('No information available') @@ -477,7 +476,6 @@ function M.signature_help(_, result, ctx, config) vim.tbl_get(client.server_capabilities, 'signatureHelpProvider', 'triggerCharacters') local ft = vim.bo[ctx.bufnr].filetype local lines, hl = util.convert_signature_help_to_markdown_lines(result, ft, triggers) - lines = util.trim_empty_lines(lines) if vim.tbl_isempty(lines) then if config.silent ~= true then print('No signature help available') -- cgit From c46a6c065e8d830adb8a2f410d3c92cf5bd4455b Mon Sep 17 00:00:00 2001 From: Maria José Solano Date: Mon, 16 Oct 2023 08:13:37 -0700 Subject: docs: do not hardcode LSP version in URL #25648 --- runtime/lua/vim/lsp/handlers.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index d43d9a7cfa..d3b199b866 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -623,7 +623,7 @@ M[ms.window_showDocument] = function(_, result, ctx, _) return { success = success or false } end ----@see https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_inlayHint_refresh +---@see https://microsoft.github.io/language-server-protocol/specification/#workspace_inlayHint_refresh M[ms.workspace_inlayHint_refresh] = function(err, result, ctx, config) return require('vim.lsp.inlay_hint').on_refresh(err, result, ctx, config) end -- cgit From 2eecb1b85dbb0e02ec40e95d28d3cc4720040f01 Mon Sep 17 00:00:00 2001 From: Maria José Solano Date: Mon, 16 Oct 2023 08:52:48 -0700 Subject: fix(lsp): highlight active parameter in signature help #25663 Fixes #25662 --- runtime/lua/vim/lsp/handlers.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index d3b199b866..d153b956ee 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -476,7 +476,7 @@ function M.signature_help(_, result, ctx, config) vim.tbl_get(client.server_capabilities, 'signatureHelpProvider', 'triggerCharacters') local ft = vim.bo[ctx.bufnr].filetype local lines, hl = util.convert_signature_help_to_markdown_lines(result, ft, triggers) - if vim.tbl_isempty(lines) then + if not lines or vim.tbl_isempty(lines) then if config.silent ~= true then print('No signature help available') end @@ -484,7 +484,9 @@ function M.signature_help(_, result, ctx, config) end local fbuf, fwin = util.open_floating_preview(lines, 'markdown', config) if hl then - api.nvim_buf_add_highlight(fbuf, -1, 'LspSignatureActiveParameter', 0, unpack(hl)) + -- Highlight the second line if the signature is wrapped in a Markdown code block. + local line = vim.startswith(lines[1], '```') and 1 or 0 + api.nvim_buf_add_highlight(fbuf, -1, 'LspSignatureActiveParameter', line, unpack(hl)) end return fbuf, fwin end -- cgit From adbe7f368397da21465f27181e254dd3694820e9 Mon Sep 17 00:00:00 2001 From: Evgeni Chasnovski Date: Tue, 31 Oct 2023 14:18:44 +0200 Subject: fix(lsp): call `on_list()` even for single location (#25830) Problem: Currently there is no way of customizing behavior of `declaration`, `definition`, `typeDefinition`, and `implementation` methods in `vim.lsp.buf` when LSP server returns `Location`. Instead, cursor jumps to that location directly. Solution: Normalize LSP response to be `Location[]` for those four cases. --- runtime/lua/vim/lsp/handlers.lua | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'runtime/lua/vim/lsp/handlers.lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index d153b956ee..6fde55cf04 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -407,25 +407,24 @@ local function location_handler(_, result, ctx, config) -- textDocument/definition can return Location or Location[] -- https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_definition + if not vim.tbl_islist(result) then + result = { result } + end - if vim.tbl_islist(result) then - local title = 'LSP locations' - local items = util.locations_to_items(result, client.offset_encoding) + local title = 'LSP locations' + local items = util.locations_to_items(result, client.offset_encoding) - if config.on_list then - assert(type(config.on_list) == 'function', 'on_list is not a function') - config.on_list({ title = title, items = items }) - else - if #result == 1 then - util.jump_to_location(result[1], client.offset_encoding, config.reuse_win) - return - end - vim.fn.setqflist({}, ' ', { title = title, items = items }) - api.nvim_command('botright copen') - end - else - util.jump_to_location(result, client.offset_encoding, config.reuse_win) + if config.on_list then + assert(type(config.on_list) == 'function', 'on_list is not a function') + config.on_list({ title = title, items = items }) + return + end + if #result == 1 then + util.jump_to_location(result[1], client.offset_encoding, config.reuse_win) + return end + vim.fn.setqflist({}, ' ', { title = title, items = items }) + api.nvim_command('botright copen') end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_declaration -- cgit