Skip to content

Commit

Permalink
try using nucleo instead of skim
Browse files Browse the repository at this point in the history
  • Loading branch information
alexpasmantier committed Sep 25, 2024
1 parent 791ad72 commit a580b6f
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 102 deletions.
52 changes: 42 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 Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ crossterm = { version = "0.28.1", features = ["serde", "event-stream"] }
derive_deref = "1.1.1"
directories = "5.0.1"
futures = "0.3.30"
fuzzy-matcher = "0.3.7"
human-panic = "2.0.1"
ignore = "0.4.23"
json5 = "0.4.1"
lazy_static = "1.5.0"
libc = "0.2.158"
nucleo = "0.5.0"
pretty_assertions = "1.4.0"
ratatui = { version = "0.28.1", features = ["serde", "macros"] }
rust-devicons = "0.2.2"
Expand Down
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
## improvements
- [ ] async finder initialization
- [ ] async finder search
- [ ] use nucleo

## feature ideas
- [x] environment variables
Expand Down
2 changes: 1 addition & 1 deletion src/components/channels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl TvChannel {

pub async fn get_tv_channel(channel: UnitTvChannel) -> TvChannel {
match channel {
UnitTvChannel::ENV => TvChannel::Env(pickers::env::EnvVarPicker::new()),
UnitTvChannel::ENV => TvChannel::Env(pickers::env::EnvVarPicker::new().await),
UnitTvChannel::FILES => TvChannel::Files(pickers::files::FilePicker::new().await),
_ => unimplemented!(),
}
Expand Down
89 changes: 5 additions & 84 deletions src/components/finders/files.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use futures::{stream, StreamExt};
use nucleo::{Config, Nucleo};
use std::{
collections::HashMap,
path::{Path, PathBuf},
};

use fuzzy_matcher::skim::SkimMatcherV2;
use ignore::{types::TypesBuilder, WalkBuilder};
use tokio::sync::mpsc;
use tracing::info;
Expand All @@ -17,17 +17,18 @@ use crate::{
pub struct FileFinder {
current_directory: PathBuf,
files: Vec<PathBuf>,
matcher: SkimMatcherV2,
matcher: Nucleo,
cache: HashMap<String, Vec<Entry>>,
}

impl FileFinder {
pub async fn new() -> Self {
let matcher_config = Config::DEFAULT.match_paths();
let files = load_files(&std::env::current_dir().unwrap()).await;
FileFinder {
current_directory: std::env::current_dir().unwrap(),
files,
matcher: SkimMatcherV2::default(),
matcher: Nucleo::new(matcher_config, notify, num_threads, columns),
cache: HashMap::new(),
}
}
Expand All @@ -38,88 +39,8 @@ impl FileFinder {
const FUZZY_THRESHOLD: i64 = 2;

impl Finder for FileFinder {
//async fn find(&mut self, pattern: &str) -> impl Iterator<Item = Entry> {
// let mut results: Vec<Entry> = Vec::new();
// // try to get from cache
// if let Some(entries) = self.cache.get(pattern) {
// results.extend(entries.iter().cloned());
// } else {
// for file in &self.files {
// let rel_path = file.strip_prefix(&self.current_directory).unwrap();
// let rel_path_str = rel_path.to_string_lossy();
// if !pattern.is_empty() {
// if let Some((score, indices)) = self.matcher.fuzzy(&rel_path_str, pattern, true)
// {
// if score < FUZZY_THRESHOLD {
// continue;
// }
// results.push(Entry {
// name: rel_path_str.to_string(),
// display_name: None,
// preview: None,
// score,
// name_match_ranges: Some(indices.iter().map(|i| (*i, *i + 1)).collect()),
// preview_match_ranges: None,
// icon: None,
// line_number: None,
// });
// }
// }
// }
// self.cache.insert(pattern.to_string(), results.clone());
// }
// results.into_iter()
//}

async fn find(&mut self, pattern: &str) -> impl stream::Stream<Item = Entry> {
let mut results: Vec<Entry> = Vec::new();

// Try to get from cache asynchronously
if let Some(entries) = self.cache.get(pattern) {
results.extend(entries.iter().cloned());
} else {
let entries = stream::iter(self.files)
.filter_map(|file| {
let rel_path = file.strip_prefix(&self.current_directory).ok()?;
let rel_path_str = rel_path.to_string_lossy().to_string();
let matcher = self.matcher.clone(); // Clone matcher to use inside async tasks
let pattern = pattern.to_string(); // Clone pattern for async task

// Spawn async block for each file
async move {
if !pattern.is_empty() {
if let Some((score, indices)) =
matcher.fuzzy(&rel_path_str, &pattern, true)
{
if score >= FUZZY_THRESHOLD {
// If score is acceptable, return the Entry
return Some(Entry {
name: rel_path_str,
display_name: None,
preview: None,
score,
name_match_ranges: Some(
indices.iter().map(|i| (*i, *i + 1)).collect(),
),
preview_match_ranges: None,
icon: None,
line_number: None,
});
}
}
}
None
}
})
.buffer_unordered(10) // Limit concurrent tasks
.collect::<Vec<Option<Entry>>>()
.await;

results.extend(entries.into_iter().filter_map(|entry| entry));
self.cache.insert(pattern.to_string(), results.clone());
}

stream::iter(results) // Return the results as a Stream
self.matcher.fuzzy_match(haystack, needle)
}
}

Expand Down
9 changes: 3 additions & 6 deletions src/components/pickers/env.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use color_eyre::Result;
use tokio_stream::StreamExt;

use crate::components::finders::{self, Finder};
use crate::components::pickers::Picker;
Expand All @@ -13,7 +14,7 @@ pub struct EnvVarPicker {
impl EnvVarPicker {
pub async fn new() -> Self {
let mut finder = finders::EnvVarFinder::new();
let entries = finder.find("").await.collect::<Vec<finders::Entry>>();
let entries = finder.find("").await.collect().await;
EnvVarPicker {
finder,
entries,
Expand All @@ -27,11 +28,7 @@ impl Picker for EnvVarPicker {
type P = previewers::EnvVarPreviewer;

async fn load_entries(&mut self, pattern: &str) -> Result<()> {
self.entries = self
.finder
.find(pattern)
.await
.collect::<Vec<finders::Entry>>();
self.entries = self.finder.find(pattern).await.collect().await;
self.entries.sort_by_key(|e| -e.score);
Ok(())
}
Expand Down

0 comments on commit a580b6f

Please sign in to comment.