diff --git a/lua/outline/folding.lua b/lua/outline/folding.lua index 507c688..f8145e7 100644 --- a/lua/outline/folding.lua +++ b/lua/outline/folding.lua @@ -1,7 +1,7 @@ local M = {} local cfg = require('outline.config') ----@param node outline.SymbolNode|outline.FlatSymbolNode +---@param node outline.Symbol|outline.FlatSymbol function M.is_foldable(node) return node.children and #node.children > 0 end @@ -16,7 +16,7 @@ local function get_default_folded(depth) end end ----@param node outline.SymbolNode|outline.FlatSymbolNode +---@param node outline.Symbol|outline.FlatSymbol function M.is_folded(node) local hover = cfg.o.symbol_folding.auto_unfold_hover local only = cfg.o.symbol_folding.auto_unfold.only diff --git a/lua/outline/highlight.lua b/lua/outline/highlight.lua index 647beda..514c1f3 100644 --- a/lua/outline/highlight.lua +++ b/lua/outline/highlight.lua @@ -20,7 +20,7 @@ end ---Add single hover highlights ---@param bufnr integer ----@param nodes outline.FlatSymbolNode[] +---@param nodes outline.FlatSymbol[] function M.hovers(bufnr, nodes) for line, node in ipairs(nodes) do if node.hovered then diff --git a/lua/outline/parser.lua b/lua/outline/parser.lua index b24b9de..6eafad7 100644 --- a/lua/outline/parser.lua +++ b/lua/outline/parser.lua @@ -9,12 +9,12 @@ local M = {} ---Parses result from LSP into a reorganized tree of symbols (not flattened, -- simply reoganized by merging each property table from the arguments into a -- table for each symbol) ----@param result table The result from a language server. +---@param result outline.ProviderSymbol The result from a language server. ---@param depth number? The current depth of the symbol in the hierarchy. ---@param hierarchy table? A table of booleans which tells if a symbols parent was the last in its group. ---@param parent table? A reference to the current symbol's parent in the function's recursion ---@param bufnr integer The buffer number which the result was from ----@return outline.SymbolNode[] +---@return outline.Symbol[] local function parse_result(result, depth, hierarchy, parent, bufnr) local ret = {} @@ -48,7 +48,7 @@ local function parse_result(result, depth, hierarchy, parent, bufnr) isLast = isLast, hierarchy = hir, parent = parent, - traversal_child = 1, + _i = 1, } table.insert(ret, node) @@ -74,7 +74,7 @@ end ---Used when refreshing and setting up new symbols ---@param response table The result from buf_request_all ---@param bufnr integer ----@return outline.SymbolNode[] +---@return outline.Symbol[] function M.parse(response, bufnr) local sorted = lsp_utils.sort_symbols(response) @@ -83,11 +83,11 @@ end ---Iterator that traverses the tree parent first before children, returning each node. -- Essentailly 'flatten' items, but returns an iterator. ----@param items outline.SymbolNode[] Tree of symbols parsed by parse_result +---@param items outline.Symbol[] Tree of symbols parsed by parse_result ---@param children_check function? Takes a node and return whether the children should be explored. ---Note that the root node (param items) is always explored regardless of children_check. function M.preorder_iter(items, children_check) - local node = { children = items, traversal_child = 1, depth = 1, is_root = true } + local node = { children = items, _i = 1, depth = 1, is_root = true } local prev local visited = {} @@ -104,19 +104,15 @@ function M.preorder_iter(items, children_check) return node end - if - node.children - and node.traversal_child <= #node.children - and (node.is_root or children_check(node)) - then + if node.children and node._i <= #node.children and (node.is_root or children_check(node)) then prev = node - if node.children[node.traversal_child] then - node.children[node.traversal_child].parent_node = node - node = node.children[node.traversal_child] + if node.children[node._i] then + node.children[node._i].parent_node = node + node = node.children[node._i] end - prev.traversal_child = prev.traversal_child + 1 + prev._i = prev._i + 1 else - node.traversal_child = 1 + node._i = 1 node = node.parent_node end end diff --git a/lua/outline/providers/init.lua b/lua/outline/providers/init.lua index e18f001..c059e10 100644 --- a/lua/outline/providers/init.lua +++ b/lua/outline/providers/init.lua @@ -1,5 +1,3 @@ -local cfg = require('outline.config') - local M = {} local import_prefix = 'outline/providers/' @@ -8,7 +6,7 @@ function M.find_provider() if not M.providers then M.providers = vim.tbl_map(function(p) return import_prefix .. p - end, cfg.get_providers()) + end, require('outline.config').get_providers()) end for _, path in ipairs(M.providers) do local provider = require(path) diff --git a/lua/outline/providers/markdown.lua b/lua/outline/providers/markdown.lua index 2b40d28..b5c5683 100644 --- a/lua/outline/providers/markdown.lua +++ b/lua/outline/providers/markdown.lua @@ -15,7 +15,6 @@ local M = { name = 'markdown', } - ---@return boolean ft_is_markdown function M.supports_buffer(bufnr) return vim.api.nvim_buf_get_option(bufnr, 'ft') == 'markdown' @@ -32,7 +31,7 @@ end -- Parses markdown files and returns a table of SymbolInformation[] which is -- used by the plugin to show the outline. ----@return table +---@return outline.ProviderSymbol[] function M.handle_markdown() local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false) local level_symbols = { { children = {} } } @@ -119,7 +118,7 @@ function M.handle_markdown() return level_symbols[1].children end ----@param on_symbols function +---@param on_symbols fun(symbols?:outline.ProviderSymbol[], opts?:table) ---@param opts table function M.request_symbols(on_symbols, opts) on_symbols(M.handle_markdown(), opts) diff --git a/lua/outline/providers/norg.lua b/lua/outline/providers/norg.lua index 451e8cd..0e0b0f0 100644 --- a/lua/outline/providers/norg.lua +++ b/lua/outline/providers/norg.lua @@ -53,6 +53,8 @@ if not _G._outline_nvim_has[8] then end end +---@param node outline.ProviderSymbol +---@param field string local function rec_remove_field(node, field) node[field] = nil if node.children then @@ -62,6 +64,8 @@ local function rec_remove_field(node, field) end end +---@param callback fun(symbols?:outline.ProviderSymbol[], opts?:table) +---@param opts table function M.request_symbols(callback, opts) if not M.parser then local status, parser = pcall(vim.treesitter.get_parser, 0, 'norg') diff --git a/lua/outline/providers/nvim-lsp.lua b/lua/outline/providers/nvim-lsp.lua index 2749da8..f0c27a5 100644 --- a/lua/outline/providers/nvim-lsp.lua +++ b/lua/outline/providers/nvim-lsp.lua @@ -15,10 +15,6 @@ function M.get_status() return { 'client: ' .. M.client.name } end -local function get_params() - return { textDocument = vim.lsp.util.make_text_document_params() } -end - function M.hover_info(bufnr, params, on_info) local clients = vim.lsp.get_active_clients({ bufnr = bufnr }) local use_client @@ -49,6 +45,7 @@ function M.hover_info(bufnr, params, on_info) use_client.request('textDocument/hover', params, on_info, bufnr) end +---@return boolean function M.supports_buffer(bufnr) local clients = vim.lsp.get_active_clients({ bufnr = bufnr }) local ret = false @@ -69,6 +66,8 @@ function M.supports_buffer(bufnr) return ret end +---@param response outline.ProviderSymbol[] +---@return outline.ProviderSymbol[] local function postprocess_symbols(response) local symbols = lsp_utils.flatten_response(response) @@ -81,9 +80,13 @@ local function postprocess_symbols(response) end end ----@param on_symbols function +---@param on_symbols fun(symbols?:outline.ProviderSymbol[], opts?:table) +---@param opts table function M.request_symbols(on_symbols, opts) - vim.lsp.buf_request_all(0, 'textDocument/documentSymbol', get_params(), function(response) + local params = { + textDocument = vim.lsp.util.make_text_document_params(), + } + vim.lsp.buf_request_all(0, 'textDocument/documentSymbol', params, function(response) response = postprocess_symbols(response) on_symbols(response, opts) end) diff --git a/lua/outline/sidebar.lua b/lua/outline/sidebar.lua index 8715947..6513a0e 100644 --- a/lua/outline/sidebar.lua +++ b/lua/outline/sidebar.lua @@ -17,9 +17,9 @@ local Sidebar = {} ---@class outline.Sidebar ---@field view outline.View ----@field items outline.SymbolNode[] ----@field flats outline.FlatSymbolNode[] ----@field hovered outline.FlatSymbolNode[] +---@field items outline.Symbol[] +---@field flats outline.FlatSymbol[] +---@field hovered outline.FlatSymbol[] ---@field original_cursor string ---@field code outline.SidebarCodeState ---@field autocmds { [integer]: integer } winnr to autocmd id @@ -68,7 +68,7 @@ function Sidebar:destroy() end ---Handler for provider request_symbols when outline is opened for the first time. ----@param response table? +---@param response outline.ProviderSymbol[]? ---@param opts outline.OutlineOpts? function Sidebar:initial_handler(response, opts) if response == nil or type(response) ~= 'table' or self.view:is_open() then @@ -110,7 +110,7 @@ end ---Convenience function for setup_keymaps ---@param cfg_name string Field in cfg.o.keymaps ---@param method string|function If string, field in Sidebar ----@param args table Passed to method +---@param args any[] Passed to method function Sidebar:nmap(cfg_name, method, args) local keys = cfg.o.keymaps[cfg_name] local fn @@ -255,7 +255,7 @@ function Sidebar:reset_cursor_style() end ---Set the cursor to current.line_in_outline and column to a convenient place ----@param current outline.FlatSymbolNode? +---@param current outline.FlatSymbol? function Sidebar:update_cursor_pos(current) local col = 0 local buf = vim.api.nvim_win_get_buf(self.code.win) @@ -271,7 +271,7 @@ end ---Calls build_outline and then calls update_cursor_pos if update_cursor is ---not false ---@param update_cursor boolean? ----@param set_cursor_to_node outline.SymbolNode|outline.FlatSymbolNode? +---@param set_cursor_to_node outline.Symbol|outline.FlatSymbol? function Sidebar:_update_lines(update_cursor, set_cursor_to_node) local current = self:build_outline(set_cursor_to_node) if update_cursor ~= false then @@ -280,6 +280,7 @@ function Sidebar:_update_lines(update_cursor, set_cursor_to_node) end ---Handler for provider request_symbols for refreshing outline +---@param response outline.ProviderSymbol[] function Sidebar:refresh_handler(response) if response == nil or type(response) ~= 'table' then return @@ -308,7 +309,7 @@ function Sidebar:refresh_handler(response) self:_update_lines(update_cursor) end ----@param items outline.SymbolNode[] +---@param items outline.Symbol[] function Sidebar:_merge_items(items) parser.merge_items_rec({ children = items }, { children = self.items }) end @@ -335,7 +336,7 @@ end -- stylua: ignore end ---Currently hovered node in outline ----@return outline.FlatSymbolNode +---@return outline.FlatSymbol function Sidebar:_current_node() local current_line = vim.api.nvim_win_get_cursor(self.view.win)[1] return self.flats[current_line] @@ -432,7 +433,7 @@ function Sidebar:_set_folded(folded, move_cursor, node_index) end end ----@param nodes outline.SymbolNode[] +---@param nodes outline.Symbol[] function Sidebar:_toggle_all_fold(nodes) nodes = nodes or self.items local folded = true @@ -448,7 +449,7 @@ function Sidebar:_toggle_all_fold(nodes) end ---@param folded boolean? ----@param nodes? outline.SymbolNode[] +---@param nodes? outline.Symbol[] function Sidebar:_set_all_folded(folded, nodes) local stack = { nodes or self.items } local current = self:_current_node() @@ -639,12 +640,12 @@ end ---@note Ensure new outlines are already set to `self.items` before calling ---this function. `self.flats` will be overwritten and current line is obtained ---from `win_get_cursor` using `self.code.win`. ----@param find_node outline.FlatSymbolNode|outline.SymbolNode? Find a given node rather than node matching cursor position in codewin ----@return outline.FlatSymbolNode? set_cursor_to_this_node +---@param find_node outline.FlatSymbol|outline.Symbol? Find a given node rather than node matching cursor position in codewin +---@return outline.FlatSymbol? set_cursor_to_this_node function Sidebar:build_outline(find_node) ---@type integer 0-indexed local hovered_line = vim.api.nvim_win_get_cursor(self.code.win)[1] - 1 - ---@type outline.FlatSymbolNode Deepest visible matching node to set cursor + ---@type outline.FlatSymbol Deepest visible matching node to set cursor local put_cursor self.flats = {} local line_count = 0 diff --git a/lua/outline/types/outline.lua b/lua/outline/types/outline.lua index 7ddb735..1f029bd 100644 --- a/lua/outline/types/outline.lua +++ b/lua/outline/types/outline.lua @@ -22,28 +22,23 @@ -- SYMBOLS ----@class outline.SymbolNode +---@class outline.ProviderSymbol ---@field name string ----@field depth integer ----@field parent outline.SymbolNode ----@field deprecated boolean ----@field kind integer|string ----@field icon string ----@field detail string ----@field line integer ----@field character integer ----@field range_start integer ----@field range_end integer ----@field isLast boolean ----@field hierarchy boolean ----@field children? outline.SymbolNode[] ----@field traversal_child integer Should NOT be modified during iteration using parser.preorder_iter ----@field is_root boolean? +---@field kind integer +---@field detail? string +---@field range outline.ProviderSymbolRange +---@field selectionRange outline.ProviderSymbolRange +---@field parent outline.ProviderSymbol +---@field children outline.ProviderSymbol[] ----@class outline.FlatSymbolNode +---@class outline.ProviderSymbolRange +---@field start integer +---@field end integer + +---@class outline.Symbol ---@field name string ---@field depth integer ----@field parent outline.FlatSymbolNode +---@field parent outline.Symbol ---@field deprecated boolean ---@field kind integer|string ---@field icon string @@ -54,9 +49,11 @@ ---@field range_end integer ---@field isLast boolean ---@field hierarchy boolean ----@field children? outline.FlatSymbolNode[] ----@field traversal_child integer ----@field is_root boolean? +---@field children? outline.Symbol[] +---@field _i integer Should NOT be modified during iteration using parser.preorder_iter +---@field is_root? boolean + +---@class outline.FlatSymbol : outline.Symbol ---@field line_in_outline integer ---@field prefix_length integer ---@field hovered boolean @@ -68,7 +65,7 @@ ---@field name string ---@field get_status? fun():string[] ---@field supports_buffer fun(bufnr:integer):boolean ----@field request_symbols fun(on_symbols:function, opts:table?) +---@field request_symbols fun(on_symbols:fun(symbols?:outline.ProviderSymbol[], opts:table?), opts:table?) ---@field hover_info? fun(bufnr:integer, params:table, on_info:function) ---@field rename_symbol? fun(sidebar:outline.Sidebar) ---@field code_actions? fun(sidebar:outline.Sidebar) diff --git a/lua/outline/view.lua b/lua/outline/view.lua index 183bf31..7d73f4a 100644 --- a/lua/outline/view.lua +++ b/lua/outline/view.lua @@ -98,7 +98,7 @@ end ---Ensure all existing highlights are already cleared before calling! ---@param hl outline.HL[] ----@param nodes outline.FlatSymbolNode[] +---@param nodes outline.FlatSymbol[] ---@param details string[] ---@param linenos string[] function View:add_hl_and_ns(hl, nodes, details, linenos)