Files
outline.nvim/scripts/convert-symbols-outline-opts.lua
hedy 24680f13f7 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.
2023-11-16 21:21:55 +08:00

127 lines
3.7 KiB
Lua

-- This script converts your existing setup opts from symbols-outline.nvim to
-- the new format for outline.nvim.
--
-- You do not need this if your old symbols-outline.nvim config was empty.
--
-- 1. Save this file somewhere temporary and open this file in nvim.
-- 2. Paste your old symbols-outline setup opts in the 'opts' table,
-- 3. Put your cursor on the line of 'your_new_opts' table.
-- 4. Keeping your cursor there, run ':luafile %'
-- 5. You can then '$yi{' to yank it in register 0
--
-- Read about all the new features and improvements on:
-- https://github.com/hedyhli/outline.nvim/issues/12
--
-- If you encounter any problems, please open an issue.
--
-- Thanks for using outline.nvim!
local opts = {
--- Example:
-- show_guides = false,
-- fold_markers = {'>', 'v'},
}
---@diagnostic disable-next-line
local your_new_opts = --[[put the cursor on this line]] {
}
---------------------------------------------------------------------
----- BEGIN SCRIPT --------------------------------------------------
---------------------------------------------------------------------
local newopts = { symbols = {} }
if opts.symbols then
newopts.symbols.icons = opts.symbols
opts.symbols = nil
end
if opts.symbol_blacklist then
newopts.symbols.filter = opts.symbol_blacklist
newopts.symbols.filter.exclude = true
opts.symbol_blacklist = nil
end
if opts.lsp_blacklist then
newopts.provider = {
lsp = {
blacklist_clients = opts.lsp_blacklist
}
}
opts.lsp_blacklist = nil
end
if opts.fold_markers or opts.autofold_depth ~= nil or opts.auto_unfold_hover ~= nil then
newopts.symbol_folding = {
autofold_depth = opts.autofold_depth,
auto_unfold_hover = opts.auto_unfold_hover,
markers = opts.fold_markers,
}
opts.autofold_depth = nil
opts.auto_unfold_hover = nil
opts.fold_markers = nil
end
if opts and next(opts) ~= nil then
newopts.preview_window = {}
newopts.outline_window = {}
newopts.outline_items = {}
for _, v in ipairs({'auto_preview', 'border'}) do
newopts.preview_window[v] = opts[v]
opts[v] = nil
end
if newopts.preview_window.auto_preview == true then
newopts.preview_window.open_hover_on_preview = true
end
if opts.preview_bg_highlight then
newopts.preview_window.winhl = 'Normal:'..opts.preview_bg_highlight
opts.preview_bg_highlight = nil
end
for _, v in ipairs({'show_symbol_details', 'highlight_hovered_item'}) do
newopts.outline_items[v] = opts[v]
opts[v] = nil
end
for _, v in ipairs({
'width', 'relative_width', 'position', 'border', 'wrap', 'auto_close',
'show_numbers', 'show_relative_numbers', 'show_cursorline',
}) do
newopts.outline_window[v] = opts[v]
opts[v] = nil
end
if type(opts.show_guides) == 'boolean' then
newopts.guides = {}
newopts.guides.enabled = opts.show_guides
end
opts.show_guides = nil
if opts.keymaps ~= nil then
newopts.keymaps = opts.keymaps
newopts.keymaps.peek_location = opts.keymaps.focus_location
newopts.keymaps.focus_location = nil
opts.keymaps = nil
end
end
for _, v in ipairs({'outline_items', 'outline_window', 'preview_window', 'symbols'}) do
if newopts[v] and next(newopts[v]) == nil then
newopts[v] = nil
end
end
local all = vim.inspect(newopts)
local lines = vim.split(all, '\n', {plain = true, trimempty = true})
table.remove(lines, 1) table.remove(lines, #lines)
local curline = vim.api.nvim_win_get_cursor(0)[1]
vim.api.nvim_buf_set_lines(0, curline, curline, true, lines)
---------------------------------------------------------------------
----- END SCRIPT ----------------------------------------------------
---------------------------------------------------------------------