use nucleo_matcher::{
Config, Matcher, Utf32Str,
pattern::{AtomKind, CaseMatching, Normalization, Pattern},
};
pub fn create_matcher() -> Matcher {
Matcher::new(Config::DEFAULT)
}
pub fn match_items_with_history(
matcher: &mut Matcher,
items: &[String],
input: &str,
history: &[String],
) -> Vec<usize> {
if input.is_empty() {
return (0..items.len()).collect();
}
let pattern = Pattern::new(
input,
CaseMatching::Ignore,
Normalization::Smart,
AtomKind::Fuzzy,
);
let mut buf = Vec::new();
let mut results: Vec<(usize, u32)> = items
.iter()
.enumerate()
.filter_map(|(i, name)| {
buf.clear();
let haystack = Utf32Str::new(name.as_str(), &mut buf);
let score = pattern.score(haystack, matcher)?;
let bonus = history
.iter()
.position(|h| h == name)
.map(|pos| 30u32.saturating_sub(pos as u32).max(5))
.unwrap_or(0);
Some((i, score + bonus))
})
.collect();
results.sort_by_key(|b| std::cmp::Reverse(b.1));
results.into_iter().map(|(i, _)| i).collect()
}