elihunter173 / dirbuf.nvim

A file manager for Neovim which lets you edit your filesystem like you edit text
GNU Affero General Public License v3.0
425 stars 6 forks source link

Empty buffers shown when '-' key is used on files in symlinked directories #53

Open andrewferrier opened 2 years ago

andrewferrier commented 2 years ago

I think I have found quite an obscure bug in dirbuf where empty dirbuf buffers are shown with certain kinds of symlinked directories setups. It's one that I hit reasonably often because I use a lot of symlinks in my config setup. I've bisected dirbuf and I'm almost certain the problem was introduced by commit 2fddd65adb. I think I've established some reliable recreation steps also:

  1. Install NVIM v0.8.0-dev-1109-g72e104142 (although I'm not sure the NeoVim version actually matters). I'm using Arch Linux but I don't think it matters.

  2. Execute the following commands to create a directory structure:

    cd /tmp
    mkdir abc
    ln -s abc def
    mkdir def/ghi
    touch def/ghi/xyz.lua
  1. Create a NeoVim config file called dirbuf-test.vim in your home directory with these contents (obviously adapt path to wherever you have dirbuf checked out):
    set rtp+=/home/user/.local/share/nvim/site/pack/packer/start/dirbuf.nvim

    runtime! plugin/dirbuf.vim

    lua require("dirbuf").setup({})
  1. Open NeoVim with nvim --noplugin -u ~/dirbuf-test.vim. Do not open any files from the command line (this is important).

  2. Open xyz.lua from the NeoVim command line with :e /tmp/def/ghi/xyz.lua (it is important to use the symlinked name).

  3. Hit -

  4. Observe that the buffer is empty! (This is supposed to be showing the contents of /tmp/def/ghi, so should include xyz.lua).

  5. If you continue to hit -, the parent buffers are shown correctly.

If I move dirbuf to the commit before 2fddd65adb, the problem listed in step (7) does not occur.

Since I noted the commit is related to autochdir, for the record that option is off for me (the default).

Thanks as always for your hard work on dirbuf! Hope the above steps help narrow things down quickly.

andrewferrier commented 2 years ago

Since I observed that in commit https://github.com/elihunter173/dirbuf.nvim/commit/2fddd65adb89d26cff42eb0a797dd82ef9a8a2a3 the only non-test change is to use nvim_buf_get_name() it looks like this NeoVim issue might be related: https://github.com/neovim/neovim/issues/18183 ?

andrewferrier commented 2 years ago

I wonder if using vim.fn.resolve() in the check might help? Perhaps a symlinked path is getting compared with a non-symlinked path? Sorry, haven't had time to explicitly check that yet.

robertgzr commented 1 year ago

the solution is recommended by the vim.fn.simplify help text:

Note: The combination "dir/.." is only removed if "dir" is a searchable directory or does not exist. On Unix, it is also removed when "dir" is a symbolic link within the same directory. In order to resolve all the involved symbolic links before simplifying the path name, use |resolve()|.

diff --git a/lua/dirbuf.lua b/lua/dirbuf.lua
index 3dad030..552402f 100644
--- a/lua/dirbuf.lua
+++ b/lua/dirbuf.lua
@@ -30,7 +30,7 @@ end
 -- This exists to ensure that all paths are displayed in a consistent way and
 -- to simplify path manipulation logic.
 local function normalize_path(path)
-  path = vim.fn.simplify(vim.fn.fnamemodify(path, ":p"))
+  path = vim.fn.simplify(vim.fn.resolve(vim.fn.fnamemodify(path, ":p")))
   -- On Windows, simplify keeps the path_separator on directories
   if path:sub(-1, -1) == fs.path_separator then
     path = vim.fn.fnamemodify(path, ":h")