summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Thiel <sthiel@thoughtworks.com>2019-06-03 14:48:22 +0530
committerSebastian Thiel <sthiel@thoughtworks.com>2019-06-03 14:49:21 +0530
commit748dfc353a7d8c7bbb6bbfb097bacec18b80e32a (patch)
tree7d04a7f9887a5672c8cc8fa10ee1310d36d37433
parenta76ad5009ac9177e1efb37130d1dcedb5df1e5de (diff)
add 'k' navigation key
-rw-r--r--src/interactive/app.rs44
-rw-r--r--tests/interactive.rs23
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(())