Skip to content

Commit

Permalink
docs,cleanup: various documentation fixes and cleanup
Browse files Browse the repository at this point in the history
Signed-off-by: ldelossa <[email protected]>
  • Loading branch information
ldelossa committed Nov 23, 2021
1 parent d5381c3 commit e41a3f4
Show file tree
Hide file tree
Showing 15 changed files with 305 additions and 198 deletions.
23 changes: 18 additions & 5 deletions doc/calltree.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ INTRODUCTION *calltree-in
Calltree is a simple plugin which adds the missing "call-hierarchy" tool
found in IDEs such as Pycharm and VSCode.

A "call-hierarchy" tool creates a tree view of incoming (callers) or outging
A "call-hierarchy" tool creates a tree view of incoming (callers) or outgoing
(callees) for a given symbol.

From there you can drive down further, discovering "callers-of-callers" or
Expand All @@ -40,9 +40,9 @@ Usage *calltree-us
Calltree's entry point is the "calltree.lsp.handlers.ch_lsp_handler" function.

This function returns a handler suitable for usage in neovim's LSP handler
dicationary.
table.

While the setup function will hijack the handlers dict for you, you can also do this
While the setup function will hijack the handlers table for you, you can also do this
manually like so:

vim.lsp.handlers['callHierarchy/incomingCalls'] = vim.lsp.with(
Expand All @@ -51,8 +51,11 @@ manually like so:
vim.lsp.handlers['callHierarchy/outgoingCalls'] = vim.lsp.with(
require('calltree.lsp.handlers').ch_lsp_handler("to"), {}
)
vim.lsp.handlers['textDocument/documentSymbol'] = vim.lsp.with(
require('calltree.lsp.handlers').ws_lsp_handler(), {}
)

This is what the "callsigns.setup()" function does.
This is what the "calltree.setup()" function does.

Once the calltree handlers are in place issuing the normal "vim.lsp.buf.incoming_calls"
and "vim.lsp.buf.outgoing_calls" will open the calltree window.
Expand All @@ -71,6 +74,14 @@ Calltree exports several commands for manipulating the calltree UI.
*:CTClose*
:CTClose
Closes the calltree window
*:STOpen*
:STOpen
Open the symboltree window with the most recent outline tree present.

*:STClose*
:STClose
Closes the symboltree window


*:CTExpand*
:CTExpand
Expand Down Expand Up @@ -143,7 +154,7 @@ The default buffer mapping is set via lua and should feel familiar if you use vi
====================================================================================
CONFIG *calltree-config*

To configure calltree you can pass the a config table to "require('calltree').setup(config)".
To configure calltree you can pass a config table to "require('calltree').setup(config)".
You only need to specify the fields you wish to override.

The config table is described below:
Expand All @@ -163,6 +174,8 @@ The config table is described below:
-- int - An integer used in the initial "resize" command for
-- the ui.
layout_size = 30,
-- whether to automatically open the calltree and symboltree ui on start.
auto_open = false,
-- the method used when jumping to a symbol in the calltree
-- "invoking" - Jumping to a symbol will use the window which the calltree
-- was initially invoked from.
Expand Down
19 changes: 13 additions & 6 deletions lua/calltree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ M.codicons = {
M.config = {
layout = "left",
layout_size = 30,
auto_open = false,
jump_mode = "invoking",
icons = "none",
symbol_hl = "Search",
Expand All @@ -87,9 +88,6 @@ function M.setup(user_config)
require('calltree.lsp.handlers').ws_lsp_handler(), {}
)

-- autocommand for updating outline view
vim.cmd([[au TextChanged,BufEnter,BufWritePost * lua require('calltree.ui').refresh_symbol_tree()]])

-- merge config
if user_config ~= nil then
for k, v in pairs(user_config) do
Expand All @@ -98,10 +96,10 @@ function M.setup(user_config)
end

-- sanatize the config
if (M.config.layout ~= "left")
and (M.config.layout ~= "right")
if (M.config.layout ~= "left")
and (M.config.layout ~= "right")
and (M.config.layout ~= "top")
and (M.config.layout ~= "bottom")
and (M.config.layout ~= "bottom")
then
M.config.layout = "left"
end
Expand All @@ -122,6 +120,15 @@ function M.setup(user_config)
end
end

-- automatically open the ui elements on buf enters.
if M.config.auto_open then
vim.cmd([[au BufEnter * lua require('calltree.ui').open_calltree()]])
vim.cmd([[au BufEnter * lua require('calltree.ui').open_symboltree()]])
end

-- will keep the outline view up to date when moving around buffers.
vim.cmd([[au TextChanged,BufEnter,BufWritePost * lua require('calltree.ui').refresh_symbol_tree()]])

-- setup commands
vim.cmd("command! CTOpen lua require('calltree.ui').open_calltree()")
vim.cmd("command! STOpen lua require('calltree.ui').open_symboltree()")
Expand Down
97 changes: 97 additions & 0 deletions lua/calltree/handlers.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
local tree = require('calltree.tree.tree')
local tree_node = require('calltree.tree.node')
local lsp_util = require('calltree.lsp.util')
local M = {}

-- calltree_expand_handler is the call_hierarchy request handler
-- used when expanding an existing node in the calltree.
--
-- node : tree.node.Node - the node being expanded
--
-- linenr : table - the line the cursor was on in the ui
-- buffer before expand writes to it.
--
-- direction : string - the call hierarchy direction
-- "to" or "from".
--
-- ui_state : table - a ui_state table which provides the ui state
-- of the current tab. defined in ui.lua
function M.calltree_expand_handler(node, linenr, direction, ui_state)
return function(err, result, _, _)
if err ~= nil then
vim.api.nvim_err_writeln(vim.inspect(err))
return
end
if result == nil then
-- rewrite the tree still to expand node giving ui
-- feedback that no further callers/callees exist
tree.write_tree(ui_state.calltree_handle, ui_state.calltree_buf)
vim.api.nvim_win_set_cursor(ui_state.calltree_win, linenr)
return
end

local children = {}
for _, call_hierarchy_call in pairs(result) do
local child = tree_node.new(
call_hierarchy_call[direction].name,
0, -- tree.add_node will compute depth for us
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

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)
end
end

-- calltree_switch_handler is the call_hierarchy request handler
-- used when switching directions from incoming to outgoing or vice versa.
--
-- direction : string - the call hierarchy direction
-- "to" or "from".
--
-- ui_state : table - a ui_state table which provides the ui state
-- of the current tab. defined in ui.lua
function M.calltree_switch_handler(direction, ui_state)
return function(err, result, ctx, _)
if err ~= nil then
return
end
-- create the root of our call tree, the request which
-- signaled this response is in ctx.params
local root = tree_node.new(ctx.params.item.name,
0,
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.calltree_buf)

-- create the root's children nodes via the response array.
local children = {}
for _, call_hierarchy_call in pairs(result) do
local child = tree_node.new(
call_hierarchy_call[direction].name,
0, -- tree.add_node will set the depth correctly.
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

-- add the new root, its children, and rewrite the
-- tree (will open the calltree ui if necessary).
tree.add_node(ui_state.calltree_handle, root, children)

tree.write_tree(ui_state.calltree_handle, ui_state.calltree_buf)
vim.api.nvim_buf_set_name(ui_state.calltree_buf, direction_map[direction].buf_name)
end
end

return M
1 change: 0 additions & 1 deletion lua/calltree/lsp/util.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

local tree_node = require('calltree.tree.node')
local M = {}

Expand Down
12 changes: 8 additions & 4 deletions lua/calltree/tree/node.lua
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ end
-- depth : int - the depth at which this node will exist
-- in the tree.
--
-- call_hierarchy_obj : table - the incoming or outgoing
-- call hierarchy object per the LSP spec.
-- call_hierarchy_item : table - the incoming or outgoing
-- call hierarchy object per the LSP spec. this is the "item" field of a
-- textDocument/[incoming|outgoing]Calls response.
--
-- kind : string - the kind of symbol this node represents.
-- references : array - references of the given symbol. this field is the fromRanges
-- field of a call_hierarchy response datastructure hoisted up to the top level of he node.
--
-- references : array of references of the given symbol
-- document_symbol : table
function M.new(name, depth, call_hierarchy_item, references, document_symbol)
local node = {
name=name,
Expand All @@ -55,6 +57,8 @@ function M.new(name, depth, call_hierarchy_item, references, document_symbol)
document_symbol=document_symbol,
-- if the node is a document_symbol this field will be present
-- containing the document uri the symbol belongs to.
--
-- not set until the documentSymbol handler is invoked in calltree.lsp.handlers
uri=""
}
node.key = M.keyify(node)
Expand Down
39 changes: 38 additions & 1 deletion lua/calltree/tree/tree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ local reg = {}
-- new_tree registers an empty tree and returns
-- the handle to the caller.
--
-- kind : "calltree" | "symboltree"
-- kind : string - "calltree" | "symboltree"
-- returns:
-- tree_handle
function M.new_tree(kind)
Expand All @@ -24,13 +24,23 @@ function M.new_tree(kind)
return handle
end

-- get_tree takes a call handle and returns a table
-- representing our tree components.
--
-- handle : tree_handle - a valid handle to a tree
--
-- returns:
-- tree : table - a table with our tree componnts,
-- see "reg" comments above.
function M.get_tree(handle)
return reg[handle]
end

-- recursive_dpt_compute traverses the tree
-- and flattens it into out depth_table
--
-- tree : tree_handle - a handle to a valid tree
--
-- node : Node - calltree's root node.
local function _recursive_dpt_compute(tree, node)
local depth = node.depth
Expand All @@ -46,11 +56,32 @@ end

-- _refresh_dpt dumps the current depth_table
-- and writes a new one.
--
-- tree : tree_handle - a handle to a valid tree
local function _refresh_dpt(tree)
reg[tree].depth_table = {}
_recursive_dpt_compute(tree, reg[tree].root)
end

-- add_node will add a node to the tree pointed to by the
-- provided tree handle.
--
-- tree : tree_handle - a handle to a valid tree
--
-- parent : tree.tree.Node - the parent of the subtree being
-- added. the parent's "depth" field is significant. setting it to
-- 0 will throw away the current root and create a new tree.
-- See usages of this function to understand how depth can be safely
-- set.
--
--
-- children : tree.tree.Node array - the children of the parent.
-- the child's depth field has no significant and can be computed
-- from the parent's.
--
-- external : bool - if true an entire tree has been built externally
-- and the root will be added to the tree without any modifications.
-- the children param has no significance in this scenario.
function M.add_node(tree, parent, children, external)
-- external nodes are roots of trees built externally
-- if this is true set the tree's root to the incoming parent
Expand Down Expand Up @@ -139,6 +170,8 @@ end
--
-- the subtree from node down is preserved.
--
-- tree : tree_handle - a handle to a valid tree
--
-- depth : int - indicator of the incoming node's depth
-- useful for understanding when recursion is done.
-- node : Node - the Node object being reparented.
Expand All @@ -162,6 +195,10 @@ function M.reparent_node(tree, depth, node)
end
end

-- dump_tree will dump the tree data structure to a
-- buffer for debugging.
--
-- tree : tree_handle - a handle to a valid tree
function M.dump_tree(tree)
local buf = vim.api.nvim_create_buf(true, false)
vim.api.nvim_buf_set_name(buf, "calltree-dump")
Expand Down
Loading

0 comments on commit e41a3f4

Please sign in to comment.