Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-term/src/ui/menu.rs')
-rw-r--r--helix-term/src/ui/menu.rs72
1 files changed, 19 insertions, 53 deletions
diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs
index 612832ce..76e50229 100644
--- a/helix-term/src/ui/menu.rs
+++ b/helix-term/src/ui/menu.rs
@@ -1,12 +1,7 @@
-use std::{borrow::Cow, cmp::Reverse};
-
use crate::{
compositor::{Callback, Component, Compositor, Context, Event, EventResult},
ctrl, key, shift,
};
-use helix_core::fuzzy::MATCHER;
-use nucleo::pattern::{Atom, AtomKind, CaseMatching, Normalization};
-use nucleo::{Config, Utf32Str};
use tui::{buffer::Buffer as Surface, widgets::Table};
pub use tui::widgets::{Cell, Row};
@@ -19,16 +14,6 @@ pub trait Item: Sync + Send + 'static {
type Data: Sync + Send + 'static;
fn format(&self, data: &Self::Data) -> Row;
-
- fn sort_text(&self, data: &Self::Data) -> Cow<str> {
- let label: String = self.format(data).cell_text().collect();
- label.into()
- }
-
- fn filter_text(&self, data: &Self::Data) -> Cow<str> {
- let label: String = self.format(data).cell_text().collect();
- label.into()
- }
}
pub type MenuCallback<T> = Box<dyn Fn(&mut Editor, Option<&T>, MenuEvent)>;
@@ -77,49 +62,30 @@ impl<T: Item> Menu<T> {
}
}
- pub fn score(&mut self, pattern: &str, incremental: bool) {
- let mut matcher = MATCHER.lock();
- matcher.config = Config::DEFAULT;
- let pattern = Atom::new(
- pattern,
- CaseMatching::Ignore,
- Normalization::Smart,
- AtomKind::Fuzzy,
- false,
- );
- let mut buf = Vec::new();
- if incremental {
- self.matches.retain_mut(|(index, score)| {
- let option = &self.options[*index as usize];
- let text = option.filter_text(&self.editor_data);
- let new_score = pattern.score(Utf32Str::new(&text, &mut buf), &mut matcher);
- match new_score {
- Some(new_score) => {
- *score = new_score as u32;
- true
- }
- None => false,
- }
- })
- } else {
- self.matches.clear();
- let matches = self.options.iter().enumerate().filter_map(|(i, option)| {
- let text = option.filter_text(&self.editor_data);
- pattern
- .score(Utf32Str::new(&text, &mut buf), &mut matcher)
- .map(|score| (i as u32, score as u32))
- });
- self.matches.extend(matches);
- }
- self.matches
- .sort_unstable_by_key(|&(i, score)| (Reverse(score), i));
-
- // reset cursor position
+ pub fn reset_cursor(&mut self) {
self.cursor = None;
self.scroll = 0;
self.recalculate = true;
}
+ pub fn update_options(&mut self) -> (&mut Vec<(u32, u32)>, &mut Vec<T>) {
+ self.recalculate = true;
+ (&mut self.matches, &mut self.options)
+ }
+
+ pub fn ensure_cursor_in_bounds(&mut self) {
+ if self.matches.is_empty() {
+ self.cursor = None;
+ self.scroll = 0;
+ } else {
+ self.scroll = 0;
+ self.recalculate = true;
+ if let Some(cursor) = &mut self.cursor {
+ *cursor = (*cursor).min(self.matches.len() - 1)
+ }
+ }
+ }
+
pub fn clear(&mut self) {
self.matches.clear();