From 102af558f510d7466c13ecf1987938c36cf01029 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Sun, 15 Sep 2024 21:44:20 +0200 Subject: [PATCH] Actually add fuzzy matcher --- crates/gitnow/src/commands/root.rs | 37 ++++++++++++++++++------------ crates/gitnow/src/fuzzy_matcher.rs | 34 +++++++++++++++++++++++++++ crates/gitnow/src/main.rs | 1 + 3 files changed, 57 insertions(+), 15 deletions(-) create mode 100644 crates/gitnow/src/fuzzy_matcher.rs diff --git a/crates/gitnow/src/commands/root.rs b/crates/gitnow/src/commands/root.rs index 446beaa..bacb364 100644 --- a/crates/gitnow/src/commands/root.rs +++ b/crates/gitnow/src/commands/root.rs @@ -1,6 +1,8 @@ use nucleo_matcher::{pattern::Pattern, Matcher, Utf32Str}; -use crate::{app::App, cache::CacheApp, projects_list::ProjectsListApp}; +use crate::{ + app::App, cache::CacheApp, fuzzy_matcher::FuzzyMatcherApp, projects_list::ProjectsListApp, +}; #[derive(Debug, Clone)] pub struct RootCommand { @@ -26,28 +28,23 @@ impl RootCommand { repositories } }; - - let haystack = repositories - .iter() - .map(|r| r.to_rel_path().display().to_string()); - let needle = match search { Some(needle) => needle.into(), None => todo!(), }; - let pattern = Pattern::new( - &needle, - nucleo_matcher::pattern::CaseMatching::Ignore, - nucleo_matcher::pattern::Normalization::Smart, - nucleo_matcher::pattern::AtomKind::Fuzzy, - ); - let mut matcher = Matcher::new(nucleo_matcher::Config::DEFAULT); - let res = pattern.match_list(haystack, &mut matcher); + let haystack = repositories + .iter() + .map(|r| r.to_rel_path().display().to_string()) + .collect::>(); + + let haystack = haystack.as_str_vec(); + + let res = self.app.fuzzy_matcher().match_pattern(&needle, &haystack); let res = res.iter().take(10).rev().collect::>(); - for (repo, _score) in res { + for repo in res { tracing::debug!("repo: {:?}", repo); } @@ -56,3 +53,13 @@ impl RootCommand { Ok(()) } } + +trait StringExt { + fn as_str_vec<'a>(&'a self) -> Vec<&'a str>; +} + +impl StringExt for Vec { + fn as_str_vec<'a>(&'a self) -> Vec<&'a str> { + self.iter().map(|r| r.as_ref()).collect() + } +} diff --git a/crates/gitnow/src/fuzzy_matcher.rs b/crates/gitnow/src/fuzzy_matcher.rs new file mode 100644 index 0000000..63c22e7 --- /dev/null +++ b/crates/gitnow/src/fuzzy_matcher.rs @@ -0,0 +1,34 @@ +use nucleo_matcher::{pattern::Pattern, Matcher}; + +use crate::app::App; + +pub struct FuzzyMatcher {} + +impl FuzzyMatcher { + pub fn new() -> Self { + Self {} + } + + pub fn match_pattern<'a>(&self, pattern: &'a str, items: &'a [&'a str]) -> Vec<&'a str> { + let pat = Pattern::new( + &pattern, + nucleo_matcher::pattern::CaseMatching::Ignore, + nucleo_matcher::pattern::Normalization::Smart, + nucleo_matcher::pattern::AtomKind::Fuzzy, + ); + let mut matcher = Matcher::new(nucleo_matcher::Config::DEFAULT); + let res = pat.match_list(items, &mut matcher); + + res.into_iter().map(|((item, _))| *item).collect::>() + } +} + +pub trait FuzzyMatcherApp { + fn fuzzy_matcher(&self) -> FuzzyMatcher; +} + +impl FuzzyMatcherApp for &'static App { + fn fuzzy_matcher(&self) -> FuzzyMatcher { + FuzzyMatcher::new() + } +} diff --git a/crates/gitnow/src/main.rs b/crates/gitnow/src/main.rs index e7d2459..4209405 100644 --- a/crates/gitnow/src/main.rs +++ b/crates/gitnow/src/main.rs @@ -12,6 +12,7 @@ mod cache; mod cache_codec; mod commands; mod config; +mod fuzzy_matcher; mod git_provider; mod projects_list;