summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFederico Stra <stra.federico@gmail.com>2021-06-27 15:30:35 +0200
committerFederico Stra <stra.federico@gmail.com>2021-06-27 15:41:39 +0200
commit00fae90e0dffc468c75bd362fa4220bc8650fb86 (patch)
treec84e4bdcd578f435ccc820d543e0546a2cae04a5
parent5534cd7126eada8a040f00cd996295dfd42cb4c1 (diff)
Implement Ctrl+t move to trash
-rw-r--r--Cargo.lock199
-rw-r--r--Cargo.toml1
-rw-r--r--src/interactive/app/handlers.rs59
-rw-r--r--src/interactive/widgets/help.rs5
-rw-r--r--src/interactive/widgets/mark.rs9
5 files changed, 273 insertions, 0 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 96ed3e1..1fec4eb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
+version = 3
+
[[package]]
name = "ansi_term"
version = "0.12.1"
@@ -60,6 +62,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
+name = "chrono"
+version = "0.4.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
+dependencies = [
+ "libc",
+ "num-integer",
+ "num-traits",
+ "time",
+ "winapi",
+]
+
+[[package]]
name = "clap"
version = "3.0.0-beta.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -103,6 +118,12 @@ dependencies = [
]
[[package]]
+name = "const-sha1"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb58b6451e8c2a812ad979ed1d83378caa5e927eef2622017a45f251457c2c9d"
+
+[[package]]
name = "core-foundation-sys"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -253,6 +274,7 @@ dependencies = [
"petgraph",
"pretty_assertions",
"sysinfo",
+ "trash",
"tui",
"tui-react",
"unicode-segmentation",
@@ -281,6 +303,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
[[package]]
+name = "form_urlencoded"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
+dependencies = [
+ "matches",
+ "percent-encoding",
+]
+
+[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -311,6 +343,17 @@ dependencies = [
]
[[package]]
+name = "idna"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
+dependencies = [
+ "matches",
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
name = "indexmap"
version = "1.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -379,6 +422,21 @@ dependencies = [
]
[[package]]
+name = "malloc_buf"
+version = "0.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "matches"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
+
+[[package]]
name = "memoffset"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -419,6 +477,25 @@ dependencies = [
]
[[package]]
+name = "num-integer"
+version = "0.1.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
name = "num_cpus"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -435,6 +512,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
[[package]]
+name = "objc"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
+dependencies = [
+ "malloc_buf",
+]
+
+[[package]]
name = "once_cell"
version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -491,6 +577,12 @@ dependencies = [
]
[[package]]
+name = "percent-encoding"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
+
+[[package]]
name = "petgraph"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -692,6 +784,47 @@ dependencies = [
]
[[package]]
+name = "time"
+version = "0.1.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
+dependencies = [
+ "libc",
+ "wasi",
+ "winapi",
+]
+
+[[package]]
+name = "tinyvec"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
+
+[[package]]
+name = "trash"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea78c1e8e861fed535e67f56601a59879f3b2d639aed32e98589d5a2d8378fbd"
+dependencies = [
+ "chrono",
+ "libc",
+ "log",
+ "objc",
+ "scopeguard",
+ "url",
+ "windows",
+]
+
+[[package]]
name = "tui"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -718,6 +851,24 @@ dependencies = [
]
[[package]]
+name = "unicode-bidi"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0"
+dependencies = [
+ "matches",
+]
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
name = "unicode-segmentation"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -736,6 +887,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
+name = "url"
+version = "2.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "matches",
+ "percent-encoding",
+]
+
+[[package]]
name = "utf8-width"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -754,6 +917,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
+name = "wasi"
+version = "0.10.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
+
+[[package]]
name = "which"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -802,3 +971,33 @@ name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e50fd72a86bac7e21de2ce132629b7921e57b75ed607025f850a97a7ce2aec3"
+dependencies = [
+ "const-sha1",
+ "windows_gen",
+ "windows_macros",
+]
+
+[[package]]
+name = "windows_gen"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b41030a241566acc784e1883355aebf4fb87bae609682a613ce62bf7639d5ec5"
+dependencies = [
+ "syn",
+]
+
+[[package]]
+name = "windows_macros"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25eb153f12764a88cd8f6898ba9b4b03b57704b26289a15c66495923d23e4208"
+dependencies = [
+ "syn",
+ "windows_gen",
+]
diff --git a/Cargo.toml b/Cargo.toml
index 18d7218..0b9e6de 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,6 +27,7 @@ num_cpus = "1.10.0"
filesize = "0.2.0"
anyhow = "1.0.31"
colored = "2.0.0"
+trash = "2.0.1"
# 'tui' related
unicode-segmentation = { version = "1.3.0", optional = true }
diff --git a/src/interactive/app/handlers.rs b/src/interactive/app/handlers.rs
index 2360aae..c15c764 100644
--- a/src/interactive/app/handlers.rs
+++ b/src/interactive/app/handlers.rs
@@ -9,6 +9,7 @@ use dua::traverse::{Traversal, TreeIndex};
use itertools::Itertools;
use petgraph::{visit::Bfs, Direction};
use std::{fs, io, path::PathBuf};
+use trash;
use tui::backend::Backend;
use tui_react::Terminal;
@@ -229,6 +230,26 @@ impl AppState {
self.message = None;
res
}
+ Some(MarkMode::Trash) => {
+ self.message = Some("Trashing entries...".to_string());
+ let mut entries_trashed = 0;
+ let res = pane.iterate_deletable_items(|mut pane, entry_to_trash| {
+ window.mark_pane = Some(pane);
+ self.draw(window, traversal, display, terminal).ok();
+ pane = window.mark_pane.take().expect("option to be filled");
+ match self.trash_entry(entry_to_trash, traversal) {
+ Ok(ed) => {
+ entries_trashed += ed;
+ self.message =
+ Some(format!("Trashed {} entries...", entries_trashed));
+ Ok(pane)
+ }
+ Err(c) => Err((pane, c)),
+ }
+ });
+ self.message = None;
+ res
+ }
None => Some(pane),
},
None => None,
@@ -274,6 +295,44 @@ impl AppState {
Ok(entries_deleted)
}
+ pub fn trash_entry(
+ &mut self,
+ index: TreeIndex,
+ traversal: &mut Traversal,
+ ) -> Result<usize, usize> {
+ let mut entries_trashed = 0;
+ if let Some(_entry) = traversal.tree.node_weight(index) {
+ let path_to_delete = path_of(&traversal.tree, index);
+ if let Err(_) = trash::delete(path_to_delete) {
+ return Err(1);
+ }
+ let parent_idx = traversal
+ .tree
+ .neighbors_directed(index, Direction::Incoming)
+ .next()
+ .expect("us being unable to delete the root index");
+ let mut bfs = Bfs::new(&traversal.tree, index);
+ while let Some(nx) = bfs.next(&traversal.tree) {
+ traversal.tree.remove_node(nx);
+ traversal.entries_traversed -= 1;
+ entries_trashed += 1;
+ }
+ self.entries = sorted_entries(&traversal.tree, self.root, self.sorting);
+ if traversal.tree.node_weight(self.root).is_none() {
+ self.set_root(traversal.root_index, traversal);
+ }
+ if self
+ .selected
+ .and_then(|selected| self.entries.iter().find(|e| e.index == selected))
+ .is_none()
+ {
+ self.selected = self.entries.get(0).map(|e| e.index);
+ }
+ self.recompute_sizes_recursively(parent_idx, traversal);
+ }
+ Ok(entries_trashed)
+ }
+
fn set_root(&mut self, root: TreeIndex, traversal: &Traversal) {
self.root = root;
self.entries = sorted_entries(&traversal.tree, root, self.sorting);
diff --git a/src/interactive/widgets/help.rs b/src/interactive/widgets/help.rs
index 89678db..d410035 100644
--- a/src/interactive/widgets/help.rs
+++ b/src/interactive/widgets/help.rs
@@ -168,6 +168,11 @@ impl HelpPane {
"Permanently delete all marked entries without prompt!",
Some("This operation cannot be undone!"),
);
+ hotkey(
+ "Ctrl + t",
+ "Move all marked entries to the trash bin",
+ Some("The entries can be restored from the trash bin"),
+ );
spacer();
}
title("Keys for application control");
diff --git a/src/interactive/widgets/mark.rs b/src/interactive/widgets/mark.rs
index 4e5829a..e01604b 100644
--- a/src/interactive/widgets/mark.rs
+++ b/src/interactive/widgets/mark.rs
@@ -28,6 +28,7 @@ use unicode_segmentation::UnicodeSegmentation;
pub enum MarkMode {
Delete,
+ Trash,
}
pub type EntryMarkMap = BTreeMap<TreeIndex, EntryMark>;
@@ -109,6 +110,7 @@ impl MarkPane {
let action = None;
match key {
Ctrl('r') => return Some(self.prepare_deletion()),
+ Ctrl('t') => return Some(self.prepare_trashing()),
Char('x') | Char('d') | Char(' ') => {
return self.remove_selected().map(|s| (s, action))
}
@@ -184,6 +186,13 @@ impl MarkPane {
self.selected = Some(0);
(self, Some(MarkMode::Delete))
}
+ fn prepare_trashing(mut self) -> (Self, Option<MarkMode>) {
+ for entry in self.marked.values_mut() {
+ entry.num_errors_during_deletion = 0;
+ }
+ self.selected = Some(0);
+ (self, Some(MarkMode::Trash))
+ }
fn remove_selected(mut self) -> Option<Self> {
if let Some(mut selected) = self.selected {
let idx = self.tree_index_by_list_position(selected);