aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/news.txt3
-rw-r--r--runtime/lua/vim/lsp/buf.lua58
-rw-r--r--runtime/lua/vim/lsp/handlers.lua25
3 files changed, 56 insertions, 30 deletions
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index f2338331fa..def66a0773 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -77,6 +77,9 @@ LSP
customizing the transformation of an LSP CompletionItem to |complete-items|.
• |vim.lsp.diagnostic.from()| can be used to convert a list of
|vim.Diagnostic| objects into their LSP diagnostic representation.
+• |vim.lsp.buf.references()| now handles multiple clients but no longer
+ triggers the global `textDocument/references` handler from
+ `vim.lsp.handlers`
LUA
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua
index f6837a627f..8803c0495a 100644
--- a/runtime/lua/vim/lsp/buf.lua
+++ b/runtime/lua/vim/lsp/buf.lua
@@ -438,11 +438,59 @@ end
---@param opts? vim.lsp.ListOpts
function M.references(context, opts)
validate('context', context, 'table', true)
- local params = util.make_position_params()
- params.context = context or {
- includeDeclaration = true,
- }
- request_with_opts(ms.textDocument_references, params, opts)
+ local clients = vim.lsp.get_clients({ method = ms.textDocument_references })
+ 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 = {}
+ local title = 'References'
+
+ local function on_done()
+ if not next(all_items) then
+ vim.notify('No references found')
+ else
+ local list = {
+ title = title,
+ items = all_items,
+ context = {
+ method = ms.textDocument_references,
+ bufnr = bufnr,
+ },
+ }
+ if opts.loclist then
+ vim.fn.setloclist(0, {}, ' ', list)
+ vim.cmd.lopen()
+ elseif opts.on_list then
+ assert(vim.is_callable(opts.on_list), 'on_list is not a function')
+ opts.on_list(list)
+ else
+ vim.fn.setqflist({}, ' ', list)
+ vim.cmd('botright copen')
+ end
+ end
+ end
+
+ local remaining = #clients
+ for _, client in ipairs(clients) do
+ local params = util.make_position_params(win, client.offset_encoding)
+
+ ---@diagnostic disable-next-line: inject-field
+ params.context = context or {
+ includeDeclaration = true,
+ }
+ client.request(ms.textDocument_references, params, function(_, result)
+ local items = util.locations_to_items(result or {}, client.offset_encoding)
+ vim.list_extend(all_items, items)
+ remaining = remaining - 1
+ if remaining == 0 then
+ on_done()
+ end
+ end)
+ end
end
--- Lists all symbols in the current buffer in the quickfix window.
diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua
index 8e538242d9..3306e480dd 100644
--- a/runtime/lua/vim/lsp/handlers.lua
+++ b/runtime/lua/vim/lsp/handlers.lua
@@ -242,31 +242,6 @@ M[ms.textDocument_inlayHint] = function(...)
return vim.lsp.inlay_hint.on_inlayhint(...)
end
---- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references
-M[ms.textDocument_references] = function(_, result, ctx, config)
- if not result or vim.tbl_isempty(result) then
- vim.notify('No references found')
- return
- end
-
- local client = assert(vim.lsp.get_client_by_id(ctx.client_id))
- config = config or {}
- local title = 'References'
- local items = util.locations_to_items(result, client.offset_encoding)
-
- local list = { title = title, items = items, context = ctx }
- if config.loclist then
- vim.fn.setloclist(0, {}, ' ', list)
- vim.cmd.lopen()
- elseif config.on_list then
- assert(vim.is_callable(config.on_list), 'on_list is not a function')
- config.on_list(list)
- else
- vim.fn.setqflist({}, ' ', list)
- vim.cmd('botright copen')
- end
-end
-
--- Return a function that converts LSP responses to list items and opens the list
---
--- The returned function has an optional {config} parameter that accepts |vim.lsp.ListOpts|