feat: trash support for linux and mac (#165)

* wip: skeleton code for trash adapter

* refactor: split trash implementation for mac and linux

* fix: ensure we create the .Trash/$uid dir

* feat: code complete linux trash implementation

* doc: write up trash features

* feat: code complete mac trash implementation

* cleanup: remove previous, terrible, undocumented trash feature

* fix: always disabled trash

* feat: show original path of trashed files

* doc: add a note about calling actions directly

* fix: bugs in trash implementation

* fix: schedule_wrap in mac trash

* doc: fix typo and line wrapping

* fix: parsing of arguments to :Oil command

* doc: small documentation tweaks

* doc: fix awkward wording in the toggle_trash action

* fix: warning on Windows when delete_to_trash = true

* feat: :Oil --trash can open specific trash directories

* fix: show all trash files in device root

* fix: trash mtime should be sortable

* fix: shorten_path handles optional trailing slash

* refactor: overhaul the UI

* fix: keep trash original path vtext from stacking

* refactor: replace disable_changes with an error filter

* fix: shorten path names in home directory relative to root

* doc: small README format changes

* cleanup: remove unnecessary preserve_undo logic

* test: add a functional test for the freedesktop trash adapter

* test: more functional tests for trash

* fix: schedule a callback to avoid main loop error

* refactor: clean up mutator logic

* doc: some comments and type annotations
This commit is contained in:
Steven Arcangeli 2023-11-05 12:40:58 -08:00 committed by GitHub
parent d8f0d91b10
commit 6175bd6462
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 1580 additions and 229 deletions

View file

@ -1,3 +1,5 @@
local uv = vim.uv or vim.loop
local default_config = {
-- Oil will take over directory buffers (e.g. `vim .` or `:e src/`)
-- Set to false if you still want to use netrw.
@ -30,8 +32,6 @@ local default_config = {
delete_to_trash = false,
-- Skip the confirmation popup for simple operations
skip_confirm_for_simple_edits = false,
-- Change this to customize the command used when deleting to trash
trash_command = "trash-put",
-- Selecting a new/moved/renamed file or directory will prompt you to save changes first
prompt_save_on_select_new_entry = true,
-- Oil will automatically delete hidden buffers after this delay
@ -60,6 +60,7 @@ local default_config = {
["gs"] = "actions.change_sort",
["gx"] = "actions.open_external",
["g."] = "actions.toggle_hidden",
["g\\"] = "actions.toggle_trash",
},
-- Set to false to disable all of the above keymaps
use_default_keymaps = true,
@ -142,6 +143,7 @@ local default_config = {
default_config.adapters = {
["oil://"] = "files",
["oil-ssh://"] = "ssh",
["oil-trash://"] = "trash",
}
default_config.adapter_aliases = {}
@ -154,13 +156,10 @@ M.setup = function(opts)
end
if new_conf.delete_to_trash then
local trash_bin = vim.split(new_conf.trash_command, " ")[1]
if vim.fn.executable(trash_bin) == 0 then
local is_windows = uv.os_uname().version:match("Windows")
if is_windows then
vim.notify(
string.format(
"oil.nvim: delete_to_trash is true, but '%s' executable not found.\nDeleted files will be permanently removed.",
new_conf.trash_command
),
"oil.nvim: delete_to_trash is true, but trash is not yet supported on Windows.\nDeleted files will be permanently removed",
vim.log.levels.WARN
)
new_conf.delete_to_trash = false
@ -176,46 +175,6 @@ M.setup = function(opts)
M.adapter_to_scheme[v] = k
end
M._adapter_by_scheme = {}
if type(M.trash) == "string" then
M.trash = vim.fn.fnamemodify(vim.fn.expand(M.trash), ":p")
end
end
---@return nil|string
M.get_trash_url = function()
if not M.trash then
return nil
end
local fs = require("oil.fs")
if M.trash == true then
local data_home = os.getenv("XDG_DATA_HOME") or vim.fn.expand("~/.local/share")
local preferred = fs.join(data_home, "trash")
local candidates = {
preferred,
}
if fs.is_windows then
-- TODO permission issues when using the recycle bin. The folder gets created without
-- read/write perms, so all operations fail
-- local cwd = vim.fn.getcwd()
-- table.insert(candidates, 1, cwd:sub(1, 3) .. "$Recycle.Bin")
-- table.insert(candidates, 1, "C:\\$Recycle.Bin")
else
table.insert(candidates, fs.join(data_home, "Trash", "files"))
table.insert(candidates, fs.join(os.getenv("HOME"), ".Trash"))
end
local trash_dir = preferred
for _, candidate in ipairs(candidates) do
if vim.fn.isdirectory(candidate) == 1 then
trash_dir = candidate
break
end
end
local oil_trash_dir = vim.fn.fnamemodify(fs.join(trash_dir, "nvim", "oil"), ":p")
fs.mkdirp(oil_trash_dir)
M.trash = oil_trash_dir
end
return M.adapter_to_scheme.files .. fs.os_to_posix_path(M.trash)
end
---@param scheme nil|string