feat: rank search results by match quality and launch frequency
Some checks failed
release / build (push) Failing after 34s

Track per-app launch counts in ~/.cache/breadbox/history.json. When a
query is active, sort visible results by fuzzy match quality (exact >
prefix > contains > subsequence) then by launch count descending, so
the most relevant and most-used app rises to the top. The base list
(no query) also surfaces most-launched apps above unvisited ones.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Breadway 2026-06-07 14:35:06 +08:00
parent 3ebadee4f4
commit d2549e56dd
6 changed files with 106 additions and 17 deletions

View file

@ -1,9 +1,10 @@
[package]
name = "breadbox-shared"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
license = "MIT"
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"
toml = "0.8"

View file

@ -1,4 +1,5 @@
use std::{
collections::HashMap,
env,
fs::{self, File},
io::{BufRead, BufReader},
@ -215,6 +216,38 @@ impl Default for IconCache {
}
}
// ---- Launch history ---------------------------------------------------------
pub struct LaunchHistory {
counts: HashMap<String, u32>,
path: PathBuf,
}
impl LaunchHistory {
pub fn load() -> Self {
let path = cache_dir().join("history.json");
let counts = fs::read_to_string(&path)
.ok()
.and_then(|s| serde_json::from_str(&s).ok())
.unwrap_or_default();
LaunchHistory { counts, path }
}
pub fn count(&self, name: &str) -> u32 {
self.counts.get(name).copied().unwrap_or(0)
}
pub fn increment(&mut self, name: &str) {
*self.counts.entry(name.to_string()).or_insert(0) += 1;
}
pub fn save(&self) {
if let Ok(json) = serde_json::to_string(&self.counts) {
let _ = fs::write(&self.path, json);
}
}
}
// ---- Config -----------------------------------------------------------------
#[derive(Debug, Clone, Serialize, Deserialize, Default)]