From 25d4f14b9057d99a9da1e6e5165522c734e49996 Mon Sep 17 00:00:00 2001 From: ljie-PI Date: Sat, 19 Oct 2024 14:35:00 +0800 Subject: [PATCH 1/7] Revert "fix(#2862): windows path replaces backslashes with forward slashes (#2903)" This reverts commit 45a93d99794fff3064141d5b3a50db98ce352697. --- lua/nvim-tree/actions/node/open-file.lua | 17 ++++++++--------- lua/nvim-tree/utils.lua | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/lua/nvim-tree/actions/node/open-file.lua b/lua/nvim-tree/actions/node/open-file.lua index 3e5a697a934..25c74451204 100644 --- a/lua/nvim-tree/actions/node/open-file.lua +++ b/lua/nvim-tree/actions/node/open-file.lua @@ -331,9 +331,9 @@ local function open_in_new_window(filename, mode) local fname if M.relative_path then - fname = vim.fn.fnameescape(utils.path_relative(filename, vim.fn.getcwd())) + fname = utils.escape_special_chars(vim.fn.fnameescape(utils.path_relative(filename, vim.fn.getcwd()))) else - fname = vim.fn.fnameescape(filename) + fname = utils.escape_special_chars(vim.fn.fnameescape(filename)) end local command @@ -370,28 +370,27 @@ end ---@param mode string ---@param filename string function M.fn(mode, filename) - local fname = utils.escape_special_chars(filename) if type(mode) ~= "string" then mode = "" end if mode == "tabnew" then - return open_file_in_tab(fname) + return open_file_in_tab(filename) end if mode == "drop" then - return drop(fname) + return drop(filename) end if mode == "tab_drop" then - return tab_drop(fname) + return tab_drop(filename) end if mode == "edit_in_place" then - return edit_in_current_buf(fname) + return edit_in_current_buf(filename) end - local buf_loaded = is_already_loaded(fname) + local buf_loaded = is_already_loaded(filename) local found_win = utils.get_win_buf_from_path(filename) if found_win and (mode == "preview" or mode == "preview_no_picker") then @@ -399,7 +398,7 @@ function M.fn(mode, filename) end if not found_win then - open_in_new_window(fname, mode) + open_in_new_window(filename, mode) else vim.api.nvim_set_current_win(found_win) vim.bo.bufhidden = "" diff --git a/lua/nvim-tree/utils.lua b/lua/nvim-tree/utils.lua index b48e989b483..99436ba7b2b 100644 --- a/lua/nvim-tree/utils.lua +++ b/lua/nvim-tree/utils.lua @@ -279,7 +279,7 @@ function M.escape_special_chars(path) if path == nil then return path end - return M.is_windows and path:gsub("\\", "/") or path + return M.is_windows and path:gsub("%(", "\\("):gsub("%)", "\\)") or path end --- Create empty sub-tables if not present From cbcadc65b4a17ce325cdac5d1f53a3666143d63b Mon Sep 17 00:00:00 2001 From: ljie-PI Date: Sat, 19 Oct 2024 17:18:18 +0800 Subject: [PATCH 2/7] fix the case when '()' and '[]' are both in file path --- lua/nvim-tree/actions/node/open-file.lua | 2 ++ lua/nvim-tree/utils.lua | 33 +++++++++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/lua/nvim-tree/actions/node/open-file.lua b/lua/nvim-tree/actions/node/open-file.lua index 25c74451204..da98eab613a 100644 --- a/lua/nvim-tree/actions/node/open-file.lua +++ b/lua/nvim-tree/actions/node/open-file.lua @@ -329,12 +329,14 @@ local function open_in_new_window(filename, mode) set_current_win_no_autocmd(target_winid, { "BufEnter" }) end + print("filename: " .. filename) local fname if M.relative_path then fname = utils.escape_special_chars(vim.fn.fnameescape(utils.path_relative(filename, vim.fn.getcwd()))) else fname = utils.escape_special_chars(vim.fn.fnameescape(filename)) end + print("fname: " .. fname) local command if create_new_window then diff --git a/lua/nvim-tree/utils.lua b/lua/nvim-tree/utils.lua index 99436ba7b2b..849e3197037 100644 --- a/lua/nvim-tree/utils.lua +++ b/lua/nvim-tree/utils.lua @@ -59,6 +59,17 @@ function M.path_basename(path) return path:sub(i + 1, #path) end +--- Check if there are parentheses before brackets, it causes problems for windows. +--- Refer to issue #2862 and #2961 for more details. +local function has_parentheses_and_brackets(path) + local _, i_parentheses = path:find("(", 1, true) + local _, i_brackets = path:find("[", 1, true) + if i_parentheses and i_brackets then + return true + end + return false +end + --- Get a path relative to another path. ---@param path string ---@param relative_to string|nil @@ -68,13 +79,18 @@ function M.path_relative(path, relative_to) return path end - local _, r = path:find(M.path_add_trailing(relative_to), 1, true) - local p = path + local norm_path = path + if has_parentheses_and_brackets(path) then + norm_path = path:gsub("/", "\\") + end + + local _, r = norm_path:find(M.path_add_trailing(relative_to), 1, true) + local p = norm_path if r then -- take the relative path starting after '/' -- if somehow given a completely matching path, -- returns "" - p = path:sub(r + 1) + p = norm_path:sub(r + 1) end return p end @@ -272,6 +288,14 @@ function M.canonical_path(path) return path end +--- Escapes special characters in string for windows, refer to issue #2862 and #2961 for more details. +local function escape_special_char_for_windows(path) + if has_parentheses_and_brackets(path) then + return path:gsub("\\", "/"):gsub("/ ", "\\ ") + end + return path:gsub("%(", "\\("):gsub("%)", "\\)") +end + --- Escapes special characters in string if windows else returns unmodified string. ---@param path string ---@return string|nil @@ -279,7 +303,8 @@ function M.escape_special_chars(path) if path == nil then return path end - return M.is_windows and path:gsub("%(", "\\("):gsub("%)", "\\)") or path + -- return M.is_windows and path:gsub("%(", "\\("):gsub("%)", "\\)") or path + return M.is_windows and escape_special_char_for_windows(path) or path end --- Create empty sub-tables if not present From 952e0fdbdbbb45f6e4282a9a58efa595aae41178 Mon Sep 17 00:00:00 2001 From: ljie-PI Date: Sat, 19 Oct 2024 17:25:47 +0800 Subject: [PATCH 3/7] remove debug messages --- lua/nvim-tree/actions/node/open-file.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/lua/nvim-tree/actions/node/open-file.lua b/lua/nvim-tree/actions/node/open-file.lua index da98eab613a..25c74451204 100644 --- a/lua/nvim-tree/actions/node/open-file.lua +++ b/lua/nvim-tree/actions/node/open-file.lua @@ -329,14 +329,12 @@ local function open_in_new_window(filename, mode) set_current_win_no_autocmd(target_winid, { "BufEnter" }) end - print("filename: " .. filename) local fname if M.relative_path then fname = utils.escape_special_chars(vim.fn.fnameescape(utils.path_relative(filename, vim.fn.getcwd()))) else fname = utils.escape_special_chars(vim.fn.fnameescape(filename)) end - print("fname: " .. fname) local command if create_new_window then From 9176eabb3b47e20b0a43537506eacf4da8b0628d Mon Sep 17 00:00:00 2001 From: ljie-PI Date: Sat, 19 Oct 2024 17:40:03 +0800 Subject: [PATCH 4/7] remove unnecessary comments --- lua/nvim-tree/utils.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/lua/nvim-tree/utils.lua b/lua/nvim-tree/utils.lua index 849e3197037..fc03c238cac 100644 --- a/lua/nvim-tree/utils.lua +++ b/lua/nvim-tree/utils.lua @@ -303,7 +303,6 @@ function M.escape_special_chars(path) if path == nil then return path end - -- return M.is_windows and path:gsub("%(", "\\("):gsub("%)", "\\)") or path return M.is_windows and escape_special_char_for_windows(path) or path end From 2b110a6d0f1789cfe1ba506c1d3b144b276e822c Mon Sep 17 00:00:00 2001 From: ljie-PI Date: Mon, 21 Oct 2024 15:08:09 +0800 Subject: [PATCH 5/7] add is_windows feature flag when normalizing path --- lua/nvim-tree/utils.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/nvim-tree/utils.lua b/lua/nvim-tree/utils.lua index fc03c238cac..936982ec0a7 100644 --- a/lua/nvim-tree/utils.lua +++ b/lua/nvim-tree/utils.lua @@ -80,7 +80,7 @@ function M.path_relative(path, relative_to) end local norm_path = path - if has_parentheses_and_brackets(path) then + if M.is_windows and has_parentheses_and_brackets(path) then norm_path = path:gsub("/", "\\") end From ada77cb7e9f5a366c2dab36007ff77287d0e02d2 Mon Sep 17 00:00:00 2001 From: ljie-PI Date: Mon, 21 Oct 2024 15:16:57 +0800 Subject: [PATCH 6/7] add is_windows flag for filename change --- lua/nvim-tree/actions/node/open-file.lua | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/lua/nvim-tree/actions/node/open-file.lua b/lua/nvim-tree/actions/node/open-file.lua index 25c74451204..c3b5a1fe9ff 100644 --- a/lua/nvim-tree/actions/node/open-file.lua +++ b/lua/nvim-tree/actions/node/open-file.lua @@ -331,9 +331,9 @@ local function open_in_new_window(filename, mode) local fname if M.relative_path then - fname = utils.escape_special_chars(vim.fn.fnameescape(utils.path_relative(filename, vim.fn.getcwd()))) + fname = vim.fn.fnameescape(utils.path_relative(filename, vim.fn.getcwd())) else - fname = utils.escape_special_chars(vim.fn.fnameescape(filename)) + fname = vim.fn.fnameescape(filename) end local command @@ -370,27 +370,33 @@ end ---@param mode string ---@param filename string function M.fn(mode, filename) + local fname + if utils.is_windows then + fname = filename + else + fname = utils.escape_special_chars(filename) + end if type(mode) ~= "string" then mode = "" end if mode == "tabnew" then - return open_file_in_tab(filename) + return open_file_in_tab(fname) end if mode == "drop" then - return drop(filename) + return drop(fname) end if mode == "tab_drop" then - return tab_drop(filename) + return tab_drop(fname) end if mode == "edit_in_place" then - return edit_in_current_buf(filename) + return edit_in_current_buf(fname) end - local buf_loaded = is_already_loaded(filename) + local buf_loaded = is_already_loaded(fname) local found_win = utils.get_win_buf_from_path(filename) if found_win and (mode == "preview" or mode == "preview_no_picker") then @@ -398,7 +404,7 @@ function M.fn(mode, filename) end if not found_win then - open_in_new_window(filename, mode) + open_in_new_window(fname, mode) else vim.api.nvim_set_current_win(found_win) vim.bo.bufhidden = "" From dd80ce00a68847707b4b82cdb7011640dcf983f4 Mon Sep 17 00:00:00 2001 From: ljie-PI Date: Mon, 21 Oct 2024 15:19:06 +0800 Subject: [PATCH 7/7] Revert "add is_windows flag for filename change" This reverts commit ada77cb7e9f5a366c2dab36007ff77287d0e02d2. --- lua/nvim-tree/actions/node/open-file.lua | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/lua/nvim-tree/actions/node/open-file.lua b/lua/nvim-tree/actions/node/open-file.lua index c3b5a1fe9ff..25c74451204 100644 --- a/lua/nvim-tree/actions/node/open-file.lua +++ b/lua/nvim-tree/actions/node/open-file.lua @@ -331,9 +331,9 @@ local function open_in_new_window(filename, mode) local fname if M.relative_path then - fname = vim.fn.fnameescape(utils.path_relative(filename, vim.fn.getcwd())) + fname = utils.escape_special_chars(vim.fn.fnameescape(utils.path_relative(filename, vim.fn.getcwd()))) else - fname = vim.fn.fnameescape(filename) + fname = utils.escape_special_chars(vim.fn.fnameescape(filename)) end local command @@ -370,33 +370,27 @@ end ---@param mode string ---@param filename string function M.fn(mode, filename) - local fname - if utils.is_windows then - fname = filename - else - fname = utils.escape_special_chars(filename) - end if type(mode) ~= "string" then mode = "" end if mode == "tabnew" then - return open_file_in_tab(fname) + return open_file_in_tab(filename) end if mode == "drop" then - return drop(fname) + return drop(filename) end if mode == "tab_drop" then - return tab_drop(fname) + return tab_drop(filename) end if mode == "edit_in_place" then - return edit_in_current_buf(fname) + return edit_in_current_buf(filename) end - local buf_loaded = is_already_loaded(fname) + local buf_loaded = is_already_loaded(filename) local found_win = utils.get_win_buf_from_path(filename) if found_win and (mode == "preview" or mode == "preview_no_picker") then @@ -404,7 +398,7 @@ function M.fn(mode, filename) end if not found_win then - open_in_new_window(fname, mode) + open_in_new_window(filename, mode) else vim.api.nvim_set_current_win(found_win) vim.bo.bufhidden = ""