Skip to content

Commit

Permalink
refactor: replace skim with nucleo
Browse files Browse the repository at this point in the history
  • Loading branch information
amrbashir committed Jan 30, 2025
1 parent c03558d commit 21bb1cc
Show file tree
Hide file tree
Showing 18 changed files with 78 additions and 73 deletions.
21 changes: 11 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion kal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ serde_json = "1"
toml = "0.8"
rust-embed = "8.1"
serialize-to-javascript = "0.1"
fuzzy-matcher = "0.3"
nucleo-matcher = "0.3"
dirs = "5.0"
percent-encoding = "2.3"
dunce = "1"
Expand Down
16 changes: 16 additions & 0 deletions kal/src/fuzzy_matcher.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#[derive(Default)]
pub struct Matcher {
inner: nucleo_matcher::Matcher,
}

impl Matcher {
pub fn fuzzy_match(&mut self, haystack: &str, needle: &str) -> Option<u16> {
let mut haystack_buf = Vec::new();
let mut needle_buf = Vec::new();

let haystack = nucleo_matcher::Utf32Str::new(haystack, &mut haystack_buf);
let needle = nucleo_matcher::Utf32Str::new(needle, &mut needle_buf);

self.inner.fuzzy_match(haystack, needle)
}
}
1 change: 1 addition & 0 deletions kal/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mod app;
mod config;
#[cfg(not(debug_assertions))]
mod embedded_assets;
mod fuzzy_matcher;
mod icon;
mod ipc;
mod main_window;
Expand Down
10 changes: 6 additions & 4 deletions kal/src/main_window.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::sync::{mpsc, Arc};

use fuzzy_matcher::skim::SkimMatcherV2;
use global_hotkey::hotkey::HotKey;
use serialize_to_javascript::{Options as JsSerializeOptions, Template as JsTemplate};
use smol::lock::RwLock;
Expand Down Expand Up @@ -112,7 +111,7 @@ pub struct MainWindowState {
main_thread_sender: mpsc::Sender<AppMessage>,
event_loop_proxy: EventLoopProxy,

fuzzy_matcher: SkimMatcherV2,
fuzzy_matcher: RwLock<crate::fuzzy_matcher::Matcher>,

config: RwLock<Config>,
plugin_store: RwLock<PluginStore>,
Expand Down Expand Up @@ -140,7 +139,7 @@ impl MainWindowState {
Self {
main_thread_sender,
event_loop_proxy,
fuzzy_matcher: SkimMatcherV2::default(),
fuzzy_matcher: RwLock::new(crate::fuzzy_matcher::Matcher::default()),
config: RwLock::new(config),
plugin_store: RwLock::new(plugin_store),
results: RwLock::new(Vec::with_capacity(max_results)),
Expand Down Expand Up @@ -232,9 +231,12 @@ impl MainWindowState {

let mut results = Vec::new();

// it is fine to block here since only one query can be processed at a time
let mut plugins_store = self.plugin_store.write().await;
let mut fuzzy_matcher = self.fuzzy_matcher.write().await;

plugins_store
.query(query, &self.fuzzy_matcher, &mut results)
.query(query, &mut fuzzy_matcher, &mut results)
.await?;

// sort results in reverse so higher scores are first
Expand Down
6 changes: 2 additions & 4 deletions kal/src/plugin.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use fuzzy_matcher::skim::SkimMatcherV2;

use crate::config::{Config, GenericPluginConfig};
use crate::icon::BuiltinIcon;
use crate::result_item::ResultItem;
Expand Down Expand Up @@ -49,7 +47,7 @@ pub trait Plugin: std::fmt::Debug + Send + Sync {
async fn query(
&mut self,
query: &str,
matcher: &SkimMatcherV2,
matcher: &mut crate::fuzzy_matcher::Matcher,
) -> anyhow::Result<PluginQueryOutput> {
Ok(PluginQueryOutput::None)
}
Expand All @@ -58,7 +56,7 @@ pub trait Plugin: std::fmt::Debug + Send + Sync {
async fn query_direct(
&mut self,
query: &str,
matcher: &SkimMatcherV2,
matcher: &mut crate::fuzzy_matcher::Matcher,
) -> anyhow::Result<PluginQueryOutput> {
self.query(query, matcher).await
}
Expand Down
17 changes: 6 additions & 11 deletions kal/src/plugin_store.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use std::ops::{Deref, DerefMut};

use fuzzy_matcher::skim::SkimMatcherV2;
use smol::prelude::*;

use crate::config::Config;
use crate::plugin::Plugin;
use crate::result_item::ResultItem;
Expand Down Expand Up @@ -101,7 +98,7 @@ impl PluginStore {
pub async fn query(
&mut self,
query: &str,
matcher: &SkimMatcherV2,
matcher: &mut crate::fuzzy_matcher::Matcher,
results: &mut Vec<ResultItem>,
) -> anyhow::Result<()> {
// check if a plugin is being invoked directly
Expand All @@ -116,15 +113,13 @@ impl PluginStore {
} else {
let trimmed_query = query.trim();

// otherwise get result from all queriable plugins
let mut results_iter = smol::stream::iter(self.queriable_plugins()).map(|p| async {
p.query(trimmed_query, matcher)
for plugin in self.queriable_plugins() {
let result = plugin
.query(trimmed_query, matcher)
.await
.map_err(|e| p.error_item(e.to_string()))
});
.map_err(|e| plugin.error_item(e.to_string()));

while let Some(r) = results_iter.next().await {
match r.await {
match result {
Ok(r) => r.extend_into(results),
Err(r) => results.push(r),
}
Expand Down
5 changes: 2 additions & 3 deletions kal/src/plugins/app_launcher/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::path::Path;
use std::sync::{Arc, Mutex};

use fuzzy_matcher::skim::SkimMatcherV2;
use notify::RecommendedWatcher;
use notify_debouncer_mini::Debouncer;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -111,7 +110,7 @@ impl crate::plugin::Plugin for Plugin {
async fn query(
&mut self,
query: &str,
matcher: &SkimMatcherV2,
matcher: &mut crate::fuzzy_matcher::Matcher,
) -> anyhow::Result<PluginQueryOutput> {
if query.is_empty() {
return Ok(PluginQueryOutput::None);
Expand Down Expand Up @@ -152,7 +151,7 @@ impl App {
}

impl IntoResultItem for App {
fn fuzzy_match(&self, query: &str, matcher: &SkimMatcherV2) -> Option<ResultItem> {
fn fuzzy_match(&self, query: &str, matcher: &mut crate::fuzzy_matcher::Matcher) -> Option<ResultItem> {
match self {
App::Program(program) => program.fuzzy_match(query, matcher),
#[cfg(windows)]
Expand Down
6 changes: 2 additions & 4 deletions kal/src/plugins/app_launcher/packaged_app.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use std::ffi::OsString;
use std::path::PathBuf;

use fuzzy_matcher::skim::SkimMatcherV2;
use fuzzy_matcher::FuzzyMatcher;
use windows::core::{w, HSTRING, PCWSTR};
use windows::ApplicationModel::{
Package, PackageCatalog, PackageInstallingEventArgs, PackageUninstallingEventArgs,
Expand Down Expand Up @@ -53,7 +51,7 @@ pub struct PackagedApp {
}

impl PackagedApp {
fn item(&self, args: &str, score: i64) -> ResultItem {
fn item(&self, args: &str, score: u16) -> ResultItem {
let icon = self
.icon
.as_ref()
Expand Down Expand Up @@ -92,7 +90,7 @@ impl PackagedApp {
}

impl IntoResultItem for PackagedApp {
fn fuzzy_match(&self, query: &str, matcher: &SkimMatcherV2) -> Option<ResultItem> {
fn fuzzy_match(&self, query: &str, matcher: &mut crate::fuzzy_matcher::Matcher) -> Option<ResultItem> {
let (query, args) = query.split_args().unwrap_or((query, ""));

matcher
Expand Down
6 changes: 2 additions & 4 deletions kal/src/plugins/app_launcher/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ use std::ffi::{OsStr, OsString};
use std::path::{Path, PathBuf};
use std::time::Duration;

use fuzzy_matcher::skim::SkimMatcherV2;
use fuzzy_matcher::FuzzyMatcher;
use smol::prelude::*;

use super::App;
Expand Down Expand Up @@ -42,7 +40,7 @@ impl Program {
}
}

fn item(&self, args: &str, score: i64) -> ResultItem {
fn item(&self, args: &str, score: u16) -> ResultItem {
let path = self.path.clone();
let args_ = args.to_string();
let open = Action::primary(move |_| utils::execute_with_args(&path, &args_, false, false));
Expand Down Expand Up @@ -70,7 +68,7 @@ impl Program {
}

impl IntoResultItem for Program {
fn fuzzy_match(&self, query: &str, matcher: &SkimMatcherV2) -> Option<ResultItem> {
fn fuzzy_match(&self, query: &str, matcher: &mut crate::fuzzy_matcher::Matcher) -> Option<ResultItem> {
let (query, args) = query.split_args().unwrap_or((query, ""));

matcher
Expand Down
2 changes: 1 addition & 1 deletion kal/src/plugins/calculator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl crate::plugin::Plugin for Plugin {
async fn query(
&mut self,
query: &str,
_matcher: &fuzzy_matcher::skim::SkimMatcherV2,
_matcher: &mut crate::fuzzy_matcher::Matcher,
) -> anyhow::Result<PluginQueryOutput> {
if !query.starts_with(|c: char| c.is_ascii_digit()) {
return Ok(PluginQueryOutput::None);
Expand Down
10 changes: 5 additions & 5 deletions kal/src/plugins/directory_indexer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::ffi::OsString;
use std::path::{Path, PathBuf};

use fuzzy_matcher::skim::SkimMatcherV2;
use fuzzy_matcher::FuzzyMatcher;


use serde::{Deserialize, Serialize};
use smol::stream::*;

Expand Down Expand Up @@ -71,7 +71,7 @@ impl crate::plugin::Plugin for Plugin {
async fn query(
&mut self,
query: &str,
matcher: &SkimMatcherV2,
matcher: &mut crate::fuzzy_matcher::Matcher,
) -> anyhow::Result<PluginQueryOutput> {
Ok(self
.entries
Expand Down Expand Up @@ -104,7 +104,7 @@ impl DirEntry {
}
}

fn item(&self, score: i64) -> ResultItem {
fn item(&self, score: u16) -> ResultItem {
let actions = if self.is_dir {
vec![
{
Expand Down Expand Up @@ -146,7 +146,7 @@ impl DirEntry {
}

impl IntoResultItem for DirEntry {
fn fuzzy_match(&self, query: &str, matcher: &SkimMatcherV2) -> Option<ResultItem> {
fn fuzzy_match(&self, query: &str, matcher: &mut crate::fuzzy_matcher::Matcher) -> Option<ResultItem> {
matcher
.fuzzy_match(&self.name.to_string_lossy(), query)
.or_else(|| matcher.fuzzy_match(&self.path.to_string_lossy(), query))
Expand Down
6 changes: 3 additions & 3 deletions kal/src/plugins/everything/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::ffi::OsString;
use std::path::PathBuf;

use fuzzy_matcher::skim::SkimMatcherV2;

use serde::{Deserialize, Serialize};

use crate::config::{Config, GenericPluginConfig};
Expand Down Expand Up @@ -59,7 +59,7 @@ impl crate::plugin::Plugin for Plugin {
async fn query_direct(
&mut self,
query: &str,
matcher: &SkimMatcherV2,
matcher: &mut crate::fuzzy_matcher::Matcher,
) -> anyhow::Result<PluginQueryOutput> {
if query.is_empty() {
return Ok(PluginQueryOutput::None);
Expand Down Expand Up @@ -115,7 +115,7 @@ impl EverythingEntry {
}

impl IntoResultItem for EverythingEntry {
fn fuzzy_match(&self, _query: &str, _matcher: &SkimMatcherV2) -> Option<ResultItem> {
fn fuzzy_match(&self, _query: &str, _matcher: &mut crate::fuzzy_matcher::Matcher) -> Option<ResultItem> {
let actions = if self.is_dir {
vec![
{
Expand Down
2 changes: 1 addition & 1 deletion kal/src/plugins/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl crate::plugin::Plugin for Plugin {
async fn query_direct(
&mut self,
query: &str,
_matcher: &fuzzy_matcher::skim::SkimMatcherV2,
_matcher: &mut crate::fuzzy_matcher::Matcher,
) -> anyhow::Result<PluginQueryOutput> {
Ok(self.shell.item(query.to_string(), self.no_exit).into())
}
Expand Down
12 changes: 5 additions & 7 deletions kal/src/plugins/system_commands/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use fuzzy_matcher::skim::SkimMatcherV2;
use fuzzy_matcher::FuzzyMatcher;
use strum::AsRefStr;

use crate::config::{Config, GenericPluginConfig};
Expand All @@ -23,7 +21,7 @@ impl Plugin {
.collect_non_empty()
}

fn all_for_query(&self, query: &str, matcher: &SkimMatcherV2) -> Option<Vec<ResultItem>> {
fn all_for_query(&self, query: &str, matcher: &mut crate::fuzzy_matcher::Matcher) -> Option<Vec<ResultItem>> {
self.commands
.iter()
.filter_map(|workflow| workflow.fuzzy_match(query, matcher))
Expand Down Expand Up @@ -58,15 +56,15 @@ impl crate::plugin::Plugin for Plugin {
async fn query(
&mut self,
query: &str,
matcher: &fuzzy_matcher::skim::SkimMatcherV2,
matcher: &mut crate::fuzzy_matcher::Matcher,
) -> anyhow::Result<PluginQueryOutput> {
Ok(self.all_for_query(query, matcher).into())
}

async fn query_direct(
&mut self,
query: &str,
matcher: &fuzzy_matcher::skim::SkimMatcherV2,
matcher: &mut crate::fuzzy_matcher::Matcher,
) -> anyhow::Result<PluginQueryOutput> {
if query.is_empty() {
Ok(self.all().into())
Expand Down Expand Up @@ -203,7 +201,7 @@ impl SystemCommand {
unimplemented!()
}

fn item(&self, score: i64) -> ResultItem {
fn item(&self, score: u16) -> ResultItem {
let system_command = *self;
ResultItem {
id: self.id().into(),
Expand All @@ -218,7 +216,7 @@ impl SystemCommand {
}

impl IntoResultItem for SystemCommand {
fn fuzzy_match(&self, query: &str, matcher: &SkimMatcherV2) -> Option<ResultItem> {
fn fuzzy_match(&self, query: &str, matcher: &mut crate::fuzzy_matcher::Matcher) -> Option<ResultItem> {
matcher
.fuzzy_match(self.as_ref(), query)
.map(|score| self.item(score))
Expand Down
Loading

0 comments on commit 21bb1cc

Please sign in to comment.