navigator.lua/lua/navigator/reference.lua

225 lines
6.7 KiB
Lua
Raw Normal View History

2021-12-12 23:42:53 +00:00
local util = require('navigator.util')
local mk_handler = util.mk_handler
2021-04-26 11:45:45 +00:00
local log = util.log
2021-12-12 23:42:53 +00:00
local lsphelper = require('navigator.lspwrapper')
local gui = require('navigator.gui')
local lsp = require('navigator.lspwrapper')
local trace = require('navigator.util').trace
ListViewCtrl = ListViewCtrl or require('guihua.listviewctrl').ListViewCtrl
2021-04-19 02:56:32 +00:00
-- local partial = util.partial
-- local cwd = vim.loop.cwd()
2021-04-19 02:56:32 +00:00
-- local lsphelper = require "navigator.lspwrapper"
local locations_to_items = lsphelper.locations_to_items
local M = {}
local ref_view = function(err, locations, ctx, cfg)
local truncate = cfg and cfg.truncate or 20
2021-04-19 02:56:32 +00:00
local opts = {}
2021-12-12 23:42:53 +00:00
trace('arg1', err, ctx, locations)
trace(locations)
2021-12-23 08:17:48 +00:00
if ctx.combine then
-- wait for both request
2021-12-24 06:48:54 +00:00
if ctx.results == nil then
return
end
2022-02-17 11:21:34 +00:00
if (ctx.results.definitions == nil) or (ctx.results.references == nil) then
2021-12-23 08:17:48 +00:00
log('not all requests returned')
return
end
local definitions = ctx.results.definitions
local references = ctx.results.references
2022-02-17 11:21:34 +00:00
log(ctx)
2021-12-23 08:17:48 +00:00
if definitions.error and references.error then
2021-12-29 04:50:41 +00:00
vim.notify('lsp ref callback error' .. vim.inspect(ctx.result), vim.lsp.log_levels.WARN)
2021-12-23 08:17:48 +00:00
end
locations = {}
2022-02-17 11:21:34 +00:00
if definitions and definitions.result then
2021-12-23 08:17:48 +00:00
for i, _ in ipairs(definitions.result) do
definitions.result[i].definition = true
end
vim.list_extend(locations, definitions.result)
end
2022-02-17 11:21:34 +00:00
if references and references.result and #references.result > 0 then
local refs = references.result
for _, value in pairs(locations) do
vrange = value.range or { start = { line = 0 }, ['end'] = { line = 0 } }
for i = 1, #refs, 1 do
local rg = refs[i].range or {}
log(value, refs[i])
log(rg, vrange)
if rg.start.line == vrange.start.line and rg['end'].line == vrange['end'].line then
table.remove(refs, i)
break
end
end
end
vim.list_extend(locations, refs)
2021-12-23 08:17:48 +00:00
end
err = nil
2022-02-17 11:21:34 +00:00
log(locations)
2021-12-23 08:17:48 +00:00
end
2021-04-19 02:56:32 +00:00
-- log("num", num)
-- log("bfnr", bufnr)
if err ~= nil then
2021-12-29 04:50:41 +00:00
vim.notify(
'lsp ref callback error' .. vim.inspect(err) .. vim.inspect(ctx) .. vim.inspect(locations),
vim.lsp.log_levels.WARN
)
log('ref callback error, lsp may not ready', err, ctx, vim.inspect(locations))
return
end
if type(locations) ~= 'table' then
log(locations)
2021-12-12 23:42:53 +00:00
log('ctx', ctx)
2021-12-29 04:50:41 +00:00
vim.notify('incorrect setup' .. vim.inspect(locations), vim.lsp.log_levels.WARN)
return
end
2021-04-19 02:56:32 +00:00
if locations == nil or vim.tbl_isempty(locations) then
2022-02-17 11:21:34 +00:00
vim.notify('References not found', vim.lsp.log_levels.INFO)
2021-04-19 02:56:32 +00:00
return
end
2022-01-18 05:25:48 +00:00
ctx.max_items = truncate
local items, width, second_part = locations_to_items(locations, ctx)
local thread_items = vim.deepcopy(items)
2021-12-12 23:42:53 +00:00
log('splits: ', #items, #second_part)
2021-12-12 23:42:53 +00:00
local ft = vim.api.nvim_buf_get_option(ctx.bufnr, 'ft')
2021-12-12 23:42:53 +00:00
local wwidth = vim.api.nvim_get_option('columns')
2021-06-25 10:18:55 +00:00
local mwidth = _NgConfigValues.width
width = math.min(width + 30, 120, math.floor(wwidth * mwidth))
-- log(items)
-- log(width)
opts = {
total = #locations,
2021-06-13 04:03:01 +00:00
items = items,
2021-12-12 23:42:53 +00:00
rawdata = false,
2021-06-13 04:03:01 +00:00
ft = ft,
width = width,
2021-12-12 23:42:53 +00:00
api = 'Reference',
2021-12-29 04:50:41 +00:00
enable_preview_edit = true,
}
local listview = gui.new_list_view(opts)
2021-12-12 23:42:53 +00:00
if listview == nil then
vim.notify('failed to create preview windows', vim.lsp.log_levels.INFO)
2021-12-12 23:42:53 +00:00
return
end
-- trace("update items", listview.ctrl.class)
local nv_ref_async
nv_ref_async = vim.loop.new_async(vim.schedule_wrap(function()
log('$$$$$$$$ seperate thread... $$$$$$$$')
if vim.tbl_isempty(second_part) then
return
end
2022-01-18 05:25:48 +00:00
local items2 = locations_to_items(second_part, ctx)
vim.list_extend(thread_items, items2)
2021-12-12 23:42:53 +00:00
local data = require('navigator.render').prepare_for_render(thread_items, opts)
listview.ctrl:on_data_update(data)
if nv_ref_async then
vim.loop.close(nv_ref_async)
else
2021-12-12 23:42:53 +00:00
log('invalid asy', nv_ref_async)
end
end))
vim.defer_fn(function()
vim.loop.new_thread(function(asy)
asy:send()
end, nv_ref_async)
end, 100)
return listview, items, width
end
local ref_hdlr = mk_handler(function(err, locations, ctx, cfg)
_NgConfigValues.closer = nil
trace(err, locations, ctx, cfg)
M.async_hdlr = vim.loop.new_async(vim.schedule_wrap(function()
ref_view(err, locations, ctx, cfg)
if M.async_hdlr:is_active() then
M.async_hdlr:close()
end
end))
M.async_hdlr:send()
end)
2021-12-23 08:17:48 +00:00
local async_ref = function()
local ref_params = vim.lsp.util.make_position_params()
2022-02-17 11:21:34 +00:00
local results = {}
2021-12-23 08:17:48 +00:00
lsp.call_async('textDocument/definition', ref_params, function(err, result, ctx, config)
trace(err, result, ctx, config)
2022-04-05 20:47:47 +00:00
if err ~= nil or result == nil then
log('failed to get def', err, result, ctx, config)
result = {}
end
2022-02-17 11:21:34 +00:00
for i = 1, #result do
if result[i].range == nil and result[i].targetRange then
result[i].range = result[i].targetRange
end
end
2021-12-29 04:50:41 +00:00
results.definitions = { error = err, result = result, ctx = ctx, config = config }
2022-02-17 11:21:34 +00:00
log(result)
2021-12-23 08:17:48 +00:00
ctx = ctx or {}
ctx.results = results
ctx.combine = true
ref_view(err, result, ctx, config)
end) -- return asyncresult, canceller
ref_params.context = { includeDeclaration = false }
2021-12-23 08:17:48 +00:00
lsp.call_async('textDocument/references', ref_params, function(err, result, ctx, config)
2022-04-05 20:47:47 +00:00
if err ~= nil or result == nil then
log('failed to get ref', err, result, ctx, config)
result = {}
end
2021-12-23 08:17:48 +00:00
trace(err, result, ctx, config)
2021-12-29 04:50:41 +00:00
results.references = { error = err, result = result, ctx = ctx, config = config }
2021-12-23 08:17:48 +00:00
ctx = ctx or {}
ctx.results = results
ctx.combine = true
ref_view(err, result, ctx, config)
end) -- return asyncresult, canceller
end
local ref_req = function()
if _NgConfigValues.closer ~= nil then
-- do not call it twice
_NgConfigValues.closer()
end
2021-04-26 11:45:45 +00:00
local ref_params = vim.lsp.util.make_position_params()
2021-12-29 04:50:41 +00:00
ref_params.context = { includeDeclaration = true }
-- lsp.call_async("textDocument/references", ref_params, ref_hdlr) -- return asyncresult, canceller
local bufnr = vim.api.nvim_get_current_buf()
2021-12-12 23:42:53 +00:00
log('bufnr', bufnr)
local ids, closer = vim.lsp.buf_request(bufnr, 'textDocument/references', ref_params, ref_hdlr)
log(ids)
_NgConfigValues.closer = closer
return ids, closer
end
local ref = function()
local bufnr = vim.api.nvim_get_current_buf()
local ref_params = vim.lsp.util.make_position_params()
vim.lsp.for_each_buffer_client(bufnr, function(client, client_id, bufnr)
if client.resolved_capabilities.find_references then
2021-12-12 23:42:53 +00:00
client.request('textDocument/references', ref_params, ref_hdlr, bufnr)
end
end)
2021-04-26 11:45:45 +00:00
end
2021-12-24 06:48:54 +00:00
return {
reference_handler = ref_hdlr,
reference = ref_req,
ref_view = ref_view,
2021-12-29 04:50:41 +00:00
async_ref = async_ref,
2021-12-24 06:48:54 +00:00
}