Skip to content

nvim-tree allows the creation of files over sshfs, but they can't be accessed #2794

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
futurisold opened this issue Jun 5, 2024 · 19 comments · Fixed by #2893 or #2922
Closed

nvim-tree allows the creation of files over sshfs, but they can't be accessed #2794

futurisold opened this issue Jun 5, 2024 · 19 comments · Fixed by #2893 or #2922
Labels
bug Something isn't working PR please nvim-tree team does not have the bandwidth to implement; a PR will be gratefully appreciated regression Existing functionality broken

Comments

@futurisold
Copy link

Description

I'm using nosduco/remote-sshfs.nvim to work remotely over sshfs.

nvim-tree doesn't show anything from the mounted folder on the server, however, you can perform edit operations from nvim-tree directly, such as creating a new file (see image, I basically pressed a on top of the folder in nvim-tree panel).

I checked on server and the file was indeed created.

Thanks

Neovim version

NVIM v0.10.0
Build type: Release
LuaJIT 2.1.1716656478


"nvim-tree.lua": { "branch": "master", "commit": "517e4fbb9ef3c0986da7047f44b4b91a2400f93c" }

Operating system and version

macOS Sonoma 14.5 (23F79)

Windows variant

No response

nvim-tree version

{ "branch": "master", "commit": "517e4fbb9ef3c0986da7047f44b4b91a2400f93c" }

Clean room replication

vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1

vim.cmd [[set runtimepath=$VIMRUNTIME]]
vim.cmd [[set packpath=/tmp/nvt-min/site]]
local package_root = "/tmp/nvt-min/site/pack"
local install_path = package_root .. "/packer/start/packer.nvim"
local function load_plugins()
  require("packer").startup {
    {
    "wbthomason/packer.nvim",
    "nvim-tree/nvim-tree.lua",
    "nvim-tree/nvim-web-devicons",
    -- ADD PLUGINS THAT ARE _NECESSARY_ FOR REPRODUCING THE ISSUE
    'nosduco/remote-sshfs.nvim',
    "nvim-telescope/telescope.nvim", branch = "0.1.x",
    "nvim-lua/plenary.nvim",
    },

    config = {
      package_root = package_root,
      compile_path = install_path .. "/plugin/packer_compiled.lua",
      display = { non_interactive = true },
    },
  }
end
if vim.fn.isdirectory(install_path) == 0 then
  print "Installing nvim-tree and dependencies."
  vim.fn.system { "git", "clone", "--depth=1", "https://github.com/wbthomason/packer.nvim", install_path }
end
load_plugins()
require("packer").sync()
vim.cmd [[autocmd User PackerComplete ++once echo "Ready!" | lua setup()]]
vim.opt.termguicolors = true
vim.opt.cursorline = true

-- MODIFY NVIM-TREE SETTINGS THAT ARE _NECESSARY_ FOR REPRODUCING THE ISSUE
_G.setup = function()
    require("nvim-tree").setup {}
    require('remote-sshfs').setup {
      connections = {
        ssh_configs = { -- which ssh configs to parse for hosts list
          vim.fn.expand "$HOME" .. "/.ssh/config",
          "/etc/ssh/ssh_config",
        },
        sshfs_args = { -- arguments to pass to the sshfs command
          "-o reconnect",
          "-o auto_cache",
          "-o Ciphers=aes128-ctr",
          "-o ConnectTimeout=5",
          "-C",
          "-o cache_timeout=60",
          "-o cache=yes",
        },
      },
      mounts = {
        base_dir = vim.fn.expand "$HOME" .. "/.sshfs/", -- base directory for mount points
        unmount_on_exit = true, -- run sshfs as foreground, will unmount on vim exit
      },
      handlers = {
        on_connect = {
          change_dir = true, -- when connected change vim working directory to mount point
        },
        on_disconnect = {
          clean_mount_folders = false, -- remove mount point folder on disconnect/unmount
        },
        on_edit = {}, -- not yet implemented
      },
      ui = {
        select_prompts = false, -- not yet implemented
        confirm = {
          connect = true, -- prompt y/n when host is selected to connect to
          change_dir = false, -- prompt y/n to change working directory on connection (only applicable if handlers.on_connect.change_dir is enabled)
        },
      },
      log = {
        enable = false, -- enable logging
        truncate = false, -- truncate logs
        types = { -- enabled log types
          all = false,
          util = false,
          handler = false,
          sshfs = false,
        },
      },
    }
    require('telescope').setup {}

end

-- UNCOMMENT this block for diagnostics issues, substituting pattern and cmd as appropriate.
-- Requires diagnostics.enable = true in setup.
--[[
vim.api.nvim_create_autocmd("FileType", {
  pattern = "lua",
  callback = function()
    vim.lsp.start { cmd = { "lua-language-server" } }
  end,
})
]]

Steps to reproduce

1. nvim -nu /tmp/nvt-min.lua
2. :RemoteSSHFSConnect (pick server; have it listed in your ~/.ssh/config)
3. :NvimTreeOpen
4. expand the mounted folder (should be ~ on your server)

Expected behavior

List all files, directories, normal navigation as one would have locally.

Actual behavior

image

@futurisold futurisold added the bug Something isn't working label Jun 5, 2024
@alex-courtis
Copy link
Member

Initial thoughts: this may be a file system notification issue. Does the folder show after you manually refresh R or restart vim?

I don't have any knowledge about ssh file systems however I imagine that libuv would have issues. It's definitely not something that nvim-tree is aware of or can handle.

Suggestion: raise an issue with nosduco/remote-sshfs.nvim and see what ideas they have then we can talk further. I notice they copied our log subsystem :)

@alex-courtis alex-courtis added awaiting feedback and removed bug Something isn't working labels Jun 7, 2024
@futurisold
Copy link
Author

Thanks, @alex-courtis. Unfortunately, no, I can only create files directly from nvim-tree explorer. I will try to check on their side. Will close this and will reopen if necessarry.

@futurisold futurisold reopened this Jun 11, 2024
@futurisold
Copy link
Author

futurisold commented Jun 11, 2024

Upon further digging, this is definitely a nvim-tree issue.

The issue arises solely with the nvim-tree enabled, even when using the most basic clean configuration suggested by you (&pasted below), while mounting the folder with sshfs then nvim --clean [ mounted dir ] works.

vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1

vim.cmd [[set runtimepath=$VIMRUNTIME]]
vim.cmd [[set packpath=/tmp/nvt-min/site]]
local package_root = "/tmp/nvt-min/site/pack"
local install_path = package_root .. "/packer/start/packer.nvim"
local function load_plugins()
  require("packer").startup {
    {
    "wbthomason/packer.nvim",
    "nvim-tree/nvim-tree.lua",
    "nvim-tree/nvim-web-devicons",
    },

    config = {
      package_root = package_root,
      compile_path = install_path .. "/plugin/packer_compiled.lua",
      display = { non_interactive = true },
    },
  }
end
if vim.fn.isdirectory(install_path) == 0 then
  print "Installing nvim-tree and dependencies."
  vim.fn.system { "git", "clone", "--depth=1", "https://github.com/wbthomason/packer.nvim", install_path }
end
load_plugins()
require("packer").sync()
vim.cmd [[autocmd User PackerComplete ++once echo "Ready!" | lua setup()]]
vim.opt.termguicolors = true
vim.opt.cursorline = true

-- MODIFY NVIM-TREE SETTINGS THAT ARE _NECESSARY_ FOR REPRODUCING THE ISSUE
_G.setup = function()
    require("nvim-tree").setup {}
end

-- UNCOMMENT this block for diagnostics issues, substituting pattern and cmd as appropriate.
-- Requires diagnostics.enable = true in setup.
--[[
vim.api.nvim_create_autocmd("FileType", {
  pattern = "lua",
  callback = function()
    vim.lsp.start { cmd = { "lua-language-server" } }
  end,
})
]]

@rag-hav
Copy link

rag-hav commented Jun 15, 2024

Hi, facing the same issue. I have successfully used this plugin for fuse mounted file system using sshfs before, so it broke in some recent commit.

@alex-courtis
Copy link
Member

Thank you, I can reproduce this with sshfs and default nvim-tree config. The directories are seen by nvim-tree, but not enumerated.

Top level contains only directories: in this case baz and foo are seen, 2 is not.
This behaviour is nondeterministic - sometimes baz and foo are not seen.

: ; find .
.
./baz
./baz/2
./foo
./foo/bar
./foo/bar/1
[2024-06-15 14:12:29] [profile] START core init /home/alex/src/nvim-tree/r/2794/sfs
[2024-06-15 14:12:29] [profile] START git toplevel git_dir /home/alex/src/nvim-tree/r/2794/sfs
[2024-06-15 14:12:29] [profile] END   git toplevel git_dir /home/alex/src/nvim-tree/r/2794/sfs 3ms
[2024-06-15 14:12:29] [profile] START explore init /home/alex/src/nvim-tree/r/2794/sfs
[2024-06-15 14:12:29] [profile] START explore populate_children /home/alex/src/nvim-tree/r/2794/sfs/baz
[2024-06-15 14:12:29] [profile] END   explore populate_children /home/alex/src/nvim-tree/r/2794/sfs/baz 1ms
[2024-06-15 14:12:29] [profile] START explore populate_children /home/alex/src/nvim-tree/r/2794/sfs/foo
[2024-06-15 14:12:29] [profile] END   explore populate_children /home/alex/src/nvim-tree/r/2794/sfs/foo 1ms
[2024-06-15 14:12:29] [profile] END   explore init /home/alex/src/nvim-tree/r/2794/sfs 2ms
[2024-06-15 14:12:29] [profile] END   core init /home/alex/src/nvim-tree/r/2794/sfs 7ms
[2024-06-15 14:12:29] [profile] START view open
[2024-06-15 14:12:29] [profile] END   view open 4ms
[2024-06-15 14:12:29] [profile] START draw
[2024-06-15 14:12:29] [profile] END   draw 0ms

open baz

[2024-06-15 14:12:34] [profile] START git toplevel git_dir /home/alex/src/nvim-tree/r/2794/sfs/baz
[2024-06-15 14:12:34] [profile] END   git toplevel git_dir /home/alex/src/nvim-tree/r/2794/sfs/baz 5ms
[2024-06-15 14:12:34] [profile] START explore init /home/alex/src/nvim-tree/r/2794/sfs/baz
[2024-06-15 14:12:34] [profile] START explore populate_children /home/alex/src/nvim-tree/r/2794/sfs/baz/2
[2024-06-15 14:12:34] [profile] END   explore populate_children /home/alex/src/nvim-tree/r/2794/sfs/baz/2 0ms
[2024-06-15 14:12:34] [profile] END   explore init /home/alex/src/nvim-tree/r/2794/sfs/baz 0ms
[2024-06-15 14:12:34] [profile] START draw
[2024-06-15 14:12:34] [profile] END   draw 0ms

Add a file 0 next to foo, no change.

@rag-hav
Copy link

rag-hav commented Jun 15, 2024

git bisect shows this to be the first bad commit

2d97059

@alex-courtis
Copy link
Member

It appears to be the fs_scandir_next that is failing. fs_stat seems reliable:

---@param handle uv.uv_fs_t
---@param cwd string
---@param node Node
---@param git_status table
local function populate_children(handle, cwd, node, git_status)
  local node_ignored = explorer_node.is_git_ignored(node)
  local nodes_by_path = utils.bool_record(node.nodes, "absolute_path")
  local filter_status = filters.prepare(git_status)
  while true do
    local name, t, err = vim.loop.fs_scandir_next(handle)
    log.line("dev", "child next %s %s %s", name, t, err)

    if not name then
      break
    end

    local abs = utils.path_join { cwd, name }

    local res, ok, errr = vim.loop.fs_stat(abs)
    log.line("dev", "child stat %s %s %s", res, ok, errr)
[2024-06-15 14:39:32] [profile] START core init /home/alex/src/nvim-tree/r/2794/sfs
[2024-06-15 14:39:32] [watcher] Watcher:new '/home/alex/src/nvim-tree/r/2794/sfs' nil
[2024-06-15 14:39:32] [watcher] Event:new '/home/alex/src/nvim-tree/r/2794/sfs'
[2024-06-15 14:39:32] [watcher] Event:start '/home/alex/src/nvim-tree/r/2794/sfs'
[2024-06-15 14:39:32] [profile] START git toplevel git_dir /home/alex/src/nvim-tree/r/2794/sfs
[2024-06-15 14:39:32] [profile] END   git toplevel git_dir /home/alex/src/nvim-tree/r/2794/sfs 2ms
[2024-06-15 14:39:32] [profile] START explore init /home/alex/src/nvim-tree/r/2794/sfs
[2024-06-15 14:39:32] [dev] child next baz nil nil
[2024-06-15 14:39:32] [dev] child stat table: 0x7b6359192200 nil nil
[2024-06-15 14:39:32] [profile] START explore populate_children /home/alex/src/nvim-tree/r/2794/sfs/baz
[2024-06-15 14:39:32] [profile] END   explore populate_children /home/alex/src/nvim-tree/r/2794/sfs/baz 0ms
[2024-06-15 14:39:32] [dev] child next foo nil nil
[2024-06-15 14:39:32] [dev] child stat table: 0x7b63591937e8 nil nil
[2024-06-15 14:39:32] [profile] START explore populate_children /home/alex/src/nvim-tree/r/2794/sfs/foo
[2024-06-15 14:39:32] [profile] END   explore populate_children /home/alex/src/nvim-tree/r/2794/sfs/foo 0ms
[2024-06-15 14:39:32] [dev] child next nil nil nil
[2024-06-15 14:39:32] [dev] nodes_by_path {}
[2024-06-15 14:39:32] [profile] END   explore init /home/alex/src/nvim-tree/r/2794/sfs 0ms
[2024-06-15 14:39:32] [profile] END   core init /home/alex/src/nvim-tree/r/2794/sfs 4ms
[2024-06-15 14:39:32] [profile] START view open
[2024-06-15 14:39:32] [profile] END   view open 4ms
[2024-06-15 14:39:32] [profile] START draw
[2024-06-15 14:39:32] [profile] END   draw 0ms

@alex-courtis
Copy link
Member

git bisect shows this to be the first bad commit

2d97059

Very interesting, it does look like the type detection was changed there.

Are you interested in creating a pull request to fix this one @rag-hav ? I reckon you're the best one to find real world test cases ;)

@alex-courtis alex-courtis added bug Something isn't working and removed awaiting feedback labels Jun 15, 2024
@alex-courtis alex-courtis reopened this Jun 15, 2024
@rag-hav
Copy link

rag-hav commented Jun 15, 2024

Will look into it, but I don't really have any experience with this.

@alex-courtis
Copy link
Member

Thanks mate! Dev and contribution docs.

@ydalton
Copy link

ydalton commented Jul 9, 2024

Out of curiousity, I checked out a previous commit, and found that this bug is actually a regression. I will run a git bisect to get the first bad commit.

Edit: according to git bisect, commit 2d97059 is the first bad commit.

@alex-courtis alex-courtis added regression Existing functionality broken PR please nvim-tree team does not have the bandwidth to implement; a PR will be gratefully appreciated labels Jul 11, 2024
@mxple
Copy link
Collaborator

mxple commented Sep 1, 2024

Should be fixed in #2893. Waiting review and merge.

alex-courtis added a commit that referenced this issue Sep 9, 2024
* add type fallback for nil types

* add PR suggestions

* Update lua/nvim-tree/explorer/explore.lua

Co-authored-by: Alexander Courtis <[email protected]>

* use type from fs_stat for sshfs compatibility

---------

Co-authored-by: Alexander Courtis <[email protected]>
@Thiggel
Copy link

Thiggel commented Sep 9, 2024

Thank you so much for fixing this. Now however, nvim-tree is extremely slow when using it on an sshfs mount, possibly because it is scanning the file system every time you open nvim tree. Is there a way to optimize this? Perhaps you could assume that when working on a mount, the current machine is the only one working on the file system and hence there is no need to update it every time?

@mxple
Copy link
Collaborator

mxple commented Sep 9, 2024

@Thiggel I believe the slowness you are experiencing is network latency and not nvim-tree. Could you test the mount using a file explorer or ls/cd/cat to see if there is indeed network lag? I personally have not experienced slowness but I can investigate if the problem persists.

@gerritwellecke
Copy link

@mxple I have had a similar "lag" only when using R to reload the entire tree. Otherwise it was rather performant and enjoyable.

@alex-courtis
Copy link
Member

@Thiggel Unfortunately there's not much we can do here - nvim-tree has to look at each file.

Perhaps you could assume that when working on a mount, the current machine is the only one working on the file system and hence there is no need to update it every time?

You might like to experiment with filesystem watchers: disabling or enabling (default)

:help nvim-tree.filesystem_watchers.enable

You can be targeted about it, disabling them for specific directories:

:help nvim-tree.filesystem_watchers.ignore_dirs

alex-courtis added a commit that referenced this issue Sep 22, 2024
alex-courtis added a commit that referenced this issue Sep 22, 2024
* refactor(#2875): multi instance renderer: remove unused code

* Revert "fix(#2794): sshfs compatibility (#2893)"

This reverts commit 2d6e64d.
@alex-courtis
Copy link
Member

@mxple I've had to revert #2920 this change as there was an issue with symlinks:

For symlinks:
vim.loop.fs_scandir_next returns a type "link"
vim.loop.fs_stat returns a type "file"

I'd be most grateful if we could work together to create a complete solution.

@alex-courtis alex-courtis reopened this Sep 22, 2024
mxple added a commit to mxple/nvim-tree.lua that referenced this issue Sep 22, 2024
@mxple
Copy link
Collaborator

mxple commented Sep 22, 2024

Hi @alex-courtis . Luckily, it seems there is a pretty simple fix where we replace fs_stat with fs_lstat in init.lua. I've tested it and it works. However, I noticed that a recent commit has broken sshfs compatibility. Running a bisect, it seems commit cd9c6db is the first bad commit.

I believe I have fixed both issues in (#2922). Please test and review.

@alex-courtis
Copy link
Member

However, I noticed that a recent commit has broken sshfs compatibility. Running a bisect, it seems commit cd9c6db is the first bad commit.

Apologies, yes, that was a bad refactor/rebase.

alex-courtis added a commit that referenced this issue Sep 28, 2024
* Revert "revert(#2794): sshfs compatibility (#2920)"

This reverts commit 8405ecf.

Fix for symlinks is simple

* fix sshfs compatibility with symlinks

* add suggestions

* revert variable name change to ease multi-instance feature branch conflicts

---------

Co-authored-by: Alexander Courtis <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working PR please nvim-tree team does not have the bandwidth to implement; a PR will be gratefully appreciated regression Existing functionality broken
Projects
None yet
7 participants