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/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 624436bc9b..a32c59dd17 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -389,7 +389,7 @@ M['textDocument/implementation'] = location_handler ---@param config table Configuration table. --- - border: (default=nil) --- - Add borders to the floating window ---- - See |vim.api.nvim_open_win()| +--- - See |nvim_open_win()| function M.signature_help(_, result, ctx, config) config = config or {} config.focus_id = ctx.method -- cgit From 0773a9ee3a21db54cd6b2376dd2e087bc09d5ea1 Mon Sep 17 00:00:00 2001 From: lvimuser <109605931+lvimuser@users.noreply.github.com> Date: Sat, 8 Oct 2022 05:22:25 -0300 Subject: feat(lsp): support window/showDocument (#19977) --- runtime/lua/vim/lsp/handlers.lua | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 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 a32c59dd17..d7d9ca7ce9 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -512,6 +512,52 @@ M['window/showMessage'] = function(_, result, ctx, _) return result end +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_showDocument +M['window/showDocument'] = function(_, result, ctx, _) + local uri = result.uri + + 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', '""', vim.fn.shellescape(uri) } + elseif vim.fn.has('macunix') == 1 then + cmd = { 'open', vim.fn.shellescape(uri) } + else + cmd = { 'xdg-open', vim.fn.shellescape(uri) } + end + + local ret = vim.fn.system(cmd) + if vim.v.shellerror ~= 0 then + return { + success = false, + error = { + code = protocol.ErrorCodes.UnknownErrorCode, + message = ret, + }, + } + end + + return { success = true } + end + + 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) + if not client then + err_message({ 'LSP[', client_name, '] client has shut down after sending ', ctx.method }) + return vim.NIL + end + + local location = { + uri = uri, + range = result.selection, + } + + local success = util.show_document(location, client.offset_encoding, true, result.takeFocus) + return { success = success or false } +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 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/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 d7d9ca7ce9..93fd621161 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -1,7 +1,6 @@ local log = require('vim.lsp.log') local protocol = require('vim.lsp.protocol') local util = require('vim.lsp.util') -local vim = vim local api = vim.api local M = {} -- cgit From e0dff29adc7690bb693ff05ff8776d07e756d4f9 Mon Sep 17 00:00:00 2001 From: lvimuser <109605931+lvimuser@users.noreply.github.com> Date: Sun, 30 Oct 2022 06:35:22 -0300 Subject: fix(lsp/window_showDocument): correctly handle external resources #20867 - since cmd is a list, it runs directly ('no shell') and we shouldn't escape. - typo: shellerror -> shell_error --- runtime/lua/vim/lsp/handlers.lua | 8 ++++---- 1 file changed, 4 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 93fd621161..c648a53555 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -519,15 +519,15 @@ M['window/showDocument'] = function(_, result, ctx, _) -- TODO(lvimuser): ask the user for confirmation local cmd if vim.fn.has('win32') == 1 then - cmd = { 'cmd.exe', '/c', 'start', '""', vim.fn.shellescape(uri) } + cmd = { 'cmd.exe', '/c', 'start', '""', uri } elseif vim.fn.has('macunix') == 1 then - cmd = { 'open', vim.fn.shellescape(uri) } + cmd = { 'open', uri } else - cmd = { 'xdg-open', vim.fn.shellescape(uri) } + cmd = { 'xdg-open', uri } end local ret = vim.fn.system(cmd) - if vim.v.shellerror ~= 0 then + if vim.v.shell_error ~= 0 then return { success = false, error = { -- cgit From af204dd0f193c3cd3154156c9f9fd40199b840c6 Mon Sep 17 00:00:00 2001 From: Mathias Fußenegger Date: Sat, 19 Nov 2022 10:48:49 +0100 Subject: feat(lsp): run handler in coroutine to support async response (#21026) To illustrate a use-case this also changes `window/showMessageRequest` to use `vim.ui.select` --- runtime/lua/vim/lsp/handlers.lua | 44 +++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 14 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 c648a53555..c80adc6a87 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -81,22 +81,38 @@ M['window/workDoneProgress/create'] = function(_, result, ctx) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_showMessageRequest +---@param result lsp.ShowMessageRequestParams M['window/showMessageRequest'] = function(_, result) - local actions = result.actions - print(result.message) - local option_strings = { result.message, '\nRequest Actions:' } - for i, action in ipairs(actions) do - local title = action.title:gsub('\r\n', '\\r\\n') - title = title:gsub('\n', '\\n') - table.insert(option_strings, string.format('%d. %s', i, title)) - end - - -- window/showMessageRequest can return either MessageActionItem[] or null. - local choice = vim.fn.inputlist(option_strings) - if choice < 1 or choice > #actions then - return vim.NIL + local actions = result.actions or {} + local co, is_main = coroutine.running() + if co and not is_main then + local opts = { + prompt = result.message .. ': ', + format_item = function(action) + return (action.title:gsub('\r\n', '\\r\\n')):gsub('\n', '\\n') + end, + } + vim.ui.select(actions, opts, function(choice) + -- schedule to ensure resume doesn't happen _before_ yield with + -- default synchronous vim.ui.select + vim.schedule(function() + coroutine.resume(co, choice or vim.NIL) + end) + end) + return coroutine.yield() else - return actions[choice] + local option_strings = { result.message, '\nRequest Actions:' } + for i, action in ipairs(actions) do + local title = action.title:gsub('\r\n', '\\r\\n') + title = title:gsub('\n', '\\n') + table.insert(option_strings, string.format('%d. %s', i, title)) + end + local choice = vim.fn.inputlist(option_strings) + if choice < 1 or choice > #actions then + return vim.NIL + else + return actions[choice] + end end end -- cgit From cfdf5e6f372928c11a2b1459b14c4c2de5f69c51 Mon Sep 17 00:00:00 2001 From: Grzegorz Rozdzialik Date: Sat, 19 Nov 2022 12:27:00 +0100 Subject: fix(lsp): ignore hover and signatureHelp responses on buffer change (#21121) Language servers can take some time to respond to the `textDocument/hover` and `textDocument/signatureHelp` messages. During that time, the user could have already moved to another buffer. The popup was always shown in the current buffer, which could be a different one than the buffer for which the request was sent. This was particularly annoying when moving to a buffer with a `BufLeave` autocmd, as that autocmd was triggered when the hover popup was shown for the original buffer. Ignoring the response from these 2 messages if they are for a buffer that is not the current one leads to less noise. The popup will only be shown for the buffer for which it was requested. A more robust solution could involve cancelling the hover/signatureHelp request if the buffer changes so the language server can free its resources. It could be implemented in the future. --- runtime/lua/vim/lsp/handlers.lua | 8 ++++++++ 1 file changed, 8 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 c80adc6a87..8e5e75232f 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -328,6 +328,10 @@ end function M.hover(_, result, ctx, config) config = config or {} config.focus_id = ctx.method + if api.nvim_get_current_buf() ~= ctx.bufnr then + -- Ignore result since buffer changed. This happens for slow language servers. + return + end if not (result and result.contents) then vim.notify('No information available') return @@ -408,6 +412,10 @@ M['textDocument/implementation'] = location_handler function M.signature_help(_, result, ctx, config) config = config or {} config.focus_id = ctx.method + if api.nvim_get_current_buf() ~= ctx.bufnr then + -- Ignore result since buffer changed. This happens for slow language servers. + return + end -- When use `autocmd CompleteDone lua vim.lsp.buf.signature_help()` to call signatureHelp handler -- If the completion item doesn't have signatures It will make noise. Change to use `print` that can use `` to ignore if not (result and result.signatures and result.signatures[1]) then -- cgit From 2bb244af314e80afbab30b4db4490c8dae894b85 Mon Sep 17 00:00:00 2001 From: Raphael Date: Mon, 21 Nov 2022 18:06:14 +0800 Subject: feat(lsp): support set title in lsp relate floatwindow (#21110) --- 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 8e5e75232f..39e2577294 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -317,7 +317,9 @@ end --- vim.lsp.handlers["textDocument/hover"] = vim.lsp.with( --- vim.lsp.handlers.hover, { --- -- Use a sharp border with `FloatBorder` highlights ---- border = "single" +--- border = "single", +--- -- add the title in hover float window +--- title = "hover" --- } --- ) --- -- 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/handlers.lua | 32 ++++++++++++++++---------------- 1 file changed, 16 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 39e2577294..e0162218f1 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -313,15 +313,15 @@ M['textDocument/completion'] = function(_, result, _, _) end --- |lsp-handler| for the method "textDocument/hover" ----
---- 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) @@ -399,13 +399,13 @@ M['textDocument/implementation'] = location_handler --- |lsp-handler| for the method "textDocument/signatureHelp". --- The active parameter is highlighted with |hl-LspSignatureActiveParameter|. ----
---- 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 config table Configuration table. --- - border: (default=nil) -- cgit From 67e1390dc8eb584d26ae9c9634c05acb3b7e37ca Mon Sep 17 00:00:00 2001 From: Mathias Fussenegger Date: Sun, 4 Dec 2022 15:57:46 +0100 Subject: fix(lsp): call show_document with correct args Closes https://github.com/neovim/neovim/issues/21177 --- runtime/lua/vim/lsp/handlers.lua | 5 ++++- 1 file changed, 4 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 e0162218f1..80df83732e 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -579,7 +579,10 @@ M['window/showDocument'] = function(_, result, ctx, _) range = result.selection, } - local success = util.show_document(location, client.offset_encoding, true, result.takeFocus) + local success = util.show_document(location, client.offset_encoding, { + reuse_win = true, + focus = result.takeFocus, + }) return { success = success or false } end -- cgit From 870ca1de52b240926b88f01afa697cd9b119bdac Mon Sep 17 00:00:00 2001 From: Sebastian Lyng Johansen Date: Tue, 10 Jan 2023 11:22:41 +0100 Subject: feat(float): open float relative to mouse #21531 Problem: No easy way to position a LSP hover window relative to mouse. Solution: Introduce another option to the `relative` key in `nvim_open_win()`. With this PR it should be possible to override the handler and do something similar to this https://github.com/neovim/neovim/pull/19481#issuecomment-1193248674 to have hover information displayed from the mouse. Test case: ```lua local util = require('vim.lsp.util') local function make_position_param(window, offset_encoding) window = window or 0 local buf = vim.api.nvim_win_get_buf(window) local row, col local mouse = vim.fn.getmousepos() row = mouse.line col = mouse.column offset_encoding = offset_encoding or util._get_offset_encoding(buf) row = row - 1 local line = vim.api.nvim_buf_get_lines(buf, row, row + 1, true)[1] if not line then return { line = 0, character = 0 } end if #line < col then return { line = 0, character = 0 } end col = util._str_utfindex_enc(line, col, offset_encoding) return { line = row, character = col } end local make_params = function(window, offset_encoding) window = window or 0 local buf = vim.api.nvim_win_get_buf(window) offset_encoding = offset_encoding or util._get_offset_encoding(buf) return { textDocument = util.make_text_document_params(buf), position = make_position_param(window, offset_encoding), } end local hover_timer = nil vim.o.mousemoveevent = true vim.keymap.set({ '', 'i' }, '', function() if hover_timer then hover_timer:close() end hover_timer = vim.defer_fn(function() hover_timer = nil local params = make_params() vim.lsp.buf_request( 0, 'textDocument/hover', params, vim.lsp.with(vim.lsp.handlers.hover, { silent = true, focusable = false, relative = 'mouse', }) ) end, 500) return '' end, { expr = true }) ``` --- 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 80df83732e..b383ca1c35 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -335,7 +335,9 @@ function M.hover(_, result, ctx, config) return end if not (result and result.contents) then - vim.notify('No information available') + if config.silent ~= true then + vim.notify('No information available') + end return end local markdown_lines = util.convert_input_to_markdown_lines(result.contents) -- cgit