nvim-tree.lua icon indicating copy to clipboard operation
nvim-tree.lua copied to clipboard

Cycle through files with open buffers

Open muhmud opened this issue 2 years ago • 7 comments

Is your feature request related to a problem? Please describe. I would like to flip between the file locations for buffers I have open.

Describe the solution you'd like A shortcut that cycles through the file locations for open buffers, starting with the current directory and working outwards.

muhmud avatar Apr 01 '22 12:04 muhmud

That is an interesting feature. It could be used for other cycles e.g. git modified files.

Question: I imagine we would keep a list of files we had already cycled, so we don't hit the same one twice. How do we know when to clear this list i.e. stop cycling?

Alternatively, if we did not have a list, can you describe an algorithm that would cycle from the currently selected file, that would not get stuck in a loop?

alex-courtis avatar Apr 02 '22 01:04 alex-courtis

To start, I think there should be two directions of travel: forward & backward.

I think the easiest implementation would just cycle through the buffers in the order returned by the buffers command. It should be possible to find the current location in this list, or the closest buffer to it, and then either move to the next or previous, depending on the direction. The output of the buffers command essentially acts as the list.

There are, however, two other types of movement that I was thinking about: searching out from the current location and buffers in MRU order.

For searching out from the current location, consider the following, where the buffers are shown under the directories for the files they relate to:

└─ home/el
   ├─ .config/nvim/plugged/buffer-tree-explorer
   │  ├─ ◎ README.md ⇒ 76
   │  └─ autoload
   │     ├─ • buffer.vim ⇒ 29
   │     ├─ • explorer.vim ⇒ 27
   │     └─ • tree.vim ⇒ 26
   ├─ personal
   │  ├─ • advent-of-code/2020/day_1.py ⇒ 74
   │  └─ • machine-learning/btc/data.csv ⇒ 75
   └─ • media/videos/video.html ⇒ 22

If the current location was buffer.vim, moving forward would take us in alphabetical order through the files in the current directory, then the next sibling directory, and so on. Moving backward would move in the opposite direction.

For MRU, we would most likely need to maintain a list of buffers and the times at which they were last accessed, and then traverse this list in a similar way to the output of the buffers command.

Do this help clarify?

muhmud avatar Apr 02 '22 03:04 muhmud

To start, I think there should be two directions of travel: forward & backward.

If the current location was buffer.vim, moving forward would take us in alphabetical order through the files in the current directory, then the next sibling directory, and so on. Moving backward would move in the opposite direction.

(1) It sounds like an implementation similar to prev/next_git_item would do the job. We would achieve alphabetical ordering from the tree itself. We would probably want to look inside directories, rather than skipping over them like the git impl.

I think the easiest implementation would just cycle through the buffers in the order returned by the buffers command.

bufnr ordering would technically work, however I think that would be very confusing as we would jump "randomly" around the tree.

If the current location was buffer.vim, moving forward would take us in alphabetical order through the files in the current directory, then the next sibling directory, and so on. Moving backward would move in the opposite direction.

1 would cover this case, unless I am misunderstanding.

alex-courtis avatar Apr 02 '22 03:04 alex-courtis

Yep, make sense

muhmud avatar Apr 02 '22 03:04 muhmud

MRU: sorry, I'm not touching that ;)

Maintaining MRU in vim can be very tricky, as vim doesn't provide such a facility. It is further complicated when you bring windows/tabs into the mix. Non-file buffers are especially problematic as they often don't set their filetype/buftype until after BufEnter, which is the last event you can hook into. There are a few plugins that do some MRU however I am not aware of any that expose things nicely with an API.

I have my own window specific MRU implementation for forward/back/tagstack however it is hacky and finicky and I don't want to release it as a plugin.

alex-courtis avatar Apr 02 '22 04:04 alex-courtis

Spec for prev/next_open_buffer

File search: prev/next selects open in current folder

Folder search (open): as per file search

Folder search (closed): file system search for prev/next open file in directory. Does not open folder unless match is found.

Prev no match: sibling folder search in reverse order. Move up folder and folder search upwards from current.

Next no match: move up folder and folder/file search downwards from current.

PRs are gratefully appreciated ;)

alex-courtis avatar Apr 02 '22 04:04 alex-courtis

I think MRU cycling should be provided as a standalone plugin, this is enough complicated to track as it is, and would be out of the scope of nvim-tree i believe. Although if such plugin existed, it would make sense to add integration with nvim-tree :) PR will be gladly appreciated. Note that i'd like finishing the renderer refactoring before adding new functionalities to it, the code is bad enough as it is (if you would implement such thing as buffer information in the tree).

kyazdani42 avatar Apr 02 '22 10:04 kyazdani42

Thanks for the feature request.

Unfortunately, nvim-tree is in a stable, feature complete state and we do not intend to add such features.

alex-courtis avatar Oct 15 '22 04:10 alex-courtis

vim-bufkill has added an excellent MRU implementation that I use every day.

alex-courtis avatar Oct 15 '22 04:10 alex-courtis