Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(lsp)!: change handler signature #15504

Merged
merged 2 commits into from Sep 5, 2021
Merged

feat(lsp)!: change handler signature #15504

merged 2 commits into from Sep 5, 2021

Conversation

mjlbach
Copy link
Contributor

@mjlbach mjlbach commented Aug 28, 2021

Previously, the handler signature was:

function(err, method, params, client_id, bufnr, config)

In order to better support external plugins that wish to extend the
protocol, there is other information which would be advantageous to
forward to the client, such as the original params of the request that
generated the callback.

In order to do this, we would need to break symmetry of the handlers, to
add an additional "params" as the 7th argument.

Instead, this PR changes the signature of the handlers to:

function(err, result, context, config)

where context includes params, client_id, and bufnr. This also leaves
flexibility for future use-cases.

Todos:

  • fix tests
  • make sure I didn't break anything
  • update docs
  • warn plugin authors
  • Decide what to do about compatibility question

@mjlbach mjlbach changed the title Feat/change handler signature lsp: change handler signature Aug 28, 2021
@jose-elias-alvarez
Copy link
Contributor

Looks great! Do you think it would make sense to handle #15174 here, too, since the PR modifies the interaction between buf_request and buf_request_all? As far as I can tell, the implementation here will run into the same nil index issue, since context.client_id will be nil if no client supports a given method. (My PR to fix that issue seems to have stalled and is incompatible with the changes here, anyways.)

runtime/lua/vim/lsp.lua Outdated Show resolved Hide resolved
@mjlbach
Copy link
Contributor Author

mjlbach commented Aug 28, 2021

Looks great! Do you think it would make sense to handle #15174 here, too, since the PR modifies the interaction between buf_request and buf_request_all? As far as I can tell, the implementation here will run into the same nil index issue, since context.client_id will be nil if no client supports a given method. (My PR to fix that issue seems to have stalled and is incompatible with the changes here, anyways.)

I think that is out of scope of this PR, but I will rebase and review your PR after this.

@mjlbach mjlbach marked this pull request as ready for review August 29, 2021 16:53
@mjlbach mjlbach changed the title lsp: change handler signature feat(lsp): change handler signature Aug 29, 2021
@mjlbach
Copy link
Contributor Author

mjlbach commented Aug 29, 2021

A couple notes, I changed result to params in a few places for "consistency" but maybe I should not have done this, as params is codified in the spec. LMK what you think.

@mjlbach
Copy link
Contributor Author

mjlbach commented Aug 29, 2021

@ray-x @jose-elias-alvarez @hrsh7th @glepnir @akinsho @simrat39 this is a warning that (although we will not be merging this yet) it will break your plugins that rely on overriding handlers (also lmk if there were any obvious plugin authors I missed)

@ms-jpq
Copy link

ms-jpq commented Aug 29, 2021

this breaks existing buf_request handlers right?

@mjlbach
Copy link
Contributor Author

mjlbach commented Aug 29, 2021

@ms-jpq I knew there was someone I forgot :)

The function signature for buf_request itself is the same, but the handler passed to the handler argument follows the new pattern.

@ms-jpq
Copy link

ms-jpq commented Aug 29, 2021

thanks :)

so config is always a table and never nil right? then we can just check how many elements are in the function argument?, and do it that way.

no version detection required

@mjlbach
Copy link
Contributor Author

mjlbach commented Aug 29, 2021

@ms-jpq config can be nil, but if nil is set to an empty table within the handler. I'd recommend using the wrapper I added in vim.lsp.compat and vim.fn.has('nvim-0.5.1') to gate which handler paradigm you use, we'll push this change to 0.5.1 so it shouldn't be too disruptive (hopefully...)

@ms-jpq
Copy link

ms-jpq commented Aug 29, 2021

haha yeah, but it would break all the things for people who havn't updated the plugins though.

I think Ill just use bufnr on arg position 5 as a gate, then you are free to do whatever with the version numbers 👍

@ms-jpq
Copy link

ms-jpq commented Aug 29, 2021

anyways, thank you for letting us know early 💯

runtime/doc/lsp.txt Outdated Show resolved Hide resolved
runtime/lua/vim/lsp.lua Outdated Show resolved Hide resolved
runtime/lua/vim/lsp.lua Outdated Show resolved Hide resolved
runtime/lua/vim/lsp.lua Outdated Show resolved Hide resolved
runtime/lua/vim/lsp.lua Outdated Show resolved Hide resolved
runtime/lua/vim/lsp.lua Outdated Show resolved Hide resolved

M.wrap_05_handler = function(handler)
return function(err, result, context, config)
return handler(err, context.method, result, context.client_id, context.bufnr, config)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks like something that can be copy-pasted into any project. So we can document it, but we don't need to introduce this compat module into the API and then later deal with removing it (thus duplicating the migration issue we're already trying to deal with now)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just thinking how to adapt the handlers in my plugins so that they work with all three: 0.5, master prior this change and master with this change.

And that would require some kind of feature or version check.
With the current PR state I'd probably create something like this:

function M.mk_handler(fn)
  if vim.lsp.compat then
    return vim.lsp.compat.wrap_05_handler(fn)
  end
  return fn
end

Implementing the wrap_05_handler isn't the issue, but some kind of marker that can be checked at runtime to see which signature format is used would be good. nvim-0.6 won't be granular enough, as it would also return true for versions after 0.5, but before this change.

Copy link
Member

@justinmk justinmk Aug 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nvim-0.6 won't be granular enough, as it would also return true for versions after 0.5, but before this change.

:echo has('nvim-0.5.1') is granular. Your function would be:

function M.mk_handler(fn)
  if vim.fn.has('nvim-0.5.1') then
    return function(err, result, context, config)
      return fn(err, context.method, result, context.client_id, context.bufnr, config)
    end
  end
  return fn
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vim.fn.has('nvim-0.5.1') would also return true for the current master (without this change, using the old signature)

I guess it is acceptable that master/plugin combinations are broken for a bit, but if there were some check for patch-level or signature-format level, plugins could make the transition seamless. (At least if they adapt the code before this PR is merged)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like the following might work to keep compatiblity with all 3 variants:

function M.mk_handler(fn)
  return function(...)
    local is_new = type(select(4, ...)) ~= 'number'
    if is_new then
      fn(...)
    else
      local err = select(1, ...)
      local method = select(2, ...)
      local result = select(3, ...)
      local client_id = select(4, ...)
      local bufnr = select(5, ...)
      local config = select(6, ...)
      fn(err, result, { method = method, client_id = client_id, bufnr = bufnr }, config)
    end
  end
end

So +1 from my side to remove vim.lsp.compat from this PR

@justinmk justinmk changed the title feat(lsp): change handler signature feat(lsp)!: change handler signature Aug 29, 2021
Comment on lines 464 to 463
local _ = log.debug() and log.debug('default_handler', method, {
params = params, client_id = client_id, err = err, bufnr = bufnr, config = config
result = result, client_id = client_id, err = err, bufnr = bufnr, config = config
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth logging the context with vim.inspect, to ensure this automatically logs everything if the context gets extended.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vim.inspect has a runtime cost though right? I guess it's fine since this is only done if the user is using debug

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd think the overhead is acceptable given that it is logged on debug level and that is not enabled by default.

@mjlbach
Copy link
Contributor Author

mjlbach commented Aug 29, 2021

I think I have addressed all of the comments.

The main remaining to-do is to figure out the compatibility question:

  1. Do we include a compat module (originally suggested by TJ) or just document here/in breaking changes issue how to work around this in plugins?
  2. Do we do a runtime compatibility check somehow for testing if users are using old argument style (possible runtime cost)
  3. How long do we wait after this warning to plugin authors to merge this PR? Certain plugins (lspsaga) are not likely to be updated. I propose 1 week from today.

I think we can release 0.5.1 after this (from an LSP perspective at least), however, we either need to fix, or not backport the URI changes that caused #15261

weilbith added a commit to weilbith/nvim-lightbulb that referenced this pull request Sep 25, 2021
The signature for LSP handler function has changed in neovim/neovim#15504.
While in the past the third passed argument was the result (i.e. the actions) it
is now the second. The third argument is now the context which is never nil or
empty. As result the light bulb was always displayed at any location. The
evaluation if there is a code action or not was simply broken.
m-pilia added a commit to m-pilia/vim-ccls that referenced this pull request Sep 26, 2021
Support new LSP handler API introduced in neovim/neovim#15504
justinmk pushed a commit to justinmk/neovim that referenced this pull request Sep 26, 2021
justinmk pushed a commit to justinmk/neovim that referenced this pull request Sep 26, 2021
justinmk added a commit to justinmk/neovim that referenced this pull request Sep 26, 2021
BREAKING CHANGES:
d83df7f feat(lua)!: register_keystroke_callback => on_key
cd8f6c5 feat(lsp)!: change handler signature neovim#15504

FEATURES:
915dda3 feat(jobstart): add parameter to close stdin

FIXES:
f8e0011 neovim#15732 fix(inccommand): ignore trailing commands only for *previewed* command
2132c06 backport: fix(windowing): positioning of relative floats
51d6b26 neovim#15495 backport: tests(lua/on_yank): assert conditions that fail correctly
f700233 neovim#15482 backport: fix(lua): verify buffer in highlight.on_yank
6bda2f5 neovim#15454 backport: fix(window.c): win_close from other tabpage
be58ba2 neovim#15372 backport: fix(autocmd.c): fix conditions in block_autocmds, unblock_autocmds
d0e9a11 backport: refactor(sign): include longer sign column option
5c42376 backport: fix(sign): reset auto sign column with minimum in float win minimal style
41f7611 backport: fix(decorations): crash when :bdelete (extmark_free_all) after clear_namespace
cf62554 neovim#15111 backport: fix(:source): copy curbuf lines to memory before sourcing
6436100 neovim#14809 backport: fix(:source, nvim_exec): handle Vimscript line continuations
917f306 neovim#15043 backport: test/memory_usage_spec: skip on MacOS
a9cca1b neovim#14984 backport: fixup(clipboard): Fix error not properly handled
ae89330 neovim#14982 backport: fix(vim.opt): vimL map string values not trimmed
2229e99 neovim#14962 backport: fixup(clipboard): Use case matching
b6b12ea neovim#15489 fix(man.vim): filetype=man is too eager
6f965f4 build: use RelWithDebInfo build for nightlies, Release for releases
f027c5e build: update appdata.xml version in release commit
8336488 test(treesitter): skip all parsers tests if parsers aren't installed
008b83f Rename stdin to stdin_mode (fixes Windows build)

FIXES (LSP):
132053c neovim#15523 backport: fix(lsp): resolve bufnr in buf_is_attached
a265201 backport: fix(lsp): Ensure human readable errors are printed
33000bd backport: fix(lsp): Ensure users get feedback on references/symbols errors or empty results
9f73b7c neovim#14954 backport: fix(lsp): correctly check for windows in lsp logger
eaa1c47 neovim#15023 backport: fix(lsp): restore diagnostics extmarks that were moved to the last edit line
989ccb8 neovim#15011 backport: fix(lsp): restore diagnostics extmarks on buffer changes
2ae4c96 backport: fix(lsp): prevent double <text> for cached plaintext markup
justinmk added a commit to justinmk/neovim that referenced this pull request Sep 26, 2021
BREAKING CHANGES:
d83df7f feat(lua)!: register_keystroke_callback => on_key
cd8f6c5 feat(lsp)!: change handler signature neovim#15504

FEATURES:
915dda3 feat(jobstart): add parameter to close stdin

FIXES:
f8e0011 neovim#15732 fix(inccommand): ignore trailing commands only for *previewed* command
2132c06 backport: fix(windowing): positioning of relative floats
51d6b26 neovim#15495 backport: tests(lua/on_yank): assert conditions that fail correctly
f700233 neovim#15482 backport: fix(lua): verify buffer in highlight.on_yank
6bda2f5 neovim#15454 backport: fix(window.c): win_close from other tabpage
be58ba2 neovim#15372 backport: fix(autocmd.c): fix conditions in block_autocmds, unblock_autocmds
d0e9a11 backport: refactor(sign): include longer sign column option
5c42376 backport: fix(sign): reset auto sign column with minimum in float win minimal style
41f7611 backport: fix(decorations): crash when :bdelete (extmark_free_all) after clear_namespace
cf62554 neovim#15111 backport: fix(:source): copy curbuf lines to memory before sourcing
6436100 neovim#14809 backport: fix(:source, nvim_exec): handle Vimscript line continuations
917f306 neovim#15043 backport: test/memory_usage_spec: skip on MacOS
a9cca1b neovim#14984 backport: fixup(clipboard): Fix error not properly handled
ae89330 neovim#14982 backport: fix(vim.opt): vimL map string values not trimmed
2229e99 neovim#14962 backport: fixup(clipboard): Use case matching
b6b12ea neovim#15489 fix(man.vim): filetype=man is too eager
6f965f4 build: use RelWithDebInfo build for nightlies, Release for releases
f027c5e build: update appdata.xml version in release commit
8336488 test(treesitter): skip all parsers tests if parsers aren't installed
008b83f Rename stdin to stdin_mode (fixes Windows build)

FIXES (LSP):
132053c neovim#15523 backport: fix(lsp): resolve bufnr in buf_is_attached
a265201 backport: fix(lsp): Ensure human readable errors are printed
33000bd backport: fix(lsp): Ensure users get feedback on references/symbols errors or empty results
9f73b7c neovim#14954 backport: fix(lsp): correctly check for windows in lsp logger
eaa1c47 neovim#15023 backport: fix(lsp): restore diagnostics extmarks that were moved to the last edit line
989ccb8 neovim#15011 backport: fix(lsp): restore diagnostics extmarks on buffer changes
2ae4c96 backport: fix(lsp): prevent double <text> for cached plaintext markup
7b0ae58 feat(lsp): allow root_dir to be nil (neovim#15430) (Mathias Fußenegger)
8ec5bc9 lsp(start_client): Allow passing custom workspaceFolders to the LSP (neovim#15132) (sim)
959cf5e fix(lsp): check if buffer is valid in changetracking (neovim#15505) (Jose Alvarez)
dc15b3a fix(lsp): avoid ipairs on non-sequential tables (neovim#15059) (Michael Lingelbach)
18375c6 feat(lsp): improve vim.lsp.util.apply_text_edits (neovim#15561) (hrsh7th)
7b1315f feat(lsp): improve logging (neovim#15636) (Michael Lingelbach)
justinmk added a commit to justinmk/neovim that referenced this pull request Sep 26, 2021
BREAKING CHANGES:
d83df7f feat(lua)!: register_keystroke_callback => on_key
cd8f6c5 feat(lsp)!: change handler signature neovim#15504

FEATURES:
915dda3 feat(jobstart): add parameter to close stdin

FIXES:
f8e0011 neovim#15732 fix(inccommand): ignore trailing commands only for *previewed* command
2132c06 backport: fix(windowing): positioning of relative floats
51d6b26 neovim#15495 backport: tests(lua/on_yank): assert conditions that fail correctly
f700233 neovim#15482 backport: fix(lua): verify buffer in highlight.on_yank
6bda2f5 neovim#15454 backport: fix(window.c): win_close from other tabpage
be58ba2 neovim#15372 backport: fix(autocmd.c): fix conditions in block_autocmds, unblock_autocmds
d0e9a11 backport: refactor(sign): include longer sign column option
5c42376 backport: fix(sign): reset auto sign column with minimum in float win minimal style
41f7611 backport: fix(decorations): crash when :bdelete (extmark_free_all) after clear_namespace
cf62554 neovim#15111 backport: fix(:source): copy curbuf lines to memory before sourcing
6436100 neovim#14809 backport: fix(:source, nvim_exec): handle Vimscript line continuations
917f306 neovim#15043 backport: test/memory_usage_spec: skip on MacOS
a9cca1b neovim#14984 backport: fixup(clipboard): Fix error not properly handled
ae89330 neovim#14982 backport: fix(vim.opt): vimL map string values not trimmed
2229e99 neovim#14962 backport: fixup(clipboard): Use case matching
b6b12ea neovim#15489 fix(man.vim): filetype=man is too eager
6f965f4 build: use RelWithDebInfo build for nightlies, Release for releases
f027c5e build: update appdata.xml version in release commit
8336488 test(treesitter): skip all parsers tests if parsers aren't installed
008b83f Rename stdin to stdin_mode (fixes Windows build)

FIXES (LSP):
132053c neovim#15523 backport: fix(lsp): resolve bufnr in buf_is_attached
a265201 backport: fix(lsp): Ensure human readable errors are printed
33000bd backport: fix(lsp): Ensure users get feedback on references/symbols errors or empty results
9f73b7c neovim#14954 backport: fix(lsp): correctly check for windows in lsp logger
eaa1c47 neovim#15023 backport: fix(lsp): restore diagnostics extmarks that were moved to the last edit line
989ccb8 neovim#15011 backport: fix(lsp): restore diagnostics extmarks on buffer changes
2ae4c96 backport: fix(lsp): prevent double <text> for cached plaintext markup
7b0ae58 feat(lsp): allow root_dir to be nil (neovim#15430) (Mathias Fußenegger)
8ec5bc9 lsp(start_client): Allow passing custom workspaceFolders to the LSP (neovim#15132) (sim)
959cf5e fix(lsp): check if buffer is valid in changetracking (neovim#15505) (Jose Alvarez)
dc15b3a fix(lsp): avoid ipairs on non-sequential tables (neovim#15059) (Michael Lingelbach)
18375c6 feat(lsp): improve vim.lsp.util.apply_text_edits (neovim#15561) (hrsh7th)
7b1315f feat(lsp): improve logging (neovim#15636) (Michael Lingelbach)
justinmk added a commit to justinmk/neovim that referenced this pull request Sep 26, 2021
- not necessary on master: got lost in the vim.lsp.diagnostic => vim.diagnostic migration
- ref neovim#15504
justinmk added a commit to justinmk/neovim that referenced this pull request Sep 26, 2021
- not necessary on master: got lost in the vim.lsp.diagnostic => vim.diagnostic migration
- fix tests which accidentally depended on previous session
- ref neovim#15504
justinmk added a commit to justinmk/neovim that referenced this pull request Sep 26, 2021
BREAKING CHANGES:
d83df7f feat(lua)!: register_keystroke_callback => on_key
cd8f6c5 feat(lsp)!: change handler signature neovim#15504

FEATURES:
915dda3 feat(jobstart): add parameter to close stdin

FIXES:
f8e0011 neovim#15732 fix(inccommand): ignore trailing commands only for *previewed* command
2132c06 backport: fix(windowing): positioning of relative floats
51d6b26 neovim#15495 backport: tests(lua/on_yank): assert conditions that fail correctly
f700233 neovim#15482 backport: fix(lua): verify buffer in highlight.on_yank
6bda2f5 neovim#15454 backport: fix(window.c): win_close from other tabpage
be58ba2 neovim#15372 backport: fix(autocmd.c): fix conditions in block_autocmds, unblock_autocmds
d0e9a11 backport: refactor(sign): include longer sign column option
5c42376 backport: fix(sign): reset auto sign column with minimum in float win minimal style
41f7611 backport: fix(decorations): crash when :bdelete (extmark_free_all) after clear_namespace
cf62554 neovim#15111 backport: fix(:source): copy curbuf lines to memory before sourcing
6436100 neovim#14809 backport: fix(:source, nvim_exec): handle Vimscript line continuations
917f306 neovim#15043 backport: test/memory_usage_spec: skip on MacOS
a9cca1b neovim#14984 backport: fixup(clipboard): Fix error not properly handled
ae89330 neovim#14982 backport: fix(vim.opt): vimL map string values not trimmed
2229e99 neovim#14962 backport: fixup(clipboard): Use case matching
b6b12ea neovim#15489 fix(man.vim): filetype=man is too eager
6f965f4 build: use RelWithDebInfo build for nightlies, Release for releases
f027c5e build: update appdata.xml version in release commit
8336488 test(treesitter): skip all parsers tests if parsers aren't installed
008b83f Rename stdin to stdin_mode (fixes Windows build)

FIXES (LSP):
132053c neovim#15523 backport: fix(lsp): resolve bufnr in buf_is_attached
a265201 backport: fix(lsp): Ensure human readable errors are printed
33000bd backport: fix(lsp): Ensure users get feedback on references/symbols errors or empty results
9f73b7c neovim#14954 backport: fix(lsp): correctly check for windows in lsp logger
eaa1c47 neovim#15023 backport: fix(lsp): restore diagnostics extmarks that were moved to the last edit line
989ccb8 neovim#15011 backport: fix(lsp): restore diagnostics extmarks on buffer changes
2ae4c96 backport: fix(lsp): prevent double <text> for cached plaintext markup
7b0ae58 feat(lsp): allow root_dir to be nil (neovim#15430) (Mathias Fußenegger)
8ec5bc9 lsp(start_client): Allow passing custom workspaceFolders to the LSP (neovim#15132) (sim)
959cf5e fix(lsp): check if buffer is valid in changetracking (neovim#15505) (Jose Alvarez)
dc15b3a fix(lsp): avoid ipairs on non-sequential tables (neovim#15059) (Michael Lingelbach)
18375c6 feat(lsp): improve vim.lsp.util.apply_text_edits (neovim#15561) (hrsh7th)
7b1315f feat(lsp): improve logging (neovim#15636) (Michael Lingelbach)
stasjok added a commit to stasjok/dotfiles that referenced this pull request Oct 1, 2021
Neovim v0.5.1 introduced a breaking change by changing
lsp handler signature.
See: neovim/neovim#15504
I have to update lsp-related plugins.
rafamadriz pushed a commit to rafamadriz/NeoCode that referenced this pull request Oct 2, 2021
rafamadriz pushed a commit to rafamadriz/NeoCode that referenced this pull request Oct 2, 2021
Eyenseo added a commit to Eyenseo/vim-lsp-cxx-highlight that referenced this pull request Oct 16, 2021
neovim/neovim#15504 broke the signature in the
most unfavourable way possible. This patch should be backwards
compatible.
sodiumjoe added a commit to sodiumjoe/dotfiles that referenced this pull request Oct 30, 2021
jdhao added a commit to jdhao/nvim-config that referenced this pull request Nov 6, 2021
In nvim 0.5.1, the lsp handler signature has changed, see neovim/neovim#15504
and LunarVim/LunarVim#1484.
ckipp01 added a commit to ckipp01/nvim-metals that referenced this pull request Dec 7, 2021
This is a breaking change for anyone that was overriding handlers in the
old 0.5 way of doing them. Please see this for more details:

neovim/neovim#15504

Keep in mind that the new format for hanlders is:

```
function(err, result, context, config)
```
lewis6991 pushed a commit to lewis6991/neovim that referenced this pull request Dec 12, 2021
@dundargoc dundargoc removed the request for review from tjdevries October 3, 2022 09:57
rafamadriz added a commit to rafamadriz/NeoCode that referenced this pull request Apr 28, 2023
rafamadriz added a commit to rafamadriz/NeoCode that referenced this pull request Apr 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants