Skip to content

Commit

Permalink
fix(actions.move): scan_dir folding moving (#358)
Browse files Browse the repository at this point in the history
`plenary.scan_dir`, unlike `fd` doesn't append trailing path separators
to directory paths. This was leading to inconsistent behaviors getting
the basename of directories depending on the usage of scan_dir/fd.

This PR refactors the entry maker to standardizes path strings to NOT
end with path separators regardless of type. This is inline with
`fs_realpath` and more compatible with `vim.fs` functions.
  • Loading branch information
jamestrew committed Feb 9, 2024
1 parent 6dd6522 commit 26b5e86
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 47 deletions.
25 changes: 10 additions & 15 deletions lua/telescope/_extensions/file_browser/actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ fb_actions.rename = function(prompt_bufnr)
fb_utils.notify("action.rename", { msg = "No selection to be renamed!", level = "WARN" })
return
end
local old_path = Path:new(entry[1])
local old_path = entry.Path
-- "../" aka parent_dir more common so test first
if old_path.filename == parent_dir.filename then
fb_utils.notify("action.rename", { msg = "Please select a valid file or folder!", level = "WARN", quiet = quiet })
Expand Down Expand Up @@ -346,27 +346,22 @@ fb_actions.move = function(prompt_bufnr)
local skipped = {}

for idx, selection in ipairs(selections) do
local old_path_absolute = selection:absolute()
if vim.fn.isdirectory(old_path_absolute) == 1 then
old_path_absolute = vim.fs.dirname(old_path_absolute)
end
local basename = vim.fs.basename(old_path_absolute)
local new_path = Path:new { target_dir, basename }
if new_path:exists() then
local src_path_abs = selection:absolute()
local basename = vim.fs.basename(src_path_abs)
local dest_path = Path:new { target_dir, basename }
if dest_path:exists() then
table.insert(skipped, basename)
else
local new_path_absolute = new_path:absolute()
selection:rename {
new_name = new_path_absolute,
}
local dest_path_abs = dest_path:absolute()
selection:rename { new_name = dest_path_abs }
if not selection:is_dir() then
fb_utils.rename_buf(old_path_absolute, new_path_absolute)
fb_utils.rename_buf(src_path_abs, dest_path_abs)
else
fb_utils.rename_dir_buf(old_path_absolute, new_path_absolute)
fb_utils.rename_dir_buf(src_path_abs, dest_path_abs)
end
table.insert(moved, basename)
if idx == 1 and #selections == 1 then
fb_utils.selection_callback(current_picker, new_path_absolute)
fb_utils.selection_callback(current_picker, dest_path_abs)
end
end
end
Expand Down
61 changes: 30 additions & 31 deletions lua/telescope/_extensions/file_browser/make_entry.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,24 @@ local stat_enum = {
mode = fs_stat.mode,
}

---@return integer
local get_fb_prompt = function()
local prompt_bufnr = vim.tbl_filter(function(b)
local prompt_bufnr

local prompt_bufnrs = vim.tbl_filter(function(b)
return vim.bo[b].filetype == "TelescopePrompt"
end, vim.api.nvim_list_bufs())
-- vim.ui.{input, select} might be telescope pickers
if #prompt_bufnr > 1 then
for _, buf in ipairs(prompt_bufnr) do
local current_picker = action_state.get_current_picker(prompt_bufnr)
if #prompt_bufnrs > 1 then
for _, buf in ipairs(prompt_bufnrs) do
local current_picker = action_state.get_current_picker(buf)
if current_picker.finder._browse_files then
prompt_bufnr = buf
break
end
end
else
prompt_bufnr = prompt_bufnr[1]
prompt_bufnr = prompt_bufnrs[1]
end
return prompt_bufnr
end
Expand Down Expand Up @@ -82,6 +85,7 @@ end
-- entry
-- - value: absolute path of entry
-- - display: made relative to current folder
-- - ordial: path excl. cwd
-- - display: made relative to current folder
-- - Path: cache plenary.Path object of entry
-- - stat: lazily cached vim.loop.fs_stat of entry
Expand Down Expand Up @@ -123,34 +127,31 @@ local make_entry = function(opts)
local widths = {}
local display_array = {}
local icon, icon_hl
local is_dir = entry.Path:is_dir()
-- entry.ordinal is path excl. cwd

local tail = fb_utils.trim_right_os_sep(entry.ordinal)
-- path_display plays better with relative paths
local path_display = utils.transform_path(opts, tail)
if is_dir then
if entry.value == parent_dir then
path_display = string.format("..%s", os_sep)
else
if path_display:sub(-1, -1) ~= os_sep then
path_display = string.format("%s%s", path_display, os_sep)
end

if entry.is_dir then
if entry.path == parent_dir then
path_display = ".."
end
path_display = path_display .. os_sep
end

if not opts.disable_devicons then
if is_dir then
if entry.is_dir then
icon = opts.dir_icon or ""
icon_hl = opts.dir_icon_hl or "Default"
else
icon, icon_hl = utils.get_devicons(entry.value, opts.disable_devicons)
icon, icon_hl = utils.get_devicons(entry.path, opts.disable_devicons)
icon = icon ~= "" and icon or " "
end
table.insert(widths, { width = strings.strdisplaywidth(icon) })
table.insert(display_array, { icon, icon_hl })
end

if opts.git_status then
if entry.value == parent_dir then
if entry.path == parent_dir then
table.insert(widths, { width = 2 })
table.insert(display_array, " ")
else
Expand All @@ -164,8 +165,8 @@ local make_entry = function(opts)
if #path_display > file_width then
path_display = strings.truncate(path_display, file_width, nil, -1)
end
path_display = is_dir and { path_display, "TelescopePreviewDirectory" } or path_display
table.insert(display_array, entry.stat and path_display or { path_display, "WarningMsg" })
local display = entry.is_dir and { path_display, "TelescopePreviewDirectory" } or path_display
table.insert(display_array, entry.stat and display or { display, "WarningMsg" })
table.insert(widths, { width = file_width })

-- stat may be false meaning file not found / unavailable, e.g. broken symlink
Expand Down Expand Up @@ -199,7 +200,7 @@ local make_entry = function(opts)

if k == "git_status" then
local git_status
if t.Path:is_dir() then
if t.is_dir then
if opts.git_file_status and not vim.tbl_isempty(opts.git_file_status) then
for key, value in pairs(opts.git_file_status) do
if key:sub(1, #t.value) == t.value then
Expand All @@ -214,15 +215,6 @@ local make_entry = function(opts)
return fb_git.make_display(opts, git_status)
end

if k == "Path" then
t.Path = Path:new(t.value)
return t.Path
end

if k == "path" then
return t.value
end

if k == "stat" then
t.stat = vim.F.if_nil(vim.loop.fs_stat(t.value), false)
if not t.stat then
Expand All @@ -242,14 +234,21 @@ local make_entry = function(opts)
return t.lstat
end

return rawget(t, rawget({ value = 1 }, k))
return rawget(t, rawget({ value = "path" }, k))
end

return function(absolute_path)
absolute_path = fb_utils.trim_right_os_sep(absolute_path)
local path = Path:new(absolute_path)
local is_dir = path:is_dir()

local e = setmetatable({
absolute_path,
ordinal = (absolute_path == opts.cwd and ".")
or (absolute_path == parent_dir and ".." or absolute_path:sub(cwd_substr, -1)),
Path = path,
path = absolute_path,
is_dir = is_dir,
}, mt)

-- telescope-file-browser has to cache the entries to resolve multi-selections
Expand Down
2 changes: 1 addition & 1 deletion lua/telescope/_extensions/file_browser/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fb_utils.get_selected_files = function(prompt_bufnr, smart)
table.insert(selected, action_state.get_selected_entry())
else
for _, selection in ipairs(selections) do
table.insert(selected, Path:new(selection[1]))
table.insert(selected, selection.Path)
end
end
selected = vim.tbl_map(function(entry)
Expand Down

0 comments on commit 26b5e86

Please sign in to comment.