diff options
author | Sebastian Thiel <sthiel@thoughtworks.com> | 2019-06-03 14:48:22 +0530 |
---|---|---|
committer | Sebastian Thiel <sthiel@thoughtworks.com> | 2019-06-03 14:49:21 +0530 |
commit | 748dfc353a7d8c7bbb6bbfb097bacec18b80e32a (patch) | |
tree | 7d04a7f9887a5672c8cc8fa10ee1310d36d37433 | |
parent | a76ad5009ac9177e1efb37130d1dcedb5df1e5de (diff) |
add 'k' navigation key
-rw-r--r-- | src/interactive/app.rs | 44 | ||||
-rw-r--r-- | tests/interactive.rs | 23 |
2 files changed, 49 insertions, 18 deletions
diff --git a/src/interactive/app.rs b/src/interactive/app.rs index ce5cc65..4fcf8aa 100644 --- a/src/interactive/app.rs +++ b/src/interactive/app.rs @@ -26,6 +26,11 @@ pub struct TerminalApp { pub state: DisplayState, } +enum CursorDirection { + Down, + Up, +} + impl TerminalApp { fn draw<B>(&self, terminal: &mut Terminal<B>) -> Result<(), Error> where @@ -63,24 +68,10 @@ 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('k') => self.change_vertical_index(CursorDirection::Up), + Char('j') => self.change_vertical_index(CursorDirection::Down), Char('s') => self.state.sorting.toggle_size(), - Ctrl('c') | Char('\n') | Char('q') => break, + Ctrl('c') | Char('q') => break, _ => {} }; self.draw(terminal)?; @@ -90,6 +81,25 @@ impl TerminalApp { }) } + fn change_vertical_index(&mut self, direction: CursorDirection) -> () { + 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, _)| match direction { + CursorDirection::Down => idx.saturating_add(1), + CursorDirection::Up => idx.saturating_sub(1), + }) + .unwrap_or(0), + None => 0, + }; + self.state.selected = match entries.get(next_selected_pos) { + Some((idx, _)) => Some(*idx), + None => self.state.selected, + }; + } + pub fn initialize<B>( terminal: &mut Terminal<B>, options: WalkOptions, diff --git a/tests/interactive.rs b/tests/interactive.rs index 5b9136f..50d80c8 100644 --- a/tests/interactive.rs +++ b/tests/interactive.rs @@ -118,14 +118,35 @@ mod app { } // Entry-Navigation - // when hitting the j key { + // 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" ); + // when hitting it while there is nowhere to go + 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 stays at the previous position" + ); + // when hitting the k key + app.process_events(&mut terminal, b"k".keys())?; + assert_eq!( + node_by_name(&app, fixture_str(short_root)), + node_by_index(&app, *app.state.selected.as_ref().unwrap()), + "it moves the cursor up and selects the next entry based on the current sort mode" + ); + // when hitting the k key again + app.process_events(&mut terminal, b"k".keys())?; + assert_eq!( + node_by_name(&app, fixture_str(short_root)), + node_by_index(&app, *app.state.selected.as_ref().unwrap()), + "it stays at the current cursor position as there is nowhere to go" + ); } Ok(()) |