From 73799663483bf5e9203655d65c517002ffddc9bf Mon Sep 17 00:00:00 2001 From: Sunny Date: Tue, 7 Sep 2021 18:42:17 +0530 Subject: [PATCH] search: Improve the search matcher Introduces fuzzy matcher to improve the theme search. --- Cargo.lock | 19 +++++++++++++++++ Cargo.toml | 1 + src/operations/search.rs | 44 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 920d51f..ace41ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -252,6 +252,15 @@ dependencies = [ "slab", ] +[[package]] +name = "fuzzy-matcher" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" +dependencies = [ + "thread_local", +] + [[package]] name = "getrandom" version = "0.2.3" @@ -466,6 +475,7 @@ dependencies = [ "colored", "dirs-next", "edit-distance", + "fuzzy-matcher", "git2", "log", "pretty_env_logger", @@ -1034,6 +1044,15 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thread_local" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +dependencies = [ + "once_cell", +] + [[package]] name = "tinyvec" version = "1.2.0" diff --git a/Cargo.toml b/Cargo.toml index e8f3e14..1a56c17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,3 +27,4 @@ colored = "2.0.0" git2 = "0.13.17" edit-distance = "2.1.0" tempfile = "3.2.0" +fuzzy-matcher = "0.3.7" diff --git a/src/operations/search.rs b/src/operations/search.rs index e1d29ab..cbf3219 100644 --- a/src/operations/search.rs +++ b/src/operations/search.rs @@ -4,6 +4,8 @@ use clap::Clap; use colored::Colorize; use edit_distance::edit_distance; use errors::LeftError; +use fuzzy_matcher::skim::SkimMatcherV2; +use fuzzy_matcher::FuzzyMatcher; use log::trace; /* This function searches for themes, but does not update them by default @@ -34,7 +36,7 @@ impl Search { &theme.name, edit_distance(&theme.name, &self.name) ); - if edit_distance(&theme.name, &self.name) <= 3 { + if Search::edit_distance_match(&theme.name, &self.name) { let current = match theme.current { Some(true) => "Current: ".bright_yellow().bold(), _ => "".white(), @@ -64,4 +66,44 @@ impl Search { Ok(()) } + + // Performs a match using edit_distance. + fn edit_distance_match(a: &str, b: &str) -> bool { + if edit_distance(a, b) <= 3 { + return true; + } + false + } + + #[allow(dead_code)] + // Performs a using fuzzy matcher. + fn fuzzy_matcher_match(a: &str, b: &str) -> bool { + let matcher = SkimMatcherV2::default(); + matcher.fuzzy_match(a, b).is_some() + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_match() { + // Temporary, to demonstrate mismatch. Will be removed later. + assert!(!Search::edit_distance_match("apple pie", "apple")); + assert!(!Search::edit_distance_match("apple pie", "pie")); + assert!(!Search::edit_distance_match("Windows XP", "windows")); + assert!(!Search::edit_distance_match("Windows XP", "xp")); + assert!(!Search::edit_distance_match("Windows XP", "zinbows")); + assert!(!Search::edit_distance_match("Soothe", "soo")); + assert!(Search::edit_distance_match("Soothe", "soohe")); + + assert!(Search::fuzzy_matcher_match("apple pie", "apple")); + assert!(Search::fuzzy_matcher_match("apple pie", "pie")); + assert!(Search::fuzzy_matcher_match("Windows XP", "xp")); + assert!(Search::fuzzy_matcher_match("Windows XP", "windows")); + assert!(!Search::fuzzy_matcher_match("Windows XP", "zinbows")); + assert!(Search::fuzzy_matcher_match("Soothe", "soo")); + assert!(Search::fuzzy_matcher_match("Soothe", "soohe")); + } }