Skip to content

Commit

Permalink
feat(fb_actions.trash): add trash action
Browse files Browse the repository at this point in the history
This action attempts to find a common trash executable (currently
"trash" or "gio" in that order) and performs a blocking system call via
vim.fn.system to trash each file or directory selected in the file
browser. Like actions.remove, refuses to trash parent directory or
current working directory.
  • Loading branch information
stelcodes committed Dec 3, 2022
1 parent 8646e46 commit 137aabc
Showing 1 changed file with 88 additions and 0 deletions.
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-put" 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() }
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

0 comments on commit 137aabc

Please sign in to comment.