diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | src/app/mod.rs | 2 | ||||
-rw-r--r-- | src/app/state.rs | 13 | ||||
-rw-r--r-- | src/browser/browser_state.rs | 6 | ||||
-rw-r--r-- | src/filesystems/filesystems_state.rs | 10 | ||||
-rw-r--r-- | src/help/help_state.rs | 4 | ||||
-rw-r--r-- | src/preview/preview.rs | 15 | ||||
-rw-r--r-- | src/preview/preview_state.rs | 6 | ||||
-rw-r--r-- | src/syntactic/syntactic_view.rs | 39 | ||||
-rw-r--r-- | src/tree/tree.rs | 4 | ||||
-rw-r--r-- | src/verb/internal.rs | 4 | ||||
-rw-r--r-- | src/verb/mod.rs | 2 | ||||
-rw-r--r-- | website/docs/conf_verbs.md | 2 |
13 files changed, 60 insertions, 48 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 835a0ff..b52aa26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### next * dev.log renamed into broot.log +* `:line_up` and `:line_down` accept an optional count as argument - Fix #301 <a name="v1.0.5"></a> ### v1.0.5 - 2020-11-05 diff --git a/src/app/mod.rs b/src/app/mod.rs index 24c59f4..7cc3ea6 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -20,7 +20,7 @@ pub use { panel_id::PanelId, panel_purpose::PanelPurpose, selection::{LineNumber, Selection, SelectionType}, - state::AppState, + state::*, state_type::AppStateType, status::Status, standard_status::StandardStatus, diff --git a/src/app/state.rs b/src/app/state.rs index 43fe3dd..eae7e0d 100644 --- a/src/app/state.rs +++ b/src/app/state.rs @@ -16,6 +16,7 @@ use { }, std::{ path::{Path, PathBuf}, + str::FromStr, }, termimad::Area, }; @@ -558,3 +559,15 @@ pub trait AppState { } } } + +pub fn get_arg<T: Copy + FromStr>( + verb_invocation: Option<&VerbInvocation>, + internal_exec: &InternalExecution, + default: T, +) -> T { + verb_invocation.and_then(|vi| vi.args.as_ref()) + .or(internal_exec.arg.as_ref()) + .and_then(|s| s.parse::<T>().ok()) + .unwrap_or(default) +} + diff --git a/src/browser/browser_state.rs b/src/browser/browser_state.rs index 080452e..8e9d3f8 100644 --- a/src/browser/browser_state.rs +++ b/src/browser/browser_state.rs @@ -285,11 +285,13 @@ impl AppState for BrowserState { Internal::open_stay => self.open_selection_stay_in_broot(screen, con, bang, false)?, Internal::open_stay_filter => self.open_selection_stay_in_broot(screen, con, bang, true)?, Internal::line_down => { - self.displayed_tree_mut().move_selection(1, page_height); + let count = get_arg(input_invocation, internal_exec, 1); + self.displayed_tree_mut().move_selection(count, page_height); AppStateCmdResult::Keep } Internal::line_up => { - self.displayed_tree_mut().move_selection(-1, page_height); + let count = get_arg(input_invocation, internal_exec, 1); + self.displayed_tree_mut().move_selection(-count, page_height); AppStateCmdResult::Keep } Internal::previous_match => { diff --git a/src/filesystems/filesystems_state.rs b/src/filesystems/filesystems_state.rs index 9764c03..71b19a3 100644 --- a/src/filesystems/filesystems_state.rs +++ b/src/filesystems/filesystems_state.rs @@ -434,25 +434,27 @@ impl AppState for FilesystemState { } } Internal::line_down => { + let count = get_arg(input_invocation, internal_exec, 1); if let Some(f) = self.filtered.as_mut() { if f.selection_idx + 1 < f.mounts.len() { - f.selection_idx += 1; + f.selection_idx += count.min(f.mounts.len()-f.selection_idx); } } else { if self.selection_idx + 1 < self.count() { - self.selection_idx += 1; + self.selection_idx += count.min(self.mounts.len().get()-self.selection_idx); } } AppStateCmdResult::Keep } Internal::line_up => { + let count = get_arg(input_invocation, internal_exec, 1); if let Some(f) = self.filtered.as_mut() { if f.selection_idx > 0 { - f.selection_idx -= 1; + f.selection_idx -= count.min(f.selection_idx); } } else { if self.selection_idx > 0 { - self.selection_idx -= 1; + self.selection_idx -= count.min(self.selection_idx); } } AppStateCmdResult::Keep diff --git a/src/help/help_state.rs b/src/help/help_state.rs index 6455e74..118473f 100644 --- a/src/help/help_state.rs +++ b/src/help/help_state.rs @@ -177,11 +177,11 @@ impl AppState for HelpState { } help => AppStateCmdResult::Keep, line_down => { - self.scroll += 1; + self.scroll += get_arg(input_invocation, internal_exec, 1); AppStateCmdResult::Keep } line_up => { - self.scroll -= 1; + self.scroll -= get_arg(input_invocation, internal_exec, 1); AppStateCmdResult::Keep } open_stay => match open::that(&Conf::default_location()) { diff --git a/src/preview/preview.rs b/src/preview/preview.rs index 19c444e..564b2d8 100644 --- a/src/preview/preview.rs +++ b/src/preview/preview.rs @@ -188,20 +188,11 @@ impl Preview { _ => false, } } - pub fn select_previous_line(&mut self) { + pub fn move_selection(&mut self, dy: i32) { match self { - Self::Syntactic(sv) => sv.select_previous_line(), + Self::Syntactic(sv) => sv.move_selection(dy), Self::Hex(hv) => { - hv.try_scroll(ScrollCommand::Lines(-1)); - } - _ => {} - } - } - pub fn select_next_line(&mut self) { - match self { - Self::Syntactic(sv) => sv.select_next_line(), - Self::Hex(hv) => { - hv.try_scroll(ScrollCommand::Lines(1)); + hv.try_scroll(ScrollCommand::Lines(dy)); } _ => {} } diff --git a/src/preview/preview_state.rs b/src/preview/preview_state.rs index 3631579..3deac7f 100644 --- a/src/preview/preview_state.rs +++ b/src/preview/preview_state.rs @@ -286,11 +286,13 @@ impl AppState for PreviewState { } } Internal::line_down => { - self.mut_preview().select_next_line(); + let count = get_arg(input_invocation, internal_exec, 1); + self.mut_preview().move_selection(count); Ok(AppStateCmdResult::Keep) } Internal::line_up => { - self.mut_preview().select_previous_line(); + let count = get_arg(input_invocation, internal_exec, 1); + self.mut_preview().move_selection(-count); Ok(AppStateCmdResult::Keep) } Internal::page_down => { diff --git a/src/syntactic/syntactic_view.rs b/src/syntactic/syntactic_view.rs index 12a2393..448cd37 100644 --- a/src/syntactic/syntactic_view.rs +++ b/src/syntactic/syntactic_view.rs @@ -230,28 +230,27 @@ impl SyntacticView { false } - pub fn select_previous_line(&mut self) { - if let Some(idx) = self.selection_idx { - if idx > 0 { - self.selection_idx = Some(idx - 1); - } else { - self.selection_idx = Some(self.lines.len()-1); - } - } else if !self.lines.is_empty() { - self.selection_idx = Some(self.lines.len()-1); - } - self.ensure_selection_is_visible(); - } - - pub fn select_next_line(&mut self) { - if let Some(idx) = self.selection_idx { - if idx < self.lines.len() - 1 { - self.selection_idx = Some(idx + 1); - } else { + pub fn move_selection(&mut self, dy: i32) { + if dy > 0 { + if let Some(idx) = self.selection_idx { + if idx < self.lines.len() - 1 { + self.selection_idx = Some(idx + dy.min(self.lines.len() as i32 - 1 - dy) as usize); + } else { + self.selection_idx = Some(0); + } + } else if !self.lines.is_empty() { self.selection_idx = Some(0); } - } else if !self.lines.is_empty() { - self.selection_idx = Some(0); + } else if dy < 0 { + if let Some(idx) = self.selection_idx { + if idx > 0 { + self.selection_idx = Some(idx - (-dy).min(idx as i32) as usize); + } else { + self.selection_idx = Some(self.lines.len()-1); + } + } else if !self.lines.is_empty() { + self.selection_idx = Some(self.lines.len()-1); + } } self.ensure_selection_is_visible(); } diff --git a/src/tree/tree.rs b/src/tree/tree.rs index 465e9cf..8ac8a79 100644 --- a/src/tree/tree.rs +++ b/src/tree/tree.rs @@ -145,7 +145,7 @@ impl Tree { /// /// For example the following one if dy is 1. pub fn move_selection(&mut self, dy: i32, page_height: i32) { - // only work for +1 or -1 + // FIXME may not work well if dy is too big let l = self.lines.len(); loop { self.selection = (self.selection + ((l as i32) + dy) as usize) % l; @@ -158,7 +158,6 @@ impl Tree { let sel = self.selection as i32; if l > page_height { if dy < 0 { - // -1 if sel == l - 1 { // cycling self.scroll = l - page_height; @@ -166,7 +165,6 @@ impl Tree { self.scroll = (self.scroll + 2 * dy).max(0); } } else { - // +1 if sel == 0 { // cycling brought us back to top self.scroll = 0; diff --git a/src/verb/internal.rs b/src/verb/internal.rs index 46eec23..ca2f48c 100644 --- a/src/verb/internal.rs +++ b/src/verb/internal.rs @@ -113,12 +113,16 @@ impl Internal { pub fn invocation_pattern(self) -> &'static str { match self { Internal::focus => r"focus (?P<path>.*)?", + Internal::line_down => r"line_down (?P<count>\d*)?", + Internal::line_up => r"line_up (?P<count>\d*)?", _ => self.name(), } } pub fn exec_pattern(self) -> &'static str { match self { Internal::focus => r"focus {path}", + Internal::line_down => r"line_down {count}", + Internal::line_up => r"line_up {count}", _ => self.name(), } } diff --git a/src/verb/mod.rs b/src/verb/mod.rs index 1657e1d..8b16b98 100644 --- a/src/verb/mod.rs +++ b/src/verb/mod.rs @@ -25,7 +25,7 @@ pub use { verb::Verb, verb_description::VerbDescription, verb_execution::VerbExecution, - verb_invocation::VerbInvocation, + verb_invocation::*, verb_store::{PrefixSearchResult, VerbStore}, }; diff --git a/website/docs/conf_verbs.md b/website/docs/conf_verbs.md index 86d7470..f2a8b9c 100644 --- a/website/docs/conf_verbs.md +++ b/website/docs/conf_verbs.md @@ -207,7 +207,7 @@ invocation | default key | default shortcut | behavior / details :cp {newpath} | - | - | copy the file or directory to the provided name :help | <kbd>F1</kbd> | - | open the help page. Help page can also be open with <kbd>?</kbd> :focus | <kbd>enter</kbd> | - | set the selected directory the root of the displayed tree | -:line_down | <kbd>↓</kbd> | - | scroll one line down or select the next line +:line_down | <kbd>↓</kbd> | - | scroll one line down or select the next line (can be used with an argument eg `:line_down 4`) :line_up | <kbd>↑</kbd> | - | scroll one line up or select the previous line :mkdir {subpath} | - | md | create a directory :mv {newpath} | - | - | move the file or directory to the provided path |