diff options
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r-- | runtime/lua/vim/lsp/buf.lua | 89 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/handlers.lua | 51 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 9 |
3 files changed, 81 insertions, 68 deletions
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 8803c0495a..7bf3565499 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -50,6 +50,79 @@ local function request_with_opts(name, params, opts) request(name, params, req_handler) end +---@param method string +---@param opts? vim.lsp.LocationOpts +local function get_locations(method, opts) + opts = opts or {} + local bufnr = api.nvim_get_current_buf() + local clients = vim.lsp.get_clients({ method = method, bufnr = bufnr }) + if not next(clients) then + vim.notify(vim.lsp._unsupported_method(method), vim.log.levels.WARN) + return + end + local win = api.nvim_get_current_win() + local remaining = #clients + + ---@type vim.quickfix.entry[] + local all_items = {} + + ---@param result nil|lsp.Location|lsp.Location[] + ---@param client vim.lsp.Client + local function on_response(_, result, client) + local locations = {} + if result then + locations = vim.islist(result) and result or { result } + end + local items = util.locations_to_items(locations, client.offset_encoding) + vim.list_extend(all_items, items) + remaining = remaining - 1 + if remaining == 0 then + if vim.tbl_isempty(all_items) then + vim.notify('No locations found', vim.log.levels.INFO) + return + end + + local title = 'LSP locations' + if opts.on_list then + assert(vim.is_callable(opts.on_list), 'on_list is not a function') + opts.on_list({ + title = title, + items = all_items, + context = { bufnr = bufnr, method = method }, + }) + return + end + + if #all_items == 1 then + local item = all_items[1] + local b = item.bufnr or vim.fn.bufadd(item.filename) + vim.bo[b].buflisted = true + local w = opts.reuse_win and vim.fn.win_findbuf(b)[1] or win + api.nvim_win_set_buf(w, b) + api.nvim_win_set_cursor(w, { item.lnum, item.col - 1 }) + vim._with({ win = w }, function() + -- Open folds under the cursor + vim.cmd('normal! zv') + end) + return + end + if opts.loclist then + vim.fn.setloclist(0, {}, ' ', { title = title, items = all_items }) + vim.cmd.lopen() + else + vim.fn.setqflist({}, ' ', { title = title, items = all_items }) + vim.cmd('botright copen') + end + end + end + for _, client in ipairs(clients) do + local params = util.make_position_params(win, client.offset_encoding) + client.request(method, params, function(_, result) + on_response(_, result, client) + end) + end +end + --- @class vim.lsp.ListOpts --- --- list-handler replacing the default handler. @@ -87,30 +160,26 @@ end --- @note Many servers do not implement this method. Generally, see |vim.lsp.buf.definition()| instead. --- @param opts? vim.lsp.LocationOpts function M.declaration(opts) - local params = util.make_position_params() - request_with_opts(ms.textDocument_declaration, params, opts) + get_locations(ms.textDocument_declaration, opts) end --- Jumps to the definition of the symbol under the cursor. --- @param opts? vim.lsp.LocationOpts function M.definition(opts) - local params = util.make_position_params() - request_with_opts(ms.textDocument_definition, params, opts) + get_locations(ms.textDocument_definition, opts) end --- Jumps to the definition of the type of the symbol under the cursor. --- @param opts? vim.lsp.LocationOpts function M.type_definition(opts) - local params = util.make_position_params() - request_with_opts(ms.textDocument_typeDefinition, params, opts) + get_locations(ms.textDocument_typeDefinition, opts) end --- Lists all the implementations for the symbol under the cursor in the --- quickfix window. --- @param opts? vim.lsp.LocationOpts function M.implementation(opts) - local params = util.make_position_params() - request_with_opts(ms.textDocument_implementation, params, opts) + get_locations(ms.textDocument_implementation, opts) end --- Displays signature information about the symbol under the cursor in a @@ -438,12 +507,12 @@ end ---@param opts? vim.lsp.ListOpts function M.references(context, opts) validate('context', context, 'table', true) - local clients = vim.lsp.get_clients({ method = ms.textDocument_references }) + local bufnr = api.nvim_get_current_buf() + local clients = vim.lsp.get_clients({ method = ms.textDocument_references, bufnr = bufnr }) if not next(clients) then return end local win = api.nvim_get_current_win() - local bufnr = api.nvim_get_current_buf() opts = opts or {} local all_items = {} diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 3306e480dd..c87cf94b98 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -386,57 +386,6 @@ end --- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_hover M[ms.textDocument_hover] = M.hover ---- 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. ----@param ctx (lsp.HandlerContext) table containing the context of the request, including the method ----@param config? vim.lsp.LocationOpts ----(`textDocument/definition` can return `Location` or `Location[]` -local function location_handler(_, result, ctx, config) - if result == nil or vim.tbl_isempty(result) then - log.info(ctx.method, 'No location found') - return nil - end - local client = assert(vim.lsp.get_client_by_id(ctx.client_id)) - - config = config or {} - - -- textDocument/definition can return Location or Location[] - -- https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_definition - if not vim.islist(result) then - result = { result } - end - - local title = 'LSP locations' - local items = util.locations_to_items(result, client.offset_encoding) - - if config.on_list then - assert(vim.is_callable(config.on_list), '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 - if config.loclist then - vim.fn.setloclist(0, {}, ' ', { title = title, items = items }) - vim.cmd.lopen() - else - vim.fn.setqflist({}, ' ', { title = title, items = items }) - vim.cmd('botright copen') - end -end - ---- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_declaration -M[ms.textDocument_declaration] = location_handler ---- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_definition -M[ms.textDocument_definition] = location_handler ---- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_typeDefinition -M[ms.textDocument_typeDefinition] = location_handler ---- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_implementation -M[ms.textDocument_implementation] = location_handler - local sig_help_ns = api.nvim_create_namespace('vim_lsp_signature_help') --- |lsp-handler| for the method "textDocument/signatureHelp". diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 83c8226326..2c28633e3c 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -1023,18 +1023,13 @@ end --- Jumps to a location. --- +---@deprecated ---@param location lsp.Location|lsp.LocationLink ---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'? ---@param reuse_win boolean? Jump to existing window if buffer is already open. ---@return boolean `true` if the jump succeeded function M.jump_to_location(location, offset_encoding, reuse_win) - if offset_encoding == nil then - vim.notify_once( - 'jump_to_location must be called with valid offset encoding', - vim.log.levels.WARN - ) - end - + vim.deprecate('vim.lsp.util.jump_to_location', nil, '0.12') return M.show_document(location, offset_encoding, { reuse_win = reuse_win, focus = true }) end |