fix(lsp): callHierarchy/outgoingCalls ranges are relative to caller, not callee #39336

Problem:
The fromRanges field of the result of callHierarchy/outgoingCalls is
documented as being relative to the caller. Using
vim.lsp.buf.outgoing_calls() opened the qflist with an entry with the
callee's filename, but the caller's line number.

Solution:
Open the qflist with the callers file (the bufnr from the request),
rather than the callees (the uri from the resulting CallHierarchyItem)

(cherry picked from commit 7e006b06c4)
This commit is contained in:
Ashley Hauck
2026-04-23 14:20:58 +02:00
committed by github-actions[bot]
parent 39e8c584d5
commit 93dc301781
2 changed files with 14 additions and 4 deletions

View File

@@ -519,7 +519,8 @@ end
--- @overload fun(direction:'to'): fun(_, result: lsp.CallHierarchyOutgoingCall[]?)
local function make_call_hierarchy_handler(direction)
--- @param result lsp.CallHierarchyIncomingCall[]|lsp.CallHierarchyOutgoingCall[]
return function(_, result)
--- @param ctx lsp.HandlerContext
return function(_, result, ctx)
if not result then
return
end
@@ -527,9 +528,17 @@ local function make_call_hierarchy_handler(direction)
for _, call_hierarchy_call in pairs(result) do
--- @type lsp.CallHierarchyItem
local call_hierarchy_item = call_hierarchy_call[direction]
local filename = nil
local bufnr = nil
if direction == 'from' then
filename = assert(vim.uri_to_fname(call_hierarchy_item.uri))
else
bufnr = ctx.bufnr
end
for _, range in pairs(call_hierarchy_call.fromRanges) do
table.insert(items, {
filename = assert(vim.uri_to_fname(call_hierarchy_item.uri)),
filename = filename,
bufnr = bufnr,
text = call_hierarchy_item.name,
lnum = range.start.line + 1,
col = range.start.character + 1,

View File

@@ -106,13 +106,14 @@ describe('vim.lsp.buf', function()
},
}
local handler = require 'vim.lsp.handlers'['callHierarchy/outgoingCalls']
handler(nil, rust_analyzer_response, {})
local bufnr = vim.api.nvim_get_current_buf()
handler(nil, rust_analyzer_response, { bufnr = bufnr })
return vim.fn.getqflist()
end)
local expected = {
{
bufnr = 2,
bufnr = 1,
col = 5,
end_col = 0,
lnum = 4,