hedyhli / outline.nvim

Code outline sidebar powered by LSP. Significantly enhanced & refactored fork of symbols-outline.nvim.
https://sr.ht/~hedy/outline.nvim
MIT License
580 stars 17 forks source link

Symbol kind filtering #23

Closed hedyhli closed 10 months ago

hedyhli commented 10 months ago
older ideas `blacklist` will be an alias to `exclude`, removed and resolved in setup stage to maintain compatibility ### draft implementation 1
config: `symbols.exclude` (already implemented) - list of kinds, or - table of filetypes to list of kinds config: `symbols.only_include` - list of kinds, or - table of filetypes to list of kinds if either are lists, they are resolved into `{ ["*"] = { } }` at the setup stage config `symbols.filter_fn` - function that takes these params, and return a filtered nodes tree 1. nodes tree 1. code buffer number 1. provider info (ideally should have provider name and say lsp client name) 1. the `symbols.exclude` and `symbols.only_include` config - default - if only_include non-nil, calls `include_by_ft`, END - otherwise calls `exclude_by_ft` second + third could be packaged into a table, called ctx this allows users to wrap filter fn around the default filtering functions, could be provided from import path "outline.filter" example default functions: (params same as filter_fn) - `include_by_ft` - `include` - `exclude_by_ft` - `exclude` #### recipes - include everything (default behaviour): `only_include = nil, exclude = nil` - only include these symbols for all ft: `only_include = {"Function", "Method"}, exclude = nil` - include everything except these symbols for all ft: `exclude = {"Variable", "String"}, only_include = nil` - include everything, but for python only include these symbols: `only_include = { python = {"Function", "Class"} }, exclude = nil` - include everything, but for python exclude these symbols: `exclude = { python = {"Variable", "String"} }, only_include = nil` - only include these for python, and for others only include that: `only_include = { python = {"Function", "Class"}, ["*"] = {"Function", "Method"} }, exclude = nil` - only include these, for python ALSO exclude that: `only_include = { "Function", "Method" }, exclude = { python = {"Method"} }` - include everything, but for a particular python file exclude these symbols: ```lua exclude = { python = {"Variable", "String"} }, only_include = nil, filter_fn = function(nodes, buf, _, _, exclude) local fname = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(buf), ":t") if fname == "__init__.py" then return require("outline.filters").exclude(nodes, exclude.python) end return nodes end, ```
### draft implementation 2 - a filter key for a table of ft (defaults empty) - an exclude key for table of ft (defaults nil) keep it this way until someone reports a use-case that cannot be achieved by this implementation ### draft implementation 3 - a filter fn that takes ONE node, the bufnr and provider info, returns true (include) or false (exclude) keep it this way until someone reports a use-case where this approach is too troublesome.

draft implementation 4

Type filterTable = table Type filterSpec is either filterTable ~or a function that returns a filterTable~

symbol.filter takes either a filterSpec, or ft:filterSpec pairs

filterTable is a list of kinds which can only appear in the outline. unless in the table, exclude = true, then the list means include all kinds except ones in the list.

the function part can be left for the future when such a use-case for it arises to not introduce this feature with a complex configuration structure.

-- Only these, for all file types
filter = { 'Function', 'Class', 'Method' }
-- or equivalent:
filter = { 'Function', 'Class', 'Method', exclude = false }

-- All except these, for all file types
filter = { 'String', 'Package', exclude = true }

-- For python, include all but Variable. For others, include only these 3
filter = {
  ['*'] = {'Function', 'Class', 'Method'},
  python = { 'Variable', exclude = true }
}

-- Include all. For python include all except Function
filter = {
  python = { 'Function', exclude = true }
}

backwards compatibility

symbols.blacklist = {'Variable', 'String'}
-- Gets converted into:
symbols.filter = {'Variable', 'String', exclude = true}

TODO