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

File Preview

Open bennypowers opened this issue 2 years ago • 18 comments

I would love to have file preview while the cursor is on a file, in both the sidebar and float windows

bennypowers avatar Feb 08 '22 19:02 bennypowers

I would (as usual) recommend fzf-lua first since it also relatively stable, and it provides mature fzf-fuzzy-finding and grep-ing (using rg is available). But it could be a good idea to implement it inside neo-tree itself.

nyngwang avatar Feb 08 '22 23:02 nyngwang

Telescope also has fuzzy file preview

but fuzzy finding a file by name and browsing a file tree are two separate cognitive tasks.

bennypowers avatar Feb 09 '22 14:02 bennypowers

I agree that it would be nice to add the preview to the floating window and I can see how that should work just based on my experience with telescope and fzf.

What requires more discussion is what it means to add a preview to the sidebar, and how exactly should that behave? When neo-tree is in a sidebar, Is the preview in a floating window or or a normal split? If it's in a split, does it hijack another window or create a new one? What about when Neo-tree is in "split" mode and not a sidebar? Do we need to accommodate all of the above and add configurations?

cseickel avatar Feb 09 '22 15:02 cseickel

As an initial straw proposal, I suggest that placing the cursor on a file should open a new buffer which previews the contents of that file. if a buffer for that file is already open, switch to it. when the cursor moves, if that file didn't already have a buffer, close it

That would more-or-less map with atom/v****e behaviour

bennypowers avatar Feb 09 '22 19:02 bennypowers

Telescope also has fuzzy file preview

but fuzzy finding a file by name and browsing a file tree are two separate cognitive tasks.

You can set the cwd option in fzf-lua to preview files under the current folders and/or any folders with respect to cwd. But yeah, people are telescoping nowadays. I just personally hate it :) It's too heavy and energy-consuming. (and since tj is busy with YT things, I assume he have little time solving those tons of issues there)

Just previewing files without the ability to filtering them, seems to be just a fancy eye-catching function. I used to try many, all uninstalled.

nyngwang avatar Feb 10 '22 08:02 nyngwang

@nyngwang I'm really glad you found a tool that you enjoy for fuzzy finding. I'm also equally happy for you that you've discovered you don't really need a file browser.

This feature request has nothing to do with fuzzy finding, and this repo is primarily a file browser, so while I appreciate that you want me to use your fuzzy finding tool instead of this package, perhaps we could continue that discussion in a separate forum.

bennypowers avatar Feb 10 '22 08:02 bennypowers

As an initial straw proposal, I suggest that placing the cursor on a file should open a new buffer which previews the contents of that file. if a buffer for that file is already open, switch to it. when the cursor moves, if that file didn't already have a buffer, close it

That would more-or-less map with atom/v****e behaviour

I didn't realize vscode has this feature. Can you provide a link to a demo or documentation page?

cseickel avatar Feb 10 '22 12:02 cseickel

https://github.dev/nvim-neo-tree/neo-tree.nvim

single-click (NOT double-click) any file in the file explorer

bennypowers avatar Feb 10 '22 12:02 bennypowers

Oh yeah, I wasn't even thinking about that as a preview. With that, the difference between clicking and double clicking is that clicking uses a tab that can be taken over by the next clicked file while double clicking explicitly creates a new one that cannot be reused, and the next single clicked tab creates a new tab for the subsequent single clicked previews.

I'm not sure how this maps to vim's tab/buffer model. If you are displaying buffers as tabs, then would a previewed buffer be unlisted when another file is previewed to remove it from the tabline? Is that the equivalent here?

cseickel avatar Feb 10 '22 13:02 cseickel

I'd think cursor-over maps to single click and enter maps to double click

Doesn't need to be exactly like the M$ editor, just brought it as an example of a common ui. A floating window would likely also be ok, but the advantage to a full 'temp' buffer is that user can see more columns in her buffer when previewing

bennypowers avatar Feb 10 '22 13:02 bennypowers

I can see the utility in this, but I think I prefer the floating window preview just so that the existing window layout is not ruined unintentionally. This will likely need a lot of configuration options because everyone's tastes are different. I'm not going to do this immediately, but I'll keep thinking about it.

cseickel avatar Feb 10 '22 18:02 cseickel

trouble.nvim already implements a file preview in the last accessed window. maybe it can be useful to check it out as inspiration

caenrique avatar Apr 26 '22 15:04 caenrique

preview on the preview window, it's really useful

ShiChenCong avatar May 30 '22 02:05 ShiChenCong

You could consider utilizing the builtin functionality in vim.loop.fs_read

Basically when you open a directory, gather the file descriptors for each item in the directory, and when a user hovers over an item for n ticks (you can utilize vim.loop.hrtime to gather a ticks on CPU count which is quite small and should work great for smaller than 1 second intervals), check to see if a preview is up. If its not, open a floating buffer and display the return results of fs_read into that buffer

Not a simple task but should be relatively straightforward I think.

Edit: Selfish note, getting file explorer developers/maintainers to utilize vim.loop more makes my life easier on my project lol

miversen33 avatar May 30 '22 15:05 miversen33

I will suggest using https://github.com/ibhagwan/fzf-lua as a companion to this plugin. You can preview on-fzf-ing. For example:

https://user-images.githubusercontent.com/24765272/171303964-e5314b0e-fee5-4fab-89d1-50efdd6ab3c1.mov

This is a feature that the author of fzf-lua had spent a lot of time tuning (I personally created >30 issues there debugging). So in my understanding "make this feature work" might be simple, but "make this feature work smoothly" is hard.

nyngwang avatar Jun 01 '22 00:06 nyngwang

@nyngwang Its worth calling out that what fzf-lua does is exactly what I mentioned above Checking out the utils.lua file read_file and read_file_async

M.read_file = function(filepath)
  local fd = vim.loop.fs_open(filepath, "r", 438)
  if fd == nil then return '' end
  local stat = assert(vim.loop.fs_fstat(fd))
  if stat.type ~= 'file' then return '' end
  local data = assert(vim.loop.fs_read(fd, stat.size, 0))
  assert(vim.loop.fs_close(fd))
  return data
end

M.read_file_async = function(filepath, callback)
  vim.loop.fs_open(filepath, "r", 438, function(err_open, fd)
    if err_open then
      -- we must schedule this or we get
      -- E5560: nvim_exec must not be called in a lua loop callback
      vim.schedule(function()
        M.warn(("Unable to open file '%s', error: %s"):format(filepath, err_open))
      end)
      return
    end
    vim.loop.fs_fstat(fd, function(err_fstat, stat)
      assert(not err_fstat, err_fstat)
      if stat.type ~= 'file' then return callback('') end
      vim.loop.fs_read(fd, stat.size, 0, function(err_read, data)
        assert(not err_read, err_read)
        vim.loop.fs_close(fd, function(err_close)
          assert(not err_close, err_close)
          return callback(data)
        end)
      end)
    end)
  end)
end

Lots of wrapping around the same core logic :) Its a common way of reading files for peeks as its supported directly in native neovim (via the vim.loop logic).

Also that plugin is pretty nifty!

miversen33 avatar Jun 01 '22 00:06 miversen33

@miversen33 The author is a beast. It seems that you're the chosen one to understand its beauty. I highly recommend you give it a try. I have been using it since 11/2021 and have not encountered any problem with it this quarter. It is very stable!

nyngwang avatar Jun 01 '22 00:06 nyngwang

You could consider utilizing the builtin functionality in vim.loop.fs_read

Basically when you open a directory, gather the file descriptors for each item in the directory, and when a user hovers over an item for n ticks (you can utilize vim.loop.hrtime to gather a ticks on CPU count which is quite small and should work great for smaller than 1 second intervals), check to see if a preview is up. If its not, open a floating buffer and display the return results of fs_read into that buffer

I just learned a new trick,it's called "programming by procrastination". Basically, just put something off for long enough that someone else architects the solution in the issue comments! I wonder if the solution will grow if I let it sit longer... 🤔

Seriously though, thanks for the hints. I'll put them to use when I get to this.

cseickel avatar Jun 01 '22 02:06 cseickel

Thanks to @mrbjarksen, this is functional in main right now with the P mapping. There are still a few more things to add before it is complete:

  • [x] Add option to preview in floating window
  • [ ] Come up with a good indicator that preview mode is active for the current "preview in existing split" method
  • [x] Add documentation
  • [ ] Add tests

cseickel avatar Aug 17 '22 01:08 cseickel

For all those interested, there is a draft PR #502 with a fully functional preview in a float window. My question is, should the default preview be the float version or the original "preview in split" version? Right now there are mappings for both (F for float and P for split) but I intend to just leave a single toggle_preview mapping that does one or the other.

cseickel avatar Sep 05 '22 15:09 cseickel