mirror of
https://github.com/xvxx/phetch
synced 2024-11-10 13:10:54 +00:00
search on up/down
This commit is contained in:
parent
b1e6ec8981
commit
c5782a8d83
70
src/menu.rs
70
src/menu.rs
@ -272,6 +272,15 @@ impl Menu {
|
||||
};
|
||||
}
|
||||
|
||||
// if text is entered, find previous match
|
||||
if !self.input.is_empty() {
|
||||
if let Some(pos) = self.rlink_matching(self.link + 1, &self.input) {
|
||||
return self.action_select_link(pos);
|
||||
} else {
|
||||
return Action::None;
|
||||
}
|
||||
}
|
||||
|
||||
let new_link = self.link - 1;
|
||||
if let Some(dir) = self.link_visibility(new_link) {
|
||||
match dir {
|
||||
@ -315,11 +324,41 @@ impl Menu {
|
||||
}
|
||||
}
|
||||
|
||||
// search through links to find a match based on the pattern,
|
||||
// starting at link position `start`. returns the link position.
|
||||
fn link_matching(&self, start: usize, pattern: &str) -> Option<usize> {
|
||||
self.link_match_with_iter(pattern, &mut self.links.iter().skip(start))
|
||||
}
|
||||
|
||||
// search backwards
|
||||
fn rlink_matching(&self, start: usize, pattern: &str) -> Option<usize> {
|
||||
self.link_match_with_iter(pattern, &mut self.links.iter().take(start - 1).rev())
|
||||
}
|
||||
|
||||
fn link_match_with_iter<'a, T>(&self, pattern: &str, it: &mut T) -> Option<usize>
|
||||
where
|
||||
T: std::iter::Iterator<Item = &'a usize>,
|
||||
{
|
||||
let pattern = pattern.to_ascii_lowercase();
|
||||
while let Some(&i) = it.next() {
|
||||
let name = if let Some(link) = self.link(i) {
|
||||
link.name.to_ascii_lowercase()
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if name.contains(&pattern) {
|
||||
return Some(i);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn action_down(&mut self) -> Action {
|
||||
let new_link = self.link + 1;
|
||||
|
||||
// final link selected already
|
||||
if new_link >= self.links.len() {
|
||||
// no links or final link selected already
|
||||
if self.links.is_empty() || new_link >= self.links.len() {
|
||||
// if there are more rows, scroll down
|
||||
if self.scroll < self.padding_bottom() {
|
||||
self.scroll += 1;
|
||||
@ -329,7 +368,16 @@ impl Menu {
|
||||
}
|
||||
}
|
||||
|
||||
if !self.links.is_empty() && self.link < self.links.len() - 1 {
|
||||
// if text is entered, find next match
|
||||
if !self.input.is_empty() {
|
||||
if let Some(pos) = self.link_matching(self.link + 1, &self.input) {
|
||||
return self.action_select_link(pos);
|
||||
} else {
|
||||
return Action::None;
|
||||
}
|
||||
}
|
||||
|
||||
if self.link < self.links.len() - 1 {
|
||||
if let Some(dir) = self.link_visibility(new_link) {
|
||||
match dir {
|
||||
LinkDir::Above => {
|
||||
@ -508,21 +556,11 @@ impl Menu {
|
||||
}
|
||||
}
|
||||
|
||||
for i in 0..count {
|
||||
// check for name match
|
||||
let name = if let Some(link) = self.link(i) {
|
||||
link.name.to_ascii_lowercase()
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
|
||||
if name.contains(&self.input.to_ascii_lowercase()) {
|
||||
return self.action_select_link(i);
|
||||
}
|
||||
// name search
|
||||
if let Some(pos) = self.link_matching(0, &self.input) {
|
||||
return self.action_select_link(pos);
|
||||
}
|
||||
|
||||
// self.link = 0;
|
||||
// Action::Redraw
|
||||
self.redraw_input()
|
||||
}
|
||||
_ => Action::Keypress(key),
|
||||
|
Loading…
Reference in New Issue
Block a user