Skip to content
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

feat(fb_actions.trash): add trash action #196

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions lua/telescope/_extensions/file_browser/actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,94 @@ fb_actions.remove = function(prompt_bufnr)
end)
end

--- Trash file or folders via a pre-installed trash utility for |telescope-file-browser.picker.file_browser|.<br>
--- Note: Attempts to find "trash" or "gio" executable and performs a blocking system command.
---@param prompt_bufnr number: The prompt bufnr
fb_actions.trash = function(prompt_bufnr)
local current_picker = action_state.get_current_picker(prompt_bufnr)
local finder = current_picker.finder
local quiet = current_picker.finder.quiet
local trash_cmd = nil
if vim.fn.executable "trash" == 1 then
trash_cmd = "trash"
elseif vim.fn.executable "gio" == 1 then
trash_cmd = "gio"
end
if not trash_cmd then
fb_utils.notify("actions.trash", { msg = "Cannot locate a valid trash executable!", level = "WARN", quiet = quiet })
return
end
local selections = fb_utils.get_selected_files(prompt_bufnr, true)
if vim.tbl_isempty(selections) then
fb_utils.notify("actions.trash", { msg = "No selection to be trashed!", level = "WARN", quiet = quiet })
return
end

local files = vim.tbl_map(function(sel)
return sel.filename:sub(#sel:parent().filename + 2)
end, selections)

for _, sel in ipairs(selections) do
if sel:is_dir() then
local abs = sel:absolute()
local msg
if finder.files and Path:new(finder.path):parent():absolute() == abs then
msg = "Parent folder cannot be trashed!"
end
if not finder.files and Path:new(finder.cwd):absolute() == abs then
msg = "Current folder cannot be trashed!"
end
if msg then
fb_utils.notify("actions.trash", { msg = msg .. " Prematurely aborting.", level = "WARN", quiet = quiet })
return
end
end
end

local trashed = {}

local message = "Selections to be trashed: " .. table.concat(files, ", ")
fb_utils.notify("actions.trash", { msg = message, level = "INFO", quiet = quiet })
-- TODO fix default vim.ui.input and nvim-notify 'selections to be deleted' message
vim.ui.input({ prompt = "Trash selections [y/N]: " }, function(input)
vim.cmd [[ redraw ]] -- redraw to clear out vim.ui.prompt to avoid hit-enter prompt
if input and input:lower() == "y" then
for _, p in ipairs(selections) do
local is_dir = p:is_dir()
local cmd = nil
if trash_cmd == "gio" then
cmd = { "gio", "trash", "--", p:absolute() }
else
cmd = { trash_cmd, "--", p:absolute() }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trash from trash-cli does not accept --, so this makes the command always "fail" (although it does still trash the file).

Copy link
Contributor Author

@stelcodes stelcodes Oct 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was a regression now fixed in the most recent version: andreafrancia/trash-cli#303 (comment)

Regardless I believe the -- is unnecessary since we are using absolute paths. Looking back I also think putting all the filenames into a single command would be much faster.

end
vim.fn.system(cmd)
if vim.v.shell_error == 0 then
table.insert(trashed, p.filename:sub(#p:parent().filename + 2))
-- clean up opened buffers
if not is_dir then
fb_utils.delete_buf(p:absolute())
else
fb_utils.delete_dir_buf(p:absolute())
end
else
local msg = "Command failed: " .. table.concat(cmd, " ")
fb_utils.notify("actions.trash", { msg = msg, level = "WARN", quiet = quiet })
end
end
local msg = nil
if next(trashed) then
msg = "Trashed: " .. table.concat(trashed, ", ")
else
msg = "No selections were successfully trashed"
end
fb_utils.notify("actions.trash", { msg = msg, level = "INFO", quiet = quiet })
current_picker:refresh(current_picker.finder)
else
fb_utils.notify("actions.trash", { msg = "Trashing selections aborted!", level = "INFO", quiet = quiet })
end
end)
end

--- Toggle hidden files or folders for |telescope-file-browser.picker.file_browser|.
---@param prompt_bufnr number: The prompt bufnr
fb_actions.toggle_hidden = function(prompt_bufnr)
Expand Down