Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement selecting next/prev siblings #42

Merged
merged 1 commit into from
Mar 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ de-select node | Esc | save | C-x
exit | Esc with nothing selected | exit | C-c
jump to weighted next task | C-v | cut / paste node | C-y
move selected up in child list | C-g | move selected down in child list | C-d
search for node at or below current view | C-u | Select parent | A-p
search for node at or below current view | C-u | Select parent | A-S-p (alt shift)
Select next sibling | A-n | select previous sibling | A-p

can be customized by setting the `KEYFILE` env var to the path of a [key configuration file](default.keys)

Expand Down
8 changes: 7 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ pub enum Action {
UndoDelete,
Help,
SelectParent,
SelectNextSibling,
SelectPrevSibling,
}

fn to_action(input: String) -> Option<Action> {
Expand Down Expand Up @@ -83,6 +85,8 @@ fn to_action(input: String) -> Option<Action> {
"undo_delete" => Some(Action::UndoDelete),
"help" => Some(Action::Help),
"select_parent" => Some(Action::SelectParent),
"select_next_sibling" => Some(Action::SelectNextSibling),
"select_prev_sibling" => Some(Action::SelectPrevSibling),
_ => None,
}
}
Expand Down Expand Up @@ -160,7 +164,9 @@ impl Default for Config {
(Ctrl('u'), Action::Search),
(Ctrl('z'), Action::UndoDelete),
(Ctrl('?'), Action::Help),
(Alt('p'), Action::SelectParent),
(Alt('P'), Action::SelectParent),
(Alt('n'), Action::SelectNextSibling),
(Alt('p'), Action::SelectPrevSibling),
]
.into_iter()
.collect(),
Expand Down
34 changes: 34 additions & 0 deletions src/screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ impl Screen {
Action::Search => self.search_forward(),
Action::UndoDelete => self.undo_delete(),
Action::SelectParent => self.select_parent(),
Action::SelectNextSibling => self.select_next_sibling(),
Action::SelectPrevSibling => self.select_prev_sibling(),
},
None => warn!("received unknown input"),
}
Expand Down Expand Up @@ -1255,6 +1257,37 @@ impl Screen {
}
}

fn select_next_sibling(&mut self) { self.select_neighbor(SearchDirection::Forward); }

fn select_prev_sibling(&mut self) { self.select_neighbor(SearchDirection::Backward); }

fn select_neighbor(&mut self, dir: SearchDirection) -> Option<NodeID> {
use SearchDirection::*;
let selected_id = self.selected?;
let parent = self.nodes.get(&self.parent(selected_id)?)?;

let selected_idx = parent.children.iter().position(|&id| id == selected_id)? as u64;
let offset: isize = if dir == Forward { 1 } else { -1 };
if let Some(&neighbor_id) = parent
.children
.get((selected_idx as isize + offset) as usize)
{
self.select_node(neighbor_id);
} else {
let pos = if dir == Forward {
0
} else {
parent.children.len() - 1
};
// Wrap around if there is no neighbor sibling. We know that
// `parent.children` is nonempty because `selected_id` is one of them,
// so the indexing is safe.
self.select_node(parent.children[pos]);
}

None
}

fn drill_down(&mut self) {
trace!("drill_down()");
// bust grapheme cache on new view
Expand Down Expand Up @@ -2295,6 +2328,7 @@ impl Screen {
}
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
enum SearchDirection {
Forward,
Backward,
Expand Down