diff options
author | Sebastian Thiel <sthiel@thoughtworks.com> | 2020-05-04 11:40:02 +0800 |
---|---|---|
committer | Sebastian Thiel <sthiel@thoughtworks.com> | 2020-05-04 11:40:37 +0800 |
commit | 5cedded25d10800805d6717381bf2981e270e23d (patch) | |
tree | 46e8f80bcedcfba490a2e826c4cdeebb55dd89c1 | |
parent | 5c1a04bb108eefdb6e10294fef0681cf92ecbaad (diff) |
Add 'x' key to mark for deletion, without toggling
Fixes #45
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | src/interactive/app/eventloop.rs | 25 | ||||
-rw-r--r-- | src/interactive/app/handlers.rs | 27 | ||||
-rw-r--r-- | src/interactive/widgets/help.rs | 7 | ||||
-rw-r--r-- | src/interactive/widgets/mark.rs | 33 |
5 files changed, 73 insertions, 23 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e316be..0033c3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +#### v2.6.0 + +* Use `x` to only mark entries for deletion, instead of toggling them. + #### v2.5.0 Much more nuanced percentage bars for a more precise visualization of space consumption #### v2.4.1 Bugfix: Update currently visible entries when scanning diff --git a/src/interactive/app/eventloop.rs b/src/interactive/app/eventloop.rs index baf5c03..b34c170 100644 --- a/src/interactive/app/eventloop.rs +++ b/src/interactive/app/eventloop.rs @@ -1,7 +1,8 @@ use crate::interactive::{ sorted_entries, widgets::{MainWindow, MainWindowProps}, - ByteVisualization, CursorDirection, CursorMode, DisplayOptions, EntryDataBundle, SortMode, + ByteVisualization, CursorDirection, CursorMode, DisplayOptions, EntryDataBundle, MarkEntryMode, + SortMode, }; use dua::{ traverse::{Traversal, TreeIndex}, @@ -113,10 +114,24 @@ impl AppState { } FocussedPane::Main => match key { Char('O') => self.open_that(traversal), - Char(' ') => self.mark_entry(CursorMode::Toggle, window, traversal), - Char('d') => { - self.mark_entry(CursorMode::ToggleAndAdvanceDown, window, traversal) - } + Char(' ') => self.mark_entry( + CursorMode::KeepPosition, + MarkEntryMode::Toggle, + window, + traversal, + ), + Char('d') => self.mark_entry( + CursorMode::Advance, + MarkEntryMode::Toggle, + window, + traversal, + ), + Char('x') => self.mark_entry( + CursorMode::Advance, + MarkEntryMode::MarkForDeletion, + window, + traversal, + ), Char('u') | Char('h') | Backspace | Left => { self.exit_node_with_traversal(traversal) } diff --git a/src/interactive/app/handlers.rs b/src/interactive/app/handlers.rs index d2a5e38..44ebc3c 100644 --- a/src/interactive/app/handlers.rs +++ b/src/interactive/app/handlers.rs @@ -16,8 +16,14 @@ use tui_react::Terminal; #[derive(Copy, Clone)] pub enum CursorMode { + Advance, + KeepPosition, +} + +#[derive(Copy, Clone)] +pub enum MarkEntryMode { Toggle, - ToggleAndAdvanceDown, + MarkForDeletion, } pub enum CursorDirection { @@ -297,7 +303,13 @@ impl AppState { .map(|w| w.size); } - pub fn mark_entry(&mut self, mode: CursorMode, window: &mut MainWindow, traversal: &Traversal) { + pub fn mark_entry( + &mut self, + cursor: CursorMode, + mode: MarkEntryMode, + window: &mut MainWindow, + traversal: &Traversal, + ) { if let Some(index) = self.selected { let is_dir = self .entries @@ -305,13 +317,18 @@ impl AppState { .find(|e| e.index == index) .unwrap() .is_dir; + let should_toggle = match mode { + MarkEntryMode::Toggle => true, + MarkEntryMode::MarkForDeletion => false, + }; if let Some(pane) = window.mark_pane.take() { - window.mark_pane = pane.toggle_index(index, &traversal.tree, is_dir); + window.mark_pane = pane.toggle_index(index, &traversal.tree, is_dir, should_toggle); } else { - window.mark_pane = MarkPane::default().toggle_index(index, &traversal.tree, is_dir) + window.mark_pane = + MarkPane::default().toggle_index(index, &traversal.tree, is_dir, should_toggle) } }; - if let CursorMode::ToggleAndAdvanceDown = mode { + if let CursorMode::Advance = cursor { self.change_entry_selection(CursorDirection::Down) } } diff --git a/src/interactive/widgets/help.rs b/src/interactive/widgets/help.rs index 8b40542..c80770c 100644 --- a/src/interactive/widgets/help.rs +++ b/src/interactive/widgets/help.rs @@ -154,12 +154,17 @@ impl HelpPane { "Toggle the currently selected entry and move down", None, ); + hotkey( + "x", + "Mark for the currently selected entry for deletion and move down", + None, + ); hotkey("<space bar>", "Toggle the currently selected entry", None); spacer(); } title("Keys in the Mark pane"); { - hotkey("d/<space>", "remove the selected entry from the list", None); + hotkey("x/d/<space>", "remove the selected entry from the list", None); hotkey( "Ctrl + r", "Permanently delete all marked entries without prompt!", diff --git a/src/interactive/widgets/mark.rs b/src/interactive/widgets/mark.rs index 53833ae..ef62f76 100644 --- a/src/interactive/widgets/mark.rs +++ b/src/interactive/widgets/mark.rs @@ -6,22 +6,21 @@ use dua::{ ByteFormat, }; use itertools::Itertools; -use std::{borrow::Borrow, collections::btree_map::Entry, collections::BTreeMap, path::PathBuf}; +use std::{ + borrow::Borrow, + collections::{btree_map::Entry, BTreeMap}, + path::PathBuf, +}; use termion::{event::Key, event::Key::*}; use tui::{ buffer::Buffer, - layout::Rect, - layout::{Constraint, Direction, Layout}, + layout::{Constraint, Direction, Layout, Rect}, style::{Color, Modifier, Style}, - widgets::Block, - widgets::Borders, - widgets::Text, - widgets::{Paragraph, Widget}, + widgets::{Block, Borders, Paragraph, Text, Widget}, }; use tui_react::{ draw_text_nowrap_fn, - util::rect::line_bound, - util::{block_width, rect}, + util::{block_width, rect, rect::line_bound}, List, ListProps, }; use unicode_segmentation::UnicodeSegmentation; @@ -66,7 +65,13 @@ impl MarkPane { self.selected = None } } - pub fn toggle_index(mut self, index: TreeIndex, tree: &Tree, is_dir: bool) -> Option<Self> { + pub fn toggle_index( + mut self, + index: TreeIndex, + tree: &Tree, + is_dir: bool, + toggle: bool, + ) -> Option<Self> { match self.marked.entry(index) { Entry::Vacant(entry) => { if let Some(e) = tree.node_weight(index) { @@ -82,7 +87,9 @@ impl MarkPane { } } Entry::Occupied(entry) => { - entry.remove(); + if toggle { + entry.remove(); + } } }; if self.marked.is_empty() { @@ -98,7 +105,9 @@ impl MarkPane { let action = None; match key { Ctrl('r') => return self.prepare_deletion(), - Char('d') | Char(' ') => return self.remove_selected().map(|s| (s, action)), + Char('x') | Char('d') | Char(' ') => { + return self.remove_selected().map(|s| (s, action)) + } Ctrl('u') | PageUp => self.change_selection(CursorDirection::PageUp), Char('k') | Up => self.change_selection(CursorDirection::Up), Char('j') | Down => self.change_selection(CursorDirection::Down), |