aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r--runtime/lua/vim/lsp/buf.lua89
-rw-r--r--runtime/lua/vim/lsp/handlers.lua51
-rw-r--r--runtime/lua/vim/lsp/util.lua9
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