From fe2d3ad59ff7df621c5142061dcfd6484f27130e Mon Sep 17 00:00:00 2001 From: mxple Date: Sun, 22 Sep 2024 02:40:15 -0400 Subject: [PATCH 1/4] Revert "revert(#2794): sshfs compatibility (#2920)" This reverts commit 8405ecfbd6bb08a94ffc9c68fef211eea56e8a3b. Fix for symlinks is simple --- lua/nvim-tree/actions/fs/remove-file.lua | 9 +++++++-- lua/nvim-tree/explorer/init.lua | 13 ++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/lua/nvim-tree/actions/fs/remove-file.lua b/lua/nvim-tree/actions/fs/remove-file.lua index d9b0357c55c..14a30d3aa7e 100644 --- a/lua/nvim-tree/actions/fs/remove-file.lua +++ b/lua/nvim-tree/actions/fs/remove-file.lua @@ -57,13 +57,18 @@ local function remove_dir(cwd) end while true do - local name, t = vim.loop.fs_scandir_next(handle) + local name, _ = vim.loop.fs_scandir_next(handle) if not name then break end local new_cwd = utils.path_join { cwd, name } - if t == "directory" then + + -- Type must come from fs_stat and not fs_scandir_next to maintain sshfs compatibility + local stat = vim.loop.fs_stat(new_cwd) + local type = stat and stat.type or nil + + if type == "directory" then local success = remove_dir(new_cwd) if not success then return false diff --git a/lua/nvim-tree/explorer/init.lua b/lua/nvim-tree/explorer/init.lua index eb899f78b5e..0d44217b11e 100644 --- a/lua/nvim-tree/explorer/init.lua +++ b/lua/nvim-tree/explorer/init.lua @@ -125,7 +125,7 @@ function Explorer:reload(node, git_status) }) while true do - local name, t = vim.loop.fs_scandir_next(handle) + local name, _ = vim.loop.fs_scandir_next(handle) if not name then break end @@ -138,11 +138,14 @@ function Explorer:reload(node, git_status) if filter_reason == FILTER_REASON.none then remain_childs[abs] = true + -- Type must come from fs_stat and not fs_scandir_next to maintain sshfs compatibility + local type = stat and stat.type or nil + -- Recreate node if type changes. if nodes_by_path[abs] then local n = nodes_by_path[abs] - if n.type ~= t then + if n.type ~= type then utils.array_remove(node.nodes, n) explorer_node.node_destroy(n) nodes_by_path[abs] = nil @@ -151,11 +154,11 @@ function Explorer:reload(node, git_status) if not nodes_by_path[abs] then local new_child = nil - if t == "directory" and vim.loop.fs_access(abs, "R") and Watcher.is_fs_event_capable(abs) then + if type == "directory" and vim.loop.fs_access(abs, "R") and Watcher.is_fs_event_capable(abs) then new_child = builders.folder(node, abs, name, stat) - elseif t == "file" then + elseif type == "file" then new_child = builders.file(node, abs, name, stat) - elseif t == "link" then + elseif type == "link" then local link = builders.link(node, abs, name, stat) if link.link_to ~= nil then new_child = link From ff1296baa0dcd8612f3970da73578082af4d6ad3 Mon Sep 17 00:00:00 2001 From: mxple Date: Sun, 22 Sep 2024 02:53:45 -0400 Subject: [PATCH 2/4] fix sshfs compatibility with symlinks --- lua/nvim-tree/explorer/init.lua | 56 +++++++++++++++++---------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/lua/nvim-tree/explorer/init.lua b/lua/nvim-tree/explorer/init.lua index 0d44217b11e..fd00e3c7d6b 100644 --- a/lua/nvim-tree/explorer/init.lua +++ b/lua/nvim-tree/explorer/init.lua @@ -132,7 +132,7 @@ function Explorer:reload(node, git_status) local abs = utils.path_join { cwd, name } ---@type uv.fs_stat.result|nil - local stat = vim.loop.fs_stat(abs) + local stat = vim.loop.fs_lstat(abs) local filter_reason = self.filters:should_filter_as_reason(abs, stat, filter_status) if filter_reason == FILTER_REASON.none then @@ -241,17 +241,17 @@ function Explorer:refresh_parent_nodes_for_path(path) -- collect parent nodes from the top down local parent_nodes = {} NodeIterator.builder({ self }) - :recursor(function(node) - return node.nodes - end) - :applier(function(node) - local abs_contains = node.absolute_path and path:find(node.absolute_path, 1, true) == 1 - local link_contains = node.link_to and path:find(node.link_to, 1, true) == 1 - if abs_contains or link_contains then - table.insert(parent_nodes, node) - end - end) - :iterate() + :recursor(function(node) + return node.nodes + end) + :applier(function(node) + local abs_contains = node.absolute_path and path:find(node.absolute_path, 1, true) == 1 + local link_contains = node.link_to and path:find(node.link_to, 1, true) == 1 + if abs_contains or link_contains then + table.insert(parent_nodes, node) + end + end) + :iterate() -- refresh in order; this will expand groups as needed for _, node in ipairs(parent_nodes) do @@ -354,7 +354,7 @@ function Explorer:populate_children(handle, cwd, node, git_status, parent) }) while true do - local name, t = vim.loop.fs_scandir_next(handle) + local name, _ = vim.loop.fs_scandir_next(handle) if not name then break end @@ -365,15 +365,17 @@ function Explorer:populate_children(handle, cwd, node, git_status, parent) local profile = log.profile_start("populate_children %s", abs) ---@type uv.fs_stat.result|nil - local stat = vim.loop.fs_stat(abs) + local stat = vim.loop.fs_lstat(abs) local filter_reason = parent.filters:should_filter_as_reason(abs, stat, filter_status) if filter_reason == FILTER_REASON.none and not nodes_by_path[abs] then + -- Type must come from fs_stat and not fs_scandir_next to maintain sshfs compatibility + local type = stat and stat.type or nil local child = nil - if t == "directory" and vim.loop.fs_access(abs, "R") then + if type == "directory" and vim.loop.fs_access(abs, "R") then child = builders.folder(node, abs, name, stat) - elseif t == "file" then + elseif type == "file" then child = builders.file(node, abs, name, stat) - elseif t == "link" then + elseif type == "link" then local link = builders.link(node, abs, name, stat) if link.link_to ~= nil then child = link @@ -437,16 +439,16 @@ end ---@param projects table function Explorer:refresh_nodes(projects) Iterator.builder({ self }) - :applier(function(n) - if n.nodes then - local toplevel = git.get_toplevel(n.cwd or n.link_to or n.absolute_path) - self:reload(n, projects[toplevel] or {}) - end - end) - :recursor(function(n) - return n.group_next and { n.group_next } or (n.open and n.nodes) - end) - :iterate() + :applier(function(n) + if n.nodes then + local toplevel = git.get_toplevel(n.cwd or n.link_to or n.absolute_path) + self:reload(n, projects[toplevel] or {}) + end + end) + :recursor(function(n) + return n.group_next and { n.group_next } or (n.open and n.nodes) + end) + :iterate() end local event_running = false From 60ded549ac8ed3f2399a6e83942882c588abaa95 Mon Sep 17 00:00:00 2001 From: mxple Date: Sun, 22 Sep 2024 22:24:03 -0400 Subject: [PATCH 3/4] add suggestions --- lua/nvim-tree/explorer/init.lua | 50 ++++++++++++++++----------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/lua/nvim-tree/explorer/init.lua b/lua/nvim-tree/explorer/init.lua index fd00e3c7d6b..7463b65f434 100644 --- a/lua/nvim-tree/explorer/init.lua +++ b/lua/nvim-tree/explorer/init.lua @@ -241,17 +241,17 @@ function Explorer:refresh_parent_nodes_for_path(path) -- collect parent nodes from the top down local parent_nodes = {} NodeIterator.builder({ self }) - :recursor(function(node) - return node.nodes - end) - :applier(function(node) - local abs_contains = node.absolute_path and path:find(node.absolute_path, 1, true) == 1 - local link_contains = node.link_to and path:find(node.link_to, 1, true) == 1 - if abs_contains or link_contains then - table.insert(parent_nodes, node) - end - end) - :iterate() + :recursor(function(node) + return node.nodes + end) + :applier(function(node) + local abs_contains = node.absolute_path and path:find(node.absolute_path, 1, true) == 1 + local link_contains = node.link_to and path:find(node.link_to, 1, true) == 1 + if abs_contains or link_contains then + table.insert(parent_nodes, node) + end + end) + :iterate() -- refresh in order; this will expand groups as needed for _, node in ipairs(parent_nodes) do @@ -369,13 +369,13 @@ function Explorer:populate_children(handle, cwd, node, git_status, parent) local filter_reason = parent.filters:should_filter_as_reason(abs, stat, filter_status) if filter_reason == FILTER_REASON.none and not nodes_by_path[abs] then -- Type must come from fs_stat and not fs_scandir_next to maintain sshfs compatibility - local type = stat and stat.type or nil + local t = stat and stat.type or nil local child = nil - if type == "directory" and vim.loop.fs_access(abs, "R") then + if t == "directory" and vim.loop.fs_access(abs, "R") then child = builders.folder(node, abs, name, stat) - elseif type == "file" then + elseif t == "file" then child = builders.file(node, abs, name, stat) - elseif type == "link" then + elseif t == "link" then local link = builders.link(node, abs, name, stat) if link.link_to ~= nil then child = link @@ -439,16 +439,16 @@ end ---@param projects table function Explorer:refresh_nodes(projects) Iterator.builder({ self }) - :applier(function(n) - if n.nodes then - local toplevel = git.get_toplevel(n.cwd or n.link_to or n.absolute_path) - self:reload(n, projects[toplevel] or {}) - end - end) - :recursor(function(n) - return n.group_next and { n.group_next } or (n.open and n.nodes) - end) - :iterate() + :applier(function(n) + if n.nodes then + local toplevel = git.get_toplevel(n.cwd or n.link_to or n.absolute_path) + self:reload(n, projects[toplevel] or {}) + end + end) + :recursor(function(n) + return n.group_next and { n.group_next } or (n.open and n.nodes) + end) + :iterate() end local event_running = false From bfac4e398dbb4c5a14025c89ef99f418c7c8e6c1 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 29 Sep 2024 09:15:11 +1000 Subject: [PATCH 4/4] revert variable name change to ease multi-instance feature branch conflicts --- lua/nvim-tree/explorer/init.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lua/nvim-tree/explorer/init.lua b/lua/nvim-tree/explorer/init.lua index 7463b65f434..a180bb707ec 100644 --- a/lua/nvim-tree/explorer/init.lua +++ b/lua/nvim-tree/explorer/init.lua @@ -139,13 +139,13 @@ function Explorer:reload(node, git_status) remain_childs[abs] = true -- Type must come from fs_stat and not fs_scandir_next to maintain sshfs compatibility - local type = stat and stat.type or nil + local t = stat and stat.type or nil -- Recreate node if type changes. if nodes_by_path[abs] then local n = nodes_by_path[abs] - if n.type ~= type then + if n.type ~= t then utils.array_remove(node.nodes, n) explorer_node.node_destroy(n) nodes_by_path[abs] = nil @@ -154,11 +154,11 @@ function Explorer:reload(node, git_status) if not nodes_by_path[abs] then local new_child = nil - if type == "directory" and vim.loop.fs_access(abs, "R") and Watcher.is_fs_event_capable(abs) then + if t == "directory" and vim.loop.fs_access(abs, "R") and Watcher.is_fs_event_capable(abs) then new_child = builders.folder(node, abs, name, stat) - elseif type == "file" then + elseif t == "file" then new_child = builders.file(node, abs, name, stat) - elseif type == "link" then + elseif t == "link" then local link = builders.link(node, abs, name, stat) if link.link_to ~= nil then new_child = link