diff options
author | Sebastian Thiel <sthiel@thoughtworks.com> | 2019-06-03 14:41:38 +0530 |
---|---|---|
committer | Sebastian Thiel <sthiel@thoughtworks.com> | 2019-06-03 14:41:38 +0530 |
commit | a76ad5009ac9177e1efb37130d1dcedb5df1e5de (patch) | |
tree | 6767c318a8381980f160ee280062ee220f13d204 | |
parent | 1cfb62722d25ee17109fd0073e3cd0ac6a022ffa (diff) |
add 'j' key functionality for basic navigation
-rw-r--r-- | src/interactive/app.rs | 17 | ||||
-rw-r--r-- | tests/interactive.rs | 79 |
2 files changed, 69 insertions, 27 deletions
diff --git a/src/interactive/app.rs b/src/interactive/app.rs index 6febc5a..ce5cc65 100644 --- a/src/interactive/app.rs +++ b/src/interactive/app.rs @@ -1,6 +1,7 @@ use super::widgets::{DisplayState, MainWindow}; use crate::{interactive::Traversal, sorted_entries, ByteFormat, WalkOptions, WalkResult}; use failure::Error; +use itertools::Itertools; use std::{io, path::PathBuf}; use termion::input::{Keys, TermReadEventsAndRaw}; use tui::widgets::Widget; @@ -62,6 +63,22 @@ impl TerminalApp { self.draw(terminal)?; for key in keys.filter_map(Result::ok) { match key { + Char('j') => { + let entries = + sorted_entries(&self.traversal.tree, self.state.root, self.state.sorting); + let next_selected_pos = match self.state.selected { + Some(ref selected) => entries + .iter() + .find_position(|(idx, _)| *idx == *selected) + .map(|(idx, _)| idx + 1) + .unwrap_or(0), + None => 0, + }; + self.state.selected = match entries.get(next_selected_pos) { + Some((idx, _)) => Some(*idx), + None => self.state.selected, + }; + } Char('s') => self.state.sorting.toggle_size(), Ctrl('c') | Char('\n') | Char('q') => break, _ => {} diff --git a/tests/interactive.rs b/tests/interactive.rs index e6db413..5b9136f 100644 --- a/tests/interactive.rs +++ b/tests/interactive.rs @@ -50,8 +50,8 @@ mod app { app.traversal.tree.node_weight(id).unwrap() } - fn node_by_id(app: &TerminalApp, id: TreeIndexType) -> &EntryData { - app.traversal.tree.node_weight(id.into()).unwrap() + fn node_by_name(app: &TerminalApp, name: impl AsRef<OsStr>) -> &EntryData { + node_by_index(app, index_by_name(&app, name)) } fn index_by_name(app: &TerminalApp, name: impl AsRef<OsStr>) -> TreeIndex { @@ -73,35 +73,60 @@ mod app { #[test] fn simple_user_journey() -> Result<(), Error> { let long_root = "sample-02/dir"; - let (mut terminal, mut app) = initialized_app_and_terminal(&["sample-02", long_root])?; + let short_root = "sample-02"; + let (mut terminal, mut app) = initialized_app_and_terminal(&[short_root, long_root])?; + // POST-INIT // after initialization, we expect that... - assert_eq!( - app.state.sorting, - SortMode::SizeDescending, - "it will sort entries in descending order by size" - ); - - let first_selected_path = OsString::from(format!("{}/{}", FIXTURE_PATH, long_root)); - assert_eq!( - node_by_index(&app, index_by_name(&app, &first_selected_path)).name, - first_selected_path, - "the roots are always listed with the given (possibly long) names", - ); + { + assert_eq!( + app.state.sorting, + SortMode::SizeDescending, + "it will sort entries in descending order by size" + ); + + let first_selected_path = OsString::from(format!("{}/{}", FIXTURE_PATH, long_root)); + assert_eq!( + node_by_name(&app, &first_selected_path).name, + first_selected_path, + "the roots are always listed with the given (possibly long) names", + ); + + assert_eq!( + node_by_name(&app, fixture_str(short_root)), + node_by_index(&app, *app.state.selected.as_ref().unwrap()), + "it selects the first node in the list", + ); + } - assert_eq!( - node_by_id(&app, 1).name, - node_by_index(&app, *app.state.selected.as_ref().unwrap()).name, - "it selects the first node in the list", - ); + // SORTING + { + // when hitting the S key + app.process_events(&mut terminal, b"s".keys())?; + assert_eq!( + app.state.sorting, + SortMode::SizeAscending, + "it sets the sort mode to ascending by size" + ); + // when hitting the S key again + app.process_events(&mut terminal, b"s".keys())?; + assert_eq!( + app.state.sorting, + SortMode::SizeDescending, + "it sets the sort mode to descending by size" + ); + } - // when hitting the S key - app.process_events(&mut terminal, b"s".keys())?; - assert_eq!( - app.state.sorting, - SortMode::SizeAscending, - "it sets the sort mode to ascending by size" - ); + // Entry-Navigation + // when hitting the j key + { + app.process_events(&mut terminal, b"j".keys())?; + assert_eq!( + node_by_name(&app, fixture_str(long_root)), + node_by_index(&app, *app.state.selected.as_ref().unwrap()), + "it moves the cursor down and selects the next entry based on the current sort mode" + ); + } Ok(()) } |