diff options
author | Ivan Tham | 2021-06-12 10:46:05 +0000 |
---|---|---|
committer | Ivan Tham | 2021-06-15 04:00:31 +0000 |
commit | 002f1ad397a6fff4fec044e05a8784c643a04d48 (patch) | |
tree | 07e7fa9435cbef705963fb05575d66b0813d0cd2 /helix-term | |
parent | 7c2fb92c9170ff108bef244e7aed82e29156ae5c (diff) |
Add filter ability to picker
Inspired by doom emacs. Able to filter picker options multiple times.
Diffstat (limited to 'helix-term')
-rw-r--r-- | helix-term/src/ui/picker.rs | 22 | ||||
-rw-r--r-- | helix-term/src/ui/prompt.rs | 7 |
2 files changed, 29 insertions, 0 deletions
diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index eae9d74f..20d51d5d 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -23,6 +23,8 @@ pub struct Picker<T> { matcher: Box<Matcher>, /// (index, score) matches: Vec<(usize, i64)>, + /// Filter over original options. + filters: Vec<usize>, // could be optimized into bit but not worth it now cursor: usize, // pattern: String, @@ -50,6 +52,7 @@ impl<T> Picker<T> { options, matcher: Box::new(Matcher::default()), matches: Vec::new(), + filters: Vec::new(), cursor: 0, prompt, format_fn: Box::new(format_fn), @@ -68,6 +71,7 @@ impl<T> Picker<T> { ref mut options, ref mut matcher, ref mut matches, + ref filters, ref format_fn, .. } = *self; @@ -81,6 +85,10 @@ impl<T> Picker<T> { .iter() .enumerate() .filter_map(|(index, option)| { + // filter options first before matching + if !filters.is_empty() { + filters.binary_search(&index).ok()?; + } // TODO: maybe using format_fn isn't the best idea here let text = (format_fn)(option); // TODO: using fuzzy_indices could give us the char idx for match highlighting @@ -114,6 +122,14 @@ impl<T> Picker<T> { .get(self.cursor) .map(|(index, _score)| &self.options[*index]) } + + pub fn save_filter(&mut self) { + self.filters.clear(); + self.filters + .extend(self.matches.iter().map(|(index, _)| *index)); + self.filters.sort_unstable(); // used for binary search later + self.prompt.clear(); + } } // process: @@ -205,6 +221,12 @@ impl<T: 'static> Component for Picker<T> { } return close_fn; } + KeyEvent { + code: KeyCode::Char(' '), + modifiers: KeyModifiers::CONTROL, + } => { + self.save_filter(); + } _ => { if let EventResult::Consumed(_) = self.prompt.handle_event(event, cx) { // TODO: recalculate only if pattern changed diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index 433de15e..c388c315 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -106,6 +106,13 @@ impl Prompt { self.exit_selection(); } + pub fn clear(&mut self) { + self.line.clear(); + self.cursor = 0; + self.completion = (self.completion_fn)(&self.line); + self.exit_selection(); + } + pub fn change_completion_selection(&mut self, direction: CompletionDirection) { if self.completion.is_empty() { return; |