summaryrefslogtreecommitdiff
path: root/helix-core
diff options
context:
space:
mode:
authorPascal Kuthe2023-08-30 04:26:21 +0000
committerGitHub2023-08-30 04:26:21 +0000
commit0cb595e226c9970989ee1e680ae6b8011d188cbf (patch)
tree406b31b0343c74f96f9ae80d758f246a04374434 /helix-core
parent40d7e6c9c85d4f1ce2345f6e9d59fc091243124d (diff)
transition to nucleo for fuzzy matching (#7814)
* transition to nucleo for fuzzy matching * drop flakey test case since the picker streams in results now any test that relies on the picker containing results is potentially flakely * use crates.io version of nucleo * Fix typo in commands.rs Co-authored-by: Skyler Hawthorne <skyler@dead10ck.com> --------- Co-authored-by: Skyler Hawthorne <skyler@dead10ck.com>
Diffstat (limited to 'helix-core')
-rw-r--r--helix-core/Cargo.toml3
-rw-r--r--helix-core/src/fuzzy.rs43
-rw-r--r--helix-core/src/lib.rs1
3 files changed, 47 insertions, 0 deletions
diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml
index b434fbf3..515443e0 100644
--- a/helix-core/Cargo.toml
+++ b/helix-core/Cargo.toml
@@ -48,6 +48,9 @@ chrono = { version = "0.4", default-features = false, features = ["alloc", "std"
etcetera = "0.8"
textwrap = "0.16.0"
+nucleo.workspace = true
+parking_lot = "0.12"
+
[dev-dependencies]
quickcheck = { version = "1", default-features = false }
indoc = "2.0.3"
diff --git a/helix-core/src/fuzzy.rs b/helix-core/src/fuzzy.rs
new file mode 100644
index 00000000..e40a2d06
--- /dev/null
+++ b/helix-core/src/fuzzy.rs
@@ -0,0 +1,43 @@
+use std::ops::DerefMut;
+
+use nucleo::pattern::{AtomKind, CaseMatching, Pattern};
+use nucleo::Config;
+use parking_lot::Mutex;
+
+pub struct LazyMutex<T> {
+ inner: Mutex<Option<T>>,
+ init: fn() -> T,
+}
+
+impl<T> LazyMutex<T> {
+ pub const fn new(init: fn() -> T) -> Self {
+ Self {
+ inner: Mutex::new(None),
+ init,
+ }
+ }
+
+ pub fn lock(&self) -> impl DerefMut<Target = T> + '_ {
+ parking_lot::MutexGuard::map(self.inner.lock(), |val| val.get_or_insert_with(self.init))
+ }
+}
+
+pub static MATCHER: LazyMutex<nucleo::Matcher> = LazyMutex::new(nucleo::Matcher::default);
+
+/// convenience function to easily fuzzy match
+/// on a (relatively small list of inputs). This is not recommended for building a full tui
+/// application that can match large numbers of matches as all matching is done on the current
+/// thread, effectively blocking the UI
+pub fn fuzzy_match<T: AsRef<str>>(
+ pattern: &str,
+ items: impl IntoIterator<Item = T>,
+ path: bool,
+) -> Vec<(T, u32)> {
+ let mut matcher = MATCHER.lock();
+ matcher.config = Config::DEFAULT;
+ if path {
+ matcher.config.set_match_paths();
+ }
+ let pattern = Pattern::new(pattern, CaseMatching::Smart, AtomKind::Fuzzy);
+ pattern.match_list(items, &mut matcher)
+}
diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs
index 9a512eae..0acdb238 100644
--- a/helix-core/src/lib.rs
+++ b/helix-core/src/lib.rs
@@ -7,6 +7,7 @@ pub mod config;
pub mod diagnostic;
pub mod diff;
pub mod doc_formatter;
+pub mod fuzzy;
pub mod graphemes;
pub mod history;
pub mod increment;