neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit adbe7f368397da21465f27181e254dd3694820e9
parent c1a93285d25be8c832eceecc440e6128b773dc01
Author: Evgeni Chasnovski <evgeni.chasnovski@gmail.com>
Date:   Tue, 31 Oct 2023 14:18:44 +0200

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.
Diffstat:
Mruntime/doc/lsp.txt | 16++++++++--------
Mruntime/lua/vim/lsp/buf.lua | 12++++++++----
Mruntime/lua/vim/lsp/handlers.lua | 31+++++++++++++++----------------
3 files changed, 31 insertions(+), 28 deletions(-)

diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt @@ -1179,8 +1179,8 @@ declaration({options}) *vim.lsp.buf.declaration()* • {options} (table|nil) additional options • reuse_win: (boolean) Jump to existing window if buffer is already open. - • on_list: (function) handler for list results. See - |lsp-on-list-handler| + • on_list: (function) |lsp-on-list-handler| replacing the + default handler. Called for any non-empty result. definition({options}) *vim.lsp.buf.definition()* Jumps to the definition of the symbol under the cursor. @@ -1189,8 +1189,8 @@ definition({options}) *vim.lsp.buf.definition()* • {options} (table|nil) additional options • reuse_win: (boolean) Jump to existing window if buffer is already open. - • on_list: (function) handler for list results. See - |lsp-on-list-handler| + • on_list: (function) |lsp-on-list-handler| replacing the + default handler. Called for any non-empty result. document_highlight() *vim.lsp.buf.document_highlight()* Send request to the server to resolve document highlights for the current @@ -1271,8 +1271,8 @@ implementation({options}) *vim.lsp.buf.implementation()* Parameters: ~ • {options} (table|nil) additional options - • on_list: (function) handler for list results. See - |lsp-on-list-handler| + • on_list: (function) |lsp-on-list-handler| replacing the + default handler. Called for any non-empty result. incoming_calls() *vim.lsp.buf.incoming_calls()* Lists all the call sites of the symbol under the cursor in the |quickfix| @@ -1329,8 +1329,8 @@ type_definition({options}) *vim.lsp.buf.type_definition()* • {options} (table|nil) additional options • reuse_win: (boolean) Jump to existing window if buffer is already open. - • on_list: (function) handler for list results. See - |lsp-on-list-handler| + • on_list: (function) |lsp-on-list-handler| replacing the + default handler. Called for any non-empty result. workspace_symbol({query}, {options}) *vim.lsp.buf.workspace_symbol()* Lists all symbols in the current workspace in the quickfix window. diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua @@ -62,7 +62,8 @@ end --- ---@param options table|nil additional options --- - reuse_win: (boolean) Jump to existing window if buffer is already open. ---- - on_list: (function) handler for list results. See |lsp-on-list-handler| +--- - on_list: (function) |lsp-on-list-handler| replacing the default handler. +--- Called for any non-empty result. function M.declaration(options) local params = util.make_position_params() request_with_options(ms.textDocument_declaration, params, options) @@ -72,7 +73,8 @@ end --- ---@param options table|nil additional options --- - reuse_win: (boolean) Jump to existing window if buffer is already open. ---- - on_list: (function) handler for list results. See |lsp-on-list-handler| +--- - on_list: (function) |lsp-on-list-handler| replacing the default handler. +--- Called for any non-empty result. function M.definition(options) local params = util.make_position_params() request_with_options(ms.textDocument_definition, params, options) @@ -82,7 +84,8 @@ end --- ---@param options table|nil additional options --- - reuse_win: (boolean) Jump to existing window if buffer is already open. ---- - on_list: (function) handler for list results. See |lsp-on-list-handler| +--- - on_list: (function) |lsp-on-list-handler| replacing the default handler. +--- Called for any non-empty result. function M.type_definition(options) local params = util.make_position_params() request_with_options(ms.textDocument_typeDefinition, params, options) @@ -92,7 +95,8 @@ end --- quickfix window. --- ---@param options table|nil additional options ---- - on_list: (function) handler for list results. See |lsp-on-list-handler| +--- - on_list: (function) |lsp-on-list-handler| replacing the default handler. +--- Called for any non-empty result. function M.implementation(options) local params = util.make_position_params() request_with_options(ms.textDocument_implementation, params, options) diff --git 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