From 84080ff59f5cf93d63b064eab577ab1437466c8a Mon Sep 17 00:00:00 2001 From: dracarys18 Date: Tue, 18 Nov 2025 10:44:08 +0530 Subject: [PATCH 1/2] fix: prefer exact keyword match over score match --- src/db/mod.rs | 19 +++++++++++++++++++ src/db/stream.rs | 6 +++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/db/mod.rs b/src/db/mod.rs index d459f39..045f3ba 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -179,6 +179,25 @@ impl Database { self.with_dirty_mut(|dirty| *dirty = true); } + pub fn sort_by_keywords(&mut self, keywords: &[String]) { + if keywords.is_empty() { + return; + } + + self.with_dirs_mut(|dirs| { + dirs.sort_by_key(|dir| Self::has_exact_match(&dir.path, keywords)); + }); + self.with_dirty_mut(|dirty| *dirty = true); + } + + fn has_exact_match(path: &str, keywords: &[String]) -> bool { + keywords.last().map_or(false, |keyword| { + let path_lower = util::to_lowercase(path); + let last_component = path_lower.rsplit(std::path::is_separator).next().unwrap_or(""); + last_component == keyword + }) + } + pub fn dirty(&self) -> bool { *self.borrow_dirty() } diff --git a/src/db/stream.rs b/src/db/stream.rs index 4b06193..677ecad 100644 --- a/src/db/stream.rs +++ b/src/db/stream.rs @@ -16,7 +16,11 @@ pub struct Stream<'a> { impl<'a> Stream<'a> { pub fn new(db: &'a mut Database, options: StreamOptions) -> Self { - db.sort_by_score(options.now); + let now = options.now; + let keywords = &options.keywords; + + db.sort_by_score(now); + db.sort_by_keywords(keywords); let idxs = (0..db.dirs().len()).rev(); Stream { db, idxs, options } } From bce46a2295ca2d3c508e2c05e8b7e5e1142ba2b2 Mon Sep 17 00:00:00 2001 From: dracarys18 Date: Tue, 18 Nov 2025 11:18:06 +0530 Subject: [PATCH 2/2] chore: clippy --- src/db/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/mod.rs b/src/db/mod.rs index 045f3ba..526368a 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -191,7 +191,7 @@ impl Database { } fn has_exact_match(path: &str, keywords: &[String]) -> bool { - keywords.last().map_or(false, |keyword| { + keywords.last().is_some_and(|keyword| { let path_lower = util::to_lowercase(path); let last_component = path_lower.rsplit(std::path::is_separator).next().unwrap_or(""); last_component == keyword