Repository: Canop/broot (language: rust)

Issue:
Optionally use system trash implementation when using `rm`
When using the `rm` verb, optionally move the deleted items to the system trash instead of unlinking them.

Nushell supports this with `rm`. It appears to use this implementation: https://docs.rs/trash/latest/trash/


Discussion / hints:
This could maybe be a new `:trash` internal. I might try that.

Fix patch:
diff --git a/Cargo.lock b/Cargo.lock
index 39448bef..be0d2d72 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -265,6 +265,7 @@ dependencies = [
  "terminal-clipboard",
  "terminal-light",
  "toml",
+ "trash",
  "umask",
  "unicode-width",
  "uzers",
@@ -335,7 +336,7 @@ dependencies = [
  "num-traits",
  "serde",
  "wasm-bindgen",
- "windows-targets",
+ "windows-targets 0.48.5",
 ]
 
 [[package]]
@@ -1518,7 +1519,7 @@ dependencies = [
  "libc",
  "redox_syscall",
  "smallvec",
- "windows-targets",
+ "windows-targets 0.48.5",
 ]
 
 [[package]]
@@ -2323,6 +2324,22 @@ dependencies = [
  "winnow",
 ]
 
+[[package]]
+name = "trash"
+version = "3.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c646008e5144d988005bec12b1e56f5e0a951e957176686815eba8b025e0418"
+dependencies = [
+ "chrono",
+ "libc",
+ "log",
+ "objc",
+ "once_cell",
+ "scopeguard",
+ "url",
+ "windows",
+]
+
 [[package]]
 name = "ttf-parser"
 version = "0.19.2"
@@ -2623,13 +2640,22 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
+[[package]]
+name = "windows"
+version = "0.44.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b"
+dependencies = [
+ "windows-targets 0.42.2",
+]
+
 [[package]]
 name = "windows-core"
 version = "0.51.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
 dependencies = [
- "windows-targets",
+ "windows-targets 0.48.5",
 ]
 
 [[package]]
@@ -2638,7 +2664,22 @@ version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
 dependencies = [
- "windows-targets",
+ "windows-targets 0.48.5",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
 ]
 
 [[package]]
@@ -2647,51 +2688,93 @@ version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
 dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
+ "windows_aarch64_gnullvm 0.48.5",
+ "windows_aarch64_msvc 0.48.5",
+ "windows_i686_gnu 0.48.5",
+ "windows_i686_msvc 0.48.5",
+ "windows_x86_64_gnu 0.48.5",
+ "windows_x86_64_gnullvm 0.48.5",
+ "windows_x86_64_msvc 0.48.5",
 ]
 
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+
 [[package]]
 name = "windows_aarch64_gnullvm"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
 
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+
 [[package]]
 name = "windows_aarch64_msvc"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
 
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+
 [[package]]
 name = "windows_i686_gnu"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
 
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+
 [[package]]
 name = "windows_i686_msvc"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
 
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+
 [[package]]
 name = "windows_x86_64_gnu"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
 
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+
 [[package]]
 name = "windows_x86_64_gnullvm"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
 
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
 [[package]]
 name = "windows_x86_64_msvc"
 version = "0.48.5"
diff --git a/Cargo.toml b/Cargo.toml
index f3b8c785..c3092104 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -62,6 +62,7 @@ termimad = "0.26.1"
 terminal-clipboard = { version = "0.4.1", optional = true }
 terminal-light = "1.1.1"
 toml = "0.8"
+trash = "3.1"
 umask = "2.1.0"
 unicode-width = "0.1.10"
 which = "4.4.0"
diff --git a/resources/default-conf/verbs.hjson b/resources/default-conf/verbs.hjson
index d6a39584..2191040d 100644
--- a/resources/default-conf/verbs.hjson
+++ b/resources/default-conf/verbs.hjson
@@ -76,6 +76,15 @@ verbs: [
         execution: "cp -r {file} {parent}/{file-stem}-{version}{file-dot-extension}"
     }
 
+    # By default, `rm` does the system rm, and completely removes
+    # the file. If you prefer to have the file moved to the system
+    # trash, you may use the ':trash' internal with the verb below:
+    # {
+    #     invocation: "rm"
+    #     internal: "trash {file}"
+    #     leave_broot: false
+    # }
+
     # This verb lets you launch a terminal on ctrl-T
     # (on exit you'll be back in broot)
     {
diff --git a/src/browser/browser_state.rs b/src/browser/browser_state.rs
index a6470d34..74d11b72 100644
--- a/src/browser/browser_state.rs
+++ b/src/browser/browser_state.rs
@@ -598,6 +598,17 @@ impl PanelState for BrowserState {
                     }
                 }
             }
+            Internal::trash => {
+                let path = self.displayed_tree().selected_line().path.to_path_buf();
+                info!("trash {:?}", &path);
+                match trash::delete(&path) {
+                    Ok(()) => CmdResult::RefreshState { clear_cache: true },
+                    Err(e) => {
+                        warn!("trash error: {:?}", &e);
+                        CmdResult::DisplayError(format!("trash error: {:?}", &e))
+                    }
+                }
+            }
             Internal::quit => CmdResult::Quit,
             _ => self.on_internal_generic(
                 w,
diff --git a/src/verb/internal.rs b/src/verb/internal.rs
index 54b92bf3..c2ba0f9c 100644
--- a/src/verb/internal.rs
+++ b/src/verb/internal.rs
@@ -147,6 +147,7 @@ Internals! {
     toggle_trim_root: "toggle removing nodes at first level too" false,
     toggle_second_tree: "toggle display of a second tree panel" true,
     total_search: "search again but on all children" false,
+    trash: "move file to system trash" true,
     up_tree: "focus the parent of the current root" true,
 }
 
diff --git a/src/verb/verb_store.rs b/src/verb/verb_store.rs
index e8ebd856..0229a34a 100644
--- a/src/verb/verb_store.rs
+++ b/src/verb/verb_store.rs
@@ -298,6 +298,7 @@ impl VerbStore {
         self.add_internal(toggle_perm).with_shortcut("perm");
         self.add_internal(toggle_sizes).with_shortcut("sizes");
         self.add_internal(toggle_trim_root);
+        self.add_internal(trash);
         self.add_internal(total_search).with_key(key!(ctrl-s));
         self.add_internal(up_tree).with_shortcut("up");
     }
diff --git a/website/docs/css/extra.css b/website/docs/css/extra.css
index 0de9f9ef..eb8cb252 100644
--- a/website/docs/css/extra.css
+++ b/website/docs/css/extra.css
@@ -39,9 +39,9 @@ h3 {
 	font-size: 16px;
 }
 
-.navbar {
-	//background-image: linear-gradient(#184965,#02121b);
+body .navbar {
 	background: #1b465f;
+	box-shadow: 0 1px 5px rgba(0,0,0,0.1);
 }
 
 @media (min-width: 768px) {
diff --git a/website/docs/index.md b/website/docs/index.md
index d5edf1ff..f718db71 100644
--- a/website/docs/index.md
+++ b/website/docs/index.md
@@ -21,7 +21,7 @@ As you sometimes want to see gitignored files, or hidden ones, you'll soon get u
 
 (you can ignore them though, see [documentation](../navigation/#toggles)).
 
-# Find a directory then `cd` to it
+# Find a directory then `cd`
 
 type a few letters
 
@@ -111,7 +111,7 @@ Broot displays images in high resolution when the terminal supports Kitty's grap
 
 ![kitty preview](img/20201127-kitty-preview.png)
 
-# Apply a standard or personal command to a file
+# Apply a command to a file
 
 ![size](img/20230930-edit.png)
 
@@ -135,7 +135,7 @@ If you want to display *sizes*, *dates* and *permissions*, do `br -sdp` which ge
 
 You may also toggle options with a few keystrokes while inside broot. For example hitting a space, a <kbd>d</kbd> then <kbd>enter</kbd> shows you the dates. Or hit <kbd>alt</kbd><kbd>h</kbd> and you see hidden files.
 
-# Sort, see what takes space:
+# See what takes space:
 
 You may sort by launching broot with `--sort-by-size` or `--sort-by-date`. Or you may, inside broot, type a space, then `sd`, and <kbd>enter</kbd> and you toggled the `:sort_by_date` mode.
 


Test patch: