From 496d60fcff7af652e67c217aa82ab8d219a3f54e Mon Sep 17 00:00:00 2001 From: Steven Arcangeli Date: Sat, 6 May 2023 21:07:01 -0700 Subject: [PATCH] feat: config option for trashing deleted files (#99) --- lua/oil/adapters/files.lua | 7 +++++- lua/oil/adapters/files/trash.lua | 37 ++++++++++++++++++++++++++++++++ lua/oil/config.lua | 10 +++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 lua/oil/adapters/files/trash.lua diff --git a/lua/oil/adapters/files.lua b/lua/oil/adapters/files.lua index 5f0c24c..d483852 100644 --- a/lua/oil/adapters/files.lua +++ b/lua/oil/adapters/files.lua @@ -3,6 +3,7 @@ local columns = require("oil.columns") local config = require("oil.config") local fs = require("oil.fs") local permissions = require("oil.adapters.files.permissions") +local trash = require("oil.adapters.files.trash") local util = require("oil.util") local FIELD = require("oil.constants").FIELD local M = {} @@ -384,7 +385,11 @@ M.perform_action = function(action, cb) elseif action.type == "delete" then local _, path = util.parse_url(action.url) path = fs.posix_to_os_path(path) - fs.recursive_delete(action.entry_type, path, cb) + if config.delete_to_trash then + trash.recursive_delete(path, cb) + else + fs.recursive_delete(action.entry_type, path, cb) + end elseif action.type == "move" then local dest_adapter = config.get_adapter_by_scheme(action.dest_url) if dest_adapter == M then diff --git a/lua/oil/adapters/files/trash.lua b/lua/oil/adapters/files/trash.lua new file mode 100644 index 0000000..6051832 --- /dev/null +++ b/lua/oil/adapters/files/trash.lua @@ -0,0 +1,37 @@ +local M = {} + +M.recursive_delete = function(path, cb) + local stdout = {} + local stderr = {} + local jid = vim.fn.jobstart({ "trash-put", path }, { + stdout_buffered = true, + stderr_buffered = true, + on_stdout = function(j, output) + stdout = output + end, + on_stderr = function(j, output) + stderr = output + end, + on_exit = function(j, exit_code) + if exit_code == 0 then + cb() + else + cb( + string.format( + "Error moving '%s' to trash:\n stdout: %s\n stderr: %s", + path, + table.concat(stdout, "\n "), + table.concat(stderr, "\n ") + ) + ) + end + end, + }) + if jid == 0 then + cb(string.format("Passed invalid argument '%s' to 'trash-put'", path)) + elseif jid == -1 then + cb("'trash-put' is not executable") + end +end + +return M diff --git a/lua/oil/config.lua b/lua/oil/config.lua index 4875a97..b54d3bc 100644 --- a/lua/oil/config.lua +++ b/lua/oil/config.lua @@ -28,6 +28,8 @@ local default_config = { restore_win_options = true, -- Skip the confirmation popup for simple operations skip_confirm_for_simple_edits = false, + -- Deleted files will be removed with the `trash-put` command. + delete_to_trash = false, -- Keymaps in oil buffer. Can be any value that `vim.keymap.set` accepts OR a table of keymap -- options with a `callback` (e.g. { callback = function() ... end, desc = "", nowait = true }) -- Additionally, if it is a string that matches "actions.", @@ -130,6 +132,14 @@ M.setup = function(opts) new_conf.keymaps = opts.keymaps or {} end + if new_conf.delete_to_trash and vim.fn.executable("trash-put") == 0 then + vim.notify( + "oil.nvim: delete_to_trash is true, but trash-put executable not found.\nDeleted files will be permanently removed.", + vim.log.levels.WARN + ) + new_conf.delete_to_trash = false + end + for k, v in pairs(new_conf) do M[k] = v end