Skip to content

Commit b5514a6

Browse files
committed
feat(service): Improved search result sorting via Jaro-Winkler
1 parent 07b740a commit b5514a6

File tree

2 files changed

+35
-41
lines changed

2 files changed

+35
-41
lines changed

plugins/src/desktop_entries/mod.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,14 @@ pub async fn main() {
4141

4242
while let Some(result) = requests.next().await {
4343
match result {
44-
Ok(request) => {
45-
tracing::debug!("received request: {:?}", request);
46-
match request {
47-
Request::Activate(id) => app.activate(id).await,
48-
Request::ActivateContext { id, context } => {
49-
app.activate_context(id, context).await
50-
}
51-
Request::Context(id) => app.context(id).await,
52-
Request::Search(query) => app.search(&query).await,
53-
Request::Exit => break,
54-
_ => (),
55-
}
56-
}
44+
Ok(request) => match request {
45+
Request::Activate(id) => app.activate(id).await,
46+
Request::ActivateContext { id, context } => app.activate_context(id, context).await,
47+
Request::Context(id) => app.context(id).await,
48+
Request::Search(query) => app.search(&query).await,
49+
Request::Exit => break,
50+
_ => (),
51+
},
5752

5853
Err(why) => {
5954
tracing::error!("malformed JSON request: {}", why);
@@ -231,7 +226,7 @@ impl<W: AsyncWrite + Unpin> App<W> {
231226
|| query
232227
.split_ascii_whitespace()
233228
.any(|query| search_interest.contains(&*query))
234-
|| strsim::damerau_levenshtein(&*query, &*search_interest) < 3;
229+
|| strsim::jaro_winkler(&*query, &*search_interest) > 0.6;
235230

236231
if append {
237232
let desc_source = path_string(&entry.src);

service/src/lib.rs

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -422,8 +422,9 @@ impl<O: futures::Sink<Response> + Unpin> Service<O> {
422422
*no_sort = false;
423423
} else {
424424
active_search.sort_by(|a, b| {
425-
fn calculate_weight(meta: &PluginSearchResult, query: &str) -> usize {
426-
let mut weight = 0;
425+
// Weight is calculated between 0.0 and 1.0, with higher values being most similar
426+
fn calculate_weight(meta: &PluginSearchResult, query: &str) -> f64 {
427+
let mut weight: f64 = 0.0;
427428

428429
let name = meta.name.to_ascii_lowercase();
429430
let description = meta.description.to_ascii_lowercase();
@@ -433,50 +434,48 @@ impl<O: futures::Sink<Response> + Unpin> Service<O> {
433434
.map(|exec| exec.to_ascii_lowercase())
434435
.unwrap_or_default();
435436

436-
if !name.starts_with(query) {
437-
weight = 1;
438-
439-
if !name.contains(query) {
440-
weight = strsim::damerau_levenshtein(&name, query)
441-
.min(strsim::damerau_levenshtein(&description, query));
442-
443-
if let Some(keywords) = meta.keywords.as_ref() {
444-
for keyword in keywords.iter() {
445-
let keyword = keyword.to_ascii_lowercase();
446-
weight = if keyword.starts_with(query)
447-
|| keyword.contains(query)
448-
{
449-
1
450-
} else {
451-
weight.min(strsim::damerau_levenshtein(query, &keyword) + 1)
452-
}
453-
}
454-
}
437+
for name in name.split_ascii_whitespace() {
438+
if name.starts_with(query) {
439+
return 1.0;
455440
}
456441
}
457442

458443
if exec.contains(query) {
459-
weight = if exec.starts_with(query) {
460-
weight.min(2)
444+
if exec.starts_with(query) {
445+
return 1.0;
461446
} else {
462-
weight.min(strsim::damerau_levenshtein(query, &exec))
447+
weight = strsim::jaro_winkler(query, &exec) - 0.1;
463448
}
464449
}
465450

466451
weight
452+
.max(strsim::jaro_winkler(&name, query))
453+
.max(strsim::jaro_winkler(&description, query) - 0.1)
454+
.max(match meta.keywords.as_ref() {
455+
Some(keywords) => keywords
456+
.iter()
457+
.flat_map(|word| word.split_ascii_whitespace())
458+
.fold(0.0, |acc, keyword| {
459+
let keyword = keyword.to_ascii_lowercase();
460+
acc.max(strsim::jaro_winkler(query, &keyword) - 0.1)
461+
}),
462+
None => 0.0,
463+
})
467464
}
468465

469466
let a_weight = calculate_weight(&a.1, query);
470467
let b_weight = calculate_weight(&b.1, query);
471468

472-
match a_weight.cmp(&b_weight) {
473-
Ordering::Equal => {
469+
match a_weight.partial_cmp(&b_weight) {
470+
Some(Ordering::Equal) => {
474471
let a_len = a.1.name.len();
475472
let b_len = b.1.name.len();
476473

477474
a_len.cmp(&b_len)
478475
}
479-
other => other,
476+
Some(Ordering::Less) => Ordering::Greater,
477+
Some(Ordering::Greater) => Ordering::Less,
478+
None => Ordering::Greater,
480479
}
481480
});
482481

0 commit comments

Comments
 (0)