From 8e45592c5703451563eaf4edcd7033f80ce23b53 Mon Sep 17 00:00:00 2001 From: Phil Jones Date: Fri, 12 Aug 2022 23:14:32 +0100 Subject: Add --fuzzy_match option. This enables some simple fuzzy matching logic for searches. --- src/desktop_vec.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'src/desktop_vec.c') diff --git a/src/desktop_vec.c b/src/desktop_vec.c index f4363f8..5d63390 100644 --- a/src/desktop_vec.c +++ b/src/desktop_vec.c @@ -1,6 +1,7 @@ #include #include #include "desktop_vec.h" +#include "fuzzy_match.h" #include "log.h" #include "string_vec.h" #include "xmalloc.h" @@ -119,10 +120,10 @@ static int cmpscorep(const void *restrict a, const void *restrict b) { struct scored_string *restrict str1 = (struct scored_string *)a; struct scored_string *restrict str2 = (struct scored_string *)b; - if (str1->history_score != str2->history_score) { - return str2->history_score - str1->history_score; - } - return str1->search_score - str2->search_score; + + int hist_diff = str2->history_score - str1->history_score; + int search_diff = str2->search_score - str1->search_score; + return hist_diff + search_diff; } void desktop_vec_sort(struct desktop_vec *restrict vec) @@ -142,29 +143,49 @@ struct desktop_entry *desktop_vec_find(struct desktop_vec *restrict vec, const c struct string_vec desktop_vec_filter( const struct desktop_vec *restrict vec, - const char *restrict substr) + const char *restrict substr, + bool fuzzy) { struct string_vec filt = string_vec_create(); for (size_t i = 0; i < vec->count; i++) { - char *c = strcasestr(vec->buf[i].name, substr); - if (c != NULL) { + int32_t search_score; + if (fuzzy) { + search_score = fuzzy_match(substr, vec->buf[i].name); + } else { + char *c = strcasestr(vec->buf[i].name, substr); + if (c == NULL) { + search_score = INT32_MIN; + } else { + search_score = vec->buf[i].name - c; + } + } + if (search_score != INT32_MIN) { string_vec_add(&filt, vec->buf[i].name); /* * Store the position of the match in the string as * its search_score, for later sorting. */ - filt.buf[filt.count - 1].search_score = c - vec->buf[i].name; + filt.buf[filt.count - 1].search_score = search_score; filt.buf[filt.count - 1].history_score = vec->buf[i].history_score; } else { /* If we didn't match the name, check the keywords. */ - c = strcasestr(vec->buf[i].keywords, substr); - if (c != NULL) { + if (fuzzy) { + search_score = fuzzy_match(substr, vec->buf[i].keywords); + } else { + char *c = strcasestr(vec->buf[i].keywords, substr); + if (c == NULL) { + search_score = INT32_MIN; + } else { + search_score = vec->buf[i].keywords - c; + } + } + if (search_score != INT32_MIN) { string_vec_add(&filt, vec->buf[i].name); /* * Arbitrary score addition to make name * matches preferred over keyword matches. */ - filt.buf[filt.count - 1].search_score = 10 + c - vec->buf[i].keywords; + filt.buf[filt.count - 1].search_score = search_score - 20; filt.buf[filt.count - 1].history_score = vec->buf[i].history_score; } } -- cgit v1.2.3