diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 3e8c04b7..c4cdbcf7 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -242,6 +242,9 @@ local function setup_autocommands(opts) pattern = "*", ---@param ev vim.api.keyset.create_autocmd.callback_args callback = function(ev) + if not vim.api.nvim_buf_is_valid(ev.buf) then + return + end if vim.api.nvim_get_option_value("filetype", { buf = ev.buf }) == "NvimTree" then require("nvim-tree.events")._dispatch_on_tree_close() end diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 447c75b8..819660e5 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -135,7 +135,7 @@ end function Builder:format_line(indent_markers, arrows, icon, name, node) local added_len = 0 local function add_to_end(t1, t2) - if not t2 then + if not t2 or vim.tbl_isempty(t2) then return end for _, v in ipairs(t2) do diff --git a/lua/nvim-tree/utils.lua b/lua/nvim-tree/utils.lua index 0eff04f4..9396ba9d 100644 --- a/lua/nvim-tree/utils.lua +++ b/lua/nvim-tree/utils.lua @@ -303,11 +303,51 @@ function M.rename_loaded_buffers(old_path, new_path) end end +local is_windows_drive = function(path) + return (M.is_windows) and (path:match("^%a:\\$") ~= nil) +end + ---@param path string path to file or directory ---@return boolean function M.file_exists(path) - local _, error = vim.loop.fs_stat(path) - return error == nil + if not (M.is_windows or M.is_wsl) then + local _, error = vim.loop.fs_stat(path) + return error == nil + end + + -- Windows is case-insensetive, but case-preserving + -- If a file's name is being changed into itself + -- with different casing, windows will falsely + -- report that file is already existing, so a hand-rolled + -- implementation of checking for existance is needed. + -- Same holds for WSL, since it can sometimes + -- access Windows files directly. + -- For more details see (#3117). + + if is_windows_drive(path) then + return vim.fn.isdirectory(path) == 1 + end + + local parent = vim.fn.fnamemodify(path, ":h") + local filename = vim.fn.fnamemodify(path, ":t") + + local handle = vim.loop.fs_scandir(parent) + if not handle then + -- File can not exist if its parent directory does not exist + return false + end + + while true do + local name, _ = vim.loop.fs_scandir_next(handle) + if not name then + break + end + if name == filename then + return true + end + end + + return false end ---@param path string