diff --git a/doc/calltree.txt b/doc/calltree.txt index 84120af..1c00af1 100644 --- a/doc/calltree.txt +++ b/doc/calltree.txt @@ -204,6 +204,21 @@ The config table is described below: -- user provided UI highlights. -- see *calltree-ui-highlights* hls = {} + -- some LSP's will provide symbols with different names depending on + -- the method called. + -- + -- if resolve_symbols is set to true a workspace symbol request will + -- be made for any responses from LSP's, providing clearer information + -- for symbols in the calltree. + -- + -- this will cause the UI to open slower, tho the symbol requests are + -- async so it will not block the editor. + -- for full context see: + -- https://github.com/golang/go/issues/49690#issuecomment-975902067 + -- + -- set this to false for large codebases to speed up opening + -- the calltree. + resolve_symbols = true } ==================================================================================== diff --git a/lua/calltree.lua b/lua/calltree.lua index 263df46..75b0bdb 100644 --- a/lua/calltree.lua +++ b/lua/calltree.lua @@ -10,7 +10,8 @@ M.config = { no_hls = false, indent_guides = true, icon_highlights = {}, - hls = {} + hls = {}, + resolve_symbols = true } function _setup_default_highlights() diff --git a/lua/calltree/handlers.lua b/lua/calltree/handlers.lua index 293453b..660fc2f 100644 --- a/lua/calltree/handlers.lua +++ b/lua/calltree/handlers.lua @@ -1,6 +1,7 @@ local tree = require('calltree.tree.tree') local tree_node = require('calltree.tree.node') local lsp_util = require('calltree.lsp.util') +local config = require('calltree').config local M = {} local direction_map = { @@ -44,11 +45,18 @@ function M.calltree_expand_handler(node, linenr, direction, ui_state) call_hierarchy_call[direction], call_hierarchy_call.fromRanges ) - -- try to resolve the workspace symbol for child - child.symbol = lsp_util.symbol_from_node(ui_state.active_lsp_clients, child, ui_state.calltree_buf) table.insert(children, child) end + if config.resolve_symbols then + lsp_util.gather_symbols_async(node, children, ui_state, function() + tree.add_node(ui_state.calltree_handle, node, children) + tree.write_tree(ui_state.calltree_handle, ui_state.calltree_buf) + ui.open_calltree() + end) + return + end + tree.add_node(ui_state.calltree_handle, node, children) tree.write_tree(ui_state.calltree_handle, ui_state.calltree_buf) vim.api.nvim_win_set_cursor(ui_state.calltree_win, linenr) diff --git a/lua/calltree/lsp/handlers.lua b/lua/calltree/lsp/handlers.lua index 050cf70..99002fe 100644 --- a/lua/calltree/lsp/handlers.lua +++ b/lua/calltree/lsp/handlers.lua @@ -2,6 +2,7 @@ local tree_node = require('calltree.tree.node') local tree = require('calltree.tree.tree') local ui = require('calltree.ui') local lsp_util = require('calltree.lsp.util') +local config = require('calltree').config local M = {} @@ -23,7 +24,7 @@ M.ch_lsp_handler = function(direction) cur_tabpage = vim.api.nvim_win_get_tabpage(cur_win) - ui_state = ui.ui_state_registry[cur_tabpage] + ui_state = ui.ui_state_registry[cur_tabpage] if ui_state == nil then ui_state = {} ui.ui_state_registry[cur_tabpage] = ui_state @@ -51,9 +52,6 @@ M.ch_lsp_handler = function(direction) ctx.params.item, nil) - -- try to resolve the workspace symbol for root. - root.symbol = lsp_util.symbol_from_node(ui_state.active_lsp_clients, root, ui_state.invoking_calltree_win) - -- create the root's children nodes via the response array. local children = {} for _, call_hierarchy_call in pairs(result) do @@ -63,14 +61,20 @@ M.ch_lsp_handler = function(direction) call_hierarchy_call[direction], call_hierarchy_call.fromRanges ) - -- try to resolve the workspace symbol for child - child.symbol = lsp_util.symbol_from_node(ui_state.active_lsp_clients, child, ui_state.invoking_calltree_win) table.insert(children, child) end + -- gather symbols async + if config.resolve_symbols then + lsp_util.gather_symbols_async(root, children, ui_state, function() + tree.add_node(ui_state.calltree_handle, root, children) + ui.open_calltree() + end) + return + end tree.add_node(ui_state.calltree_handle, root, children) ui.open_calltree() - end + end end M.ws_lsp_handler = function() @@ -89,7 +93,7 @@ M.ws_lsp_handler = function() ui_state = ui.ui_state_registry[cur_tabpage] if ui_state == nil then ui_state = {} - ui.ui_state_registry[cur_tabpage] = ui_state + ui.ui_state_registry[cur_tabpage] = ui_sate end -- snag the lsp clients from the buffer issuing the diff --git a/lua/calltree/lsp/util.lua b/lua/calltree/lsp/util.lua index c98bc23..de4e973 100644 --- a/lua/calltree/lsp/util.lua +++ b/lua/calltree/lsp/util.lua @@ -157,6 +157,64 @@ function M.symbol_from_node(clients, node, bufnr) return nil end +function M.gather_symbols_async_handler(node, co) + return function(err, result, _, _) + if err ~= nil then + coroutine.resume(co, nil) + return + end + + local start_line, uri = "", "" + if node.call_hierarchy_item ~= nil then + start_line = node.call_hierarchy_item.range.start.line + uri = node.call_hierarchy_item.uri + elseif node.document_symbol ~= nil then + start_line = node.document_symbol.range.start.line + uri = node.uri + end + + for _, res in ipairs(result) do + if + res.location.uri == uri and + res.location.range.start.line == + start_line + then + coroutine.resume(co, res) + return + end + end + coroutine.resume(co, nil) + end +end + +function M.gather_symbols_async(root, children, ui_state, callback) + local co = nil + all_nodes = {} + table.insert(all_nodes, root) + for _, child in ipairs(children) do + table.insert(all_nodes, child) + end + co = coroutine.create(function() + for _, node in ipairs(all_nodes) do + local params = { + query = node.name, + } + print(node.name) + M.multi_client_request( + ui_state.active_lsp_clients, + "workspace/symbol", + params, + -- handler will call resume for this co. + M.gather_symbols_async_handler(node, co), + ui_state.invoking_calltree_win + ) + node.symbol = coroutine.yield() + end + callback() + end) + coroutine.resume(co) +end + function M.build_recursive_symbol_tree(depth, document_symbol, parent, prev_depth_table) local node = tree_node.new( document_symbol.name,