neo-tree.nvim
neo-tree.nvim copied to clipboard
feat: add preview command and position handling
This PR adds commands to preview nodes which correspond to files or file positions. It also allows the standard open commands to open files at positions given by position nodes.
A position node is defined as a node with the field extra.position
, which is an array-like table of the form { <line>, <column> }
, where the line and column numbers are 0-based (it might be more sensible to change this to (1, 0)-based indexing). If the field extra.end_position
is present, previewing the node will highlight the range between position
and end_positions
.
The code is adapted from mrbjarksen/neo-tree-diagnostics.nvim#1. It is likely that this feature will need some tweaking and testing before it can be merged. I have added the branch native-open-and-preview to neo-tree-diagnostics.nvim to test this feature using position nodes.
Codecov Report
Merging #482 (8665fac) into main (5bb0a38) will decrease coverage by
0.94%
. The diff coverage is14.85%
.
@@ Coverage Diff @@
## main #482 +/- ##
==========================================
- Coverage 52.60% 51.66% -0.95%
==========================================
Files 46 47 +1
Lines 5714 5888 +174
==========================================
+ Hits 3006 3042 +36
- Misses 2708 2846 +138
Impacted Files | Coverage Δ | |
---|---|---|
lua/neo-tree/defaults.lua | 96.87% <ø> (ø) |
|
lua/neo-tree/events/init.lua | 100.00% <ø> (ø) |
|
lua/neo-tree/utils.lua | 48.26% <4.16%> (-0.91%) |
:arrow_down: |
lua/neo-tree/sources/common/commands.lua | 8.30% <5.26%> (-0.44%) |
:arrow_down: |
lua/neo-tree/sources/common/preview.lua | 18.18% <18.18%> (ø) |
|
lua/neo-tree/setup/init.lua | 73.24% <100.00%> (-0.07%) |
:arrow_down: |
lua/neo-tree/ui/highlights.lua | 93.68% <100.00%> (+0.06%) |
:arrow_up: |
lua/neo-tree/sources/common/file-items.lua | 67.40% <0.00%> (-1.02%) |
:arrow_down: |
lua/neo-tree/sources/common/components.lua | 61.60% <0.00%> (-0.22%) |
:arrow_down: |
... and 5 more |
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.
I played around with it and I found that I intuitively wanted it to work a different way. I am picturing a "preview mode", where once activated, it previews whatever my cursor is focused on and follows that focus, until the "preview mode" is toggle off.
When the preview goes off, I'm not sure if it should stick on the last file or go back to the file that was open beforehand.
I would also prefer if there were a single mapping that toggled it off and on.
I think there also needs to be some visual indication that preview mode is enabled.
One way to accomplish the above is if it previews in a floating window where the title bar has some text to indicate that it is a preview window. Then when it is closed it is clear that it should just disappear and you will be left with the original windows underneath it. Then hitting enter, or any other command that normally opens a file will close that preview window and open the file as normal.
What do you think?
I agree that it would be great to have the preview follow the focused node, and that is how I envisioned it at first. At the time, I had some issues with CursorMoved
events (switching windows caused errors). It might be time to revisit this. The suggestions in #134 to use vim.loop
sound promising, but I'll admit the API has gone over my head when I've tried to learn to use it.
In my mind, the preview should ideally be a sort of answer to 'What happens if I open this?', showing exactly which window will be used and the view within said window if you choose to press enter, while changing nothing about the state of the user space (e.g. listed buffers, cursor positions, etc.) while it is active. Note that the preview commands in their current state do not entirely accomplish this.
Using a floating window might be more sensible, being less complex and only losing the ability to see which window will be used. I'm also not sure how to show visual indication using the method above. Another option, although less ideal, is using the built-in preview window.
I'd imagine the behavior of a preview is very opinionated and it may be worth implementing multiple options to choose from. I don't know if that is worth the extra maintenance though.
I'll look into making the preview follow the focus for now.
I agree that it would be great to have the preview follow the focused node, and that is how I envisioned it at first. At the time, I had some issues with
CursorMoved
events (switching windows caused errors).
Ideally showing the preview should not have to focus that preview window, so the focus should stay in the Neo-tree window. AT least that's how I picture it.
I'd imagine the behavior of a preview is very opinionated and it may be worth implementing multiple options to choose from. I don't know if that is worth the extra maintenance though.
I think in this case it is worthwhile because I'd imagine the preference will be pretty evenly split. If you want, I can add the floating window code (my preference) while you focus on the current "where it would normally open" code.
I'm also not sure how to show visual indication using the method above.
I was thinking that we could just add a window local variable that acts as a flag, then it could be added to someone's customized statusline or winbar. Something like 'vim.w.neo_tree_preview = 1'. Not everyone digs that deep into customizing their statusline/winbar, but for those of us that do then this would be enough.
Ideally showing the preview should not have to focus that preview window, so the focus should stay in the Neo-tree window. AT least that's how I picture it.
I agree. What I meant was that manually switching windows while the preview was active caused issues. Sorry if I wasn't clear.
I think in this case it is worthwhile because I'd imagine the preference will be pretty evenly split. If you want, I can add the floating window code (my preference) while you focus on the current "where it would normally open" code.
That sounds good. It shouldn't be too much trouble to hook into my existing preview module, opening a new floating window instead of using findWindow
. I'll leave it to you if you want to go that route or implement it separately.
I was thinking that we could just add a window local variable that acts as a flag, then it could be added to someone's customized statusline or winbar. Something like 'vim.w.neo_tree_preview = 1'. Not everyone digs that deep into customizing their statusline/winbar, but for those of us that do then this would be enough.
That's a good idea, I hadn't thought of that. It's probably the best way to go.
I just added a toggle_preview
command. It was simpler than I thought and I'm not having the same issues I had before. I've only tested it a small amount though. Let me know if you find anything.
I've implemented the fixes you mentioned. It was more trouble than I was expecting as I ran into a mess of autocommands, mostly triggered by jumping windows in get_appropriate_window
, which took a while to debug. It seems to be fixed now.
One thing I noticed was that entering a neo-tree buffer from another neo-tree buffer does not trigger NeoTreeBufferLeave
, since the event handler for BufEnter
returns early if the entered buffer belongs to neo-tree. I'm not sure if this is intentional or not, so I haven't touched it, but it means that the preview mode will not be turned off when switching sources. This could be fixed by adding an event handler for NeoTreeBufferEnter
as well, if you don't want to change this.
One thing I noticed was that entering a neo-tree buffer from another neo-tree buffer does not trigger
NeoTreeBufferLeave
, since the event handler forBufEnter
returns early if the entered buffer belongs to neo-tree. I'm not sure if this is intentional or not, so I haven't touched it,
No, that's not intentional. I just never considered that situation before. It should trigger a NeoTreeBufferLeave
followed by a NeoTreeBufferEnter
. I'll put that in as a bug.
Greatest feature! When there's no open buffer (such as starting with the alpha-nvim greeting), disabling preview causes some errors: Other than that, it works great.
E5108: Error executing lua: ...rt/neo-tree.nvim/lua/neo-tree/sources/common/preview.lua:150: Vim(append):Error executing lua callback: ..
.are/nvim/site/pack/packer/start/alpha-nvim/lua/alpha.lua:550: Cursor position outside buffer
stack traceback:
[C]: in function 'nvim_win_set_cursor'
...are/nvim/site/pack/packer/start/alpha-nvim/lua/alpha.lua:550: in function 'draw'
...are/nvim/site/pack/packer/start/alpha-nvim/lua/alpha.lua:566: in function 'redraw'
...are/nvim/site/pack/packer/start/alpha-nvim/lua/alpha.lua:473: in function <...are/nvim/site/pack/packer/start/alpha-nvim/lua/a
lpha.lua:473>
[C]: in function 'nvim_win_set_buf'
...rt/neo-tree.nvim/lua/neo-tree/sources/common/preview.lua:150: in function 'setBuffer'
...rt/neo-tree.nvim/lua/neo-tree/sources/common/preview.lua:73: in function 'revert'
...t/neo-tree.nvim/lua/neo-tree/sources/common/commands.lua:400: in function 'func'
.../packer/start/neo-tree.nvim/lua/neo-tree/ui/renderer.lua:695: in function <.../packer/start/neo-tree.nvim/lua/neo-tree/ui/rend
erer.lua:693>
stack traceback:
[C]: in function 'nvim_win_set_buf'
...rt/neo-tree.nvim/lua/neo-tree/sources/common/preview.lua:150: in function 'setBuffer'
...rt/neo-tree.nvim/lua/neo-tree/sources/common/preview.lua:73: in function 'revert'
...t/neo-tree.nvim/lua/neo-tree/sources/common/commands.lua:400: in function 'func'
.../packer/start/neo-tree.nvim/lua/neo-tree/ui/renderer.lua:695: in function <.../packer/start/neo-tree.nvim/lua/neo-tree/ui/rend
erer.lua:693>
😱 OH NO! A stack trace that includes two different plugins! 😱
Seriously though, I'm going to open a new issue for this.
Maybe a check before reverting the buffer is all, if there isn't a previous buffer open a new one... Just thinking out loud, haven't read the code yet.