Currently the implementation is very limited.
Ref: #24
- Outline must be open and have been loaded for it to work (requires
lazy loading or headless loading of Sidebar)
- Empty string returned if cursor is not in any symbol ('closest' symbol
not yet supported)
- Line column not used
- Returning concatenated symbol names rather than a list of tables with
node info (requires a refactor of outline.SymbolNode type)
- Subject to config.symbols.filter and folds (requires finding hover
list somewhere outside of writer.make_outline)
Somehow marksman also does this?
As for treesitter (norg) it may be because treesitter includes the
newline and the next line indent until the next heading, so the line of
the next heading is included in the range of the previous heading. We
manually -1 on the range end line to fix it.
Closes#37
Almost completely refactored the UI parts outline.nvim to use a Sidebar
object that implements an outline window. In init.lua, we can then store
a table of the outline for each tabpage ID.
When tabs are closed the outline is closed and sidebar reset
responsibly.
This simplifies `init.lua` quite a lot, making it the highest level
control center for the outline elements.
All lua APIs and commands should work as before.
Closes#35
Previously the treesitter javascript parser would treat `<></>`
specially and emit a `jsx_fragment`. We were checking for this type here
(from symbols-outline.nvim), though we did not include `jsx_fragment` in
the parse_ts function to even look for it.
jsx_fragment was recently removed from treesitter parser to reduce
complexity, so we will treat all jsx_element's without a `name` field in
`jsx_opening_element` as the shorthand fragment.
Using "Fragment" as the name in this case makes it look exactly the same
as if the user used `<Fragment></Fragment>` instead.
The check for `jsx_fragment` is still kept in case an older version of
the parser is still used, it can probably be removed next year.
Ref:
- tree-sitter/tree-sitter-javascript#227
- Closes#3
- Ref: simrat39/symbols-outline.nvim#190
Norg contains indents and different types of verbatim tags, I was rather
lazy to read the spec properly and parse norg using regex line-by-line
like markdown, so used treesitter instead. The only requirement is the
`norg` parser for treesitter to be installed. Tested on nvim 0.7.2.
This should lead the way for supporting vimdoc files in a similar
manner.
Documentation for how external providers could look like as of now has
been added.
In the future we could let the provider determine what to do for each
keymap, such as `goto_location` and `toggle_preview`. This would allow
the zk extension[1] to work properly without having to override existing
functions (bad practice).
[1]: https://github.com/mickael-menu/zk-nvim/discussions/134
Option to auto unfold when there is only N root nodes in outline.
Defaults to 1, meaning if there is only one 'root' parent, it should
always be unfolded.
This is useful if the entire file is a single function or a single
'return'.
The old auto_unfold_hover option **still works as expected**.
No more obnoxious '}' on the cmdline when pressing `?`!
scope:
- More type hints
- Added class Float for creating floating windows with size that fit the
content and position centered on the screen
- show_help action for outline window (key `?`) now uses a floating
window
- :OutlineStatus now provides better information, and shows content in a
floating window.
future:
- Floating window option configuration
- preview window can adapt based on position of outline window, and not
based on config value of `position` left/right
- it can also properly vertically center-align, even when there are
horizontal splits below the outline
- fixed a few bugs associated with previous rewrite commits in init.lua
config:
- Added min_height for preview window
This also fixes a typo from an old commit (did not catch the bug because
all this time I was testing with the same window!), and put
auto_update_events into outline_items since it makes more sense, and is
closer to highlight_hovered_item and (the new) auto_follow_cursor.
Added code_buf to state since it appears to be used quite often now.
Previously on each outline open, the `writer.make_outline` function
might be called at least 4 times(!), after this refactor it will only be
called once. And on update cursor autocmds, also called once (previously
at least twice).
behaviour:
- Now the outline window focus and highlight can update on each cursor
move (previously CursorHold, dependent on updatetime). This is now
configurable as well.
- During fold-all/unfold-all operations, now the cursor will remain on
the same node (rather than same line in outline buffer).
- The performance improvement is not significantly observable since even
the old implementation can appear instant. One may even argue I am
fixing a problem that did not exist, but implementation-wise it's just
so much better now.
config:
- outline_window.auto_update_events, list of events to be passed to
create_user_autocmd for updating cursor focus in outline, and updating
outline items (refetching symbols), using keys cursor and items
respectively.
- outline_window.show_cursorline now supports 2 other string values:
'focus_in_outline'/'focus_in_code' which controls when to enable
cursorline. Setting to true retains the default behaviour of always
showing the cursorline. This was added because now that the cursor
focus on the outline could change on each CursorMoved, the cursorline
may pose to be qute attention-seeking during the outline cursor
updates. Hence `focus_in_outline` is added so that when focus is in
code, the cursorline for outline window is not shown.
'focus_in_code' is added so that a user who disabled
highlight_hovered_item can keep track of position in outline when
focus is in code, disabling cursorline when focus is in outline.
At any given time, if hide cursor is enabled and show_cursorline is a
string value, hiding of cursor will not be done if cursorline is not
shown in the the given situation.
implementation:
- The reason for the improvement in performance as described in the
first paragraph is due to merging of finding hover item and finding
the deepest matched node to put cursor, into writer.make_outline. This
done, when previously done in separate function, because after the
separate function (namely _highlight_hovered_item) finishes,
writer.make_outline is called *again* anyway.
- Autocmds to update cursor position in outline is now done per buffer
rather than global.
Somehow the auto unfold and unfold depth options still work perfectly,
for this we should thank simrat or which ever contributor that
modularized the folding module and made it adaptable :)
Closes#27
- Highlight group 'OutlineJumpHighlight' (links to Visual by default)
- Config: outline_window.jump_highlight_duration (integer for
milliseconds, or boolean to enable/disable)
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.
- Provider priorities can now be configured through `providers.priority`
- Each provider can have a get_status() function that returns a string
for its status. For LSP it returns the client name.
- :OutlineStatus logic refactored, together with provider checking
functions in `providers/init.lua`
- Switch from vim.lsp.buf_get_clients to vim.lsp.get_active_clients
(former was deprecated)
- Fixed a careless mistake from symbols-outline that seems to be an
unreachable bug (lsp)