feat: Symbol filtering config structure

This commit introduces a basic framework for symbol filtering in
outline.nvim, where users can set per-filetype kinds to filter - include
or exclude for each filetype.

As a side effect the checking of symbol inclusion function has been
improved to O(1) time-complexity (previously O(n)). You can see this
from types/outline.lua and config.lua: a lookup table is used to check
if a kind is filtered, rather than looping through a list each time.
Former takes O(1) for lookup whereas the old implementation would be
O(n) for *each* node!

The old symbols.blacklist option *still works as expected*.

The schema for the new confit is detailed in #23 and types/outline.lua.
By the way, this commit also closes #23.

These should equivalent:
    symbols.blacklist = { 'Function', 'Method' }
    symbols.filter = { 'Function', 'Method', exclude=true }
    symbols.filter = {
      ['*'] = { 'Function', 'Method', exclude=true }
    }

And these should be equivalent:
    symbols.blacklist = {}
    symbols.filter = false
    symbols.filter = nil
    symbols.filter = { ['*'] = false }
    symbols.filter = { ['*'] = { exclude = true } }
    symbols.filter = { exclude = true }

The last two of which could be considered unidiomatic.

When multiple filetypes are specified, filetype specific filters
are NOT merged with the default ('*') filter, they are independent. If a
filetype is used, the default filter is not considered. The default
filter is only considered if a filetype filter for the given buffer is
not provided.

LIMITATIONS:
This is carried over from the implementation from symbols-outline:
filters can only be applied to parents at the moment. I.e.: If some node
has a kind that is excluded, all its children will NOT be considered.

Filters are only applied to children if its parent was not excluded
during filtering.

Also extracted all types into types module, and updated conversion
script to use the new symbols.filter opt.

NOTE:
On outline open it appears that parsing functions are called twice?
I should definitely add tests soon.
This commit is contained in:
hedy
2023-11-16 21:21:55 +08:00
parent 5278eb5b2b
commit 24680f13f7
7 changed files with 244 additions and 80 deletions

View File

@@ -78,11 +78,11 @@ local function __refresh()
return
end
local items = parser.parse(response)
_merge_items(items)
M.state.code_win = vim.api.nvim_get_current_win()
local items = parser.parse(response, vim.api.nvim_get_current_buf())
_merge_items(items)
_update_lines()
end
@@ -445,7 +445,7 @@ local function handler(response, opts)
setup_keymaps(M.view.bufnr)
setup_buffer_autocmd()
local items = parser.parse(response)
local items = parser.parse(response, vim.api.nvim_win_get_buf(M.state.code_win))
M.state.outline_items = items
M.state.flattened_outline_items = writer.make_outline(M.view.bufnr, items, M.state.code_win)
@@ -457,11 +457,6 @@ local function handler(response, opts)
end
end
---@class outline.OutlineOpts
---@field focus_outline boolean?
---@field on_symbols function?
---@field on_outline_setup function?
---Set position of outline window to match cursor position in code, return
---whether the window is just newly opened (previously not open).
---@param opts outline.OutlineOpts? Field `focus_outline` = `false` or `nil` means don't focus on outline window after following cursor. If opts is not provided, focus will be on outline window after following cursor.