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.
This commit is contained in:
Grzegorz Rozdzialik
2022-11-19 12:27:00 +01:00
committed by GitHub
parent 7c57f06b63
commit cfdf5e6f37

View File

@@ -328,6 +328,10 @@ end
function M.hover(_, result, ctx, config) function M.hover(_, result, ctx, config)
config = config or {} config = config or {}
config.focus_id = ctx.method 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 if not (result and result.contents) then
vim.notify('No information available') vim.notify('No information available')
return return
@@ -408,6 +412,10 @@ M['textDocument/implementation'] = location_handler
function M.signature_help(_, result, ctx, config) function M.signature_help(_, result, ctx, config)
config = config or {} config = config or {}
config.focus_id = ctx.method 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 <silent><buffer> lua vim.lsp.buf.signature_help()` to call signatureHelp handler -- When use `autocmd CompleteDone <silent><buffer> 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 `<silent>` to ignore -- If the completion item doesn't have signatures It will make noise. Change to use `print` that can use `<silent>` to ignore
if not (result and result.signatures and result.signatures[1]) then if not (result and result.signatures and result.signatures[1]) then