summaryrefslogtreecommitdiff
path: root/helix-core/src/fuzzy.rs
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/src/fuzzy.rs
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/src/fuzzy.rs')
-rw-r--r--helix-core/src/fuzzy.rs43
1 files changed, 43 insertions, 0 deletions
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)
+}