diff options
author | Phil Jones <philj56@gmail.com> | 2022-09-07 14:20:59 +0100 |
---|---|---|
committer | Phil Jones <philj56@gmail.com> | 2022-09-07 14:34:39 +0100 |
commit | adc683b7fa847bc1776e3bece532c39aff12b039 (patch) | |
tree | 73e1550421a7833c5d9d843c7bcdf1a070fdc7ef /src | |
parent | e72f81799b1184d6b1b1bf8f70ec32d9cc139556 (diff) |
Allow space-separated, per-word matches.
Diffstat (limited to 'src')
-rw-r--r-- | src/desktop_vec.c | 18 | ||||
-rw-r--r-- | src/fuzzy_match.c | 51 | ||||
-rw-r--r-- | src/fuzzy_match.h | 2 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/string_vec.c | 9 |
5 files changed, 60 insertions, 22 deletions
diff --git a/src/desktop_vec.c b/src/desktop_vec.c index 5d63390..df4218b 100644 --- a/src/desktop_vec.c +++ b/src/desktop_vec.c @@ -150,14 +150,9 @@ struct string_vec desktop_vec_filter( for (size_t i = 0; i < vec->count; i++) { int32_t search_score; if (fuzzy) { - search_score = fuzzy_match(substr, vec->buf[i].name); + search_score = fuzzy_match_words(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; - } + search_score = fuzzy_match_simple_words(substr, vec->buf[i].name); } if (search_score != INT32_MIN) { string_vec_add(&filt, vec->buf[i].name); @@ -170,14 +165,9 @@ struct string_vec desktop_vec_filter( } else { /* If we didn't match the name, check the keywords. */ if (fuzzy) { - search_score = fuzzy_match(substr, vec->buf[i].keywords); + search_score = fuzzy_match_words(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; - } + search_score = fuzzy_match_simple_words(substr, vec->buf[i].keywords); } if (search_score != INT32_MIN) { string_vec_add(&filt, vec->buf[i].name); diff --git a/src/fuzzy_match.c b/src/fuzzy_match.c index a8489e5..94c60e8 100644 --- a/src/fuzzy_match.c +++ b/src/fuzzy_match.c @@ -5,6 +5,7 @@ #include <string.h> #include "fuzzy_match.h" +#include "xmalloc.h" #undef MAX #define MAX(a, b) ((a) > (b) ? (a) : (b)) @@ -21,6 +22,56 @@ static int32_t fuzzy_match_recurse( bool first_char); /* + * Split patterns into words, and perform simple matching against str for each. + * Returns the sum of substring distances from the start of str. + * If a word is not found, returns INT32_MIN. + */ +int32_t fuzzy_match_simple_words(const char *restrict patterns, const char *restrict str) +{ + int32_t score = 0; + char *saveptr = NULL; + char *tmp = xstrdup(patterns); + char *pattern = strtok_r(tmp, " ", &saveptr); + while (pattern != NULL) { + char *c = strcasestr(str, pattern); + if (c == NULL) { + score = INT32_MIN; + break; + } else { + score += str - c; + } + pattern = strtok_r(NULL, " ", &saveptr); + } + free(tmp); + return score; +} + + +/* + * Split patterns into words, and return the sum of fuzzy_match(word, str). + * If a word is not found, returns INT32_MIN. + */ +int32_t fuzzy_match_words(const char *restrict patterns, const char *restrict str) +{ + int32_t score = 0; + char *saveptr = NULL; + char *tmp = xstrdup(patterns); + char *pattern = strtok_r(tmp, " ", &saveptr); + while (pattern != NULL) { + int32_t word_score = fuzzy_match(pattern, str); + if (word_score == INT32_MIN) { + score = INT32_MIN; + break; + } else { + score += word_score; + } + pattern = strtok_r(NULL, " ", &saveptr); + } + free(tmp); + return score; +} + +/* * Returns score if each character in pattern is found sequentially within str. * Returns INT32_MIN otherwise. */ diff --git a/src/fuzzy_match.h b/src/fuzzy_match.h index df4d298..d427bc6 100644 --- a/src/fuzzy_match.h +++ b/src/fuzzy_match.h @@ -3,6 +3,8 @@ #include <stdint.h> +int32_t fuzzy_match_simple_words(const char *restrict patterns, const char *restrict str); +int32_t fuzzy_match_words(const char *restrict patterns, const char *restrict str); int32_t fuzzy_match(const char *restrict pattern, const char *restrict str); #endif /* FUZZY_MATCH_H */ @@ -158,7 +158,7 @@ static void handle_keypress(struct tofi *tofi, xkb_keycode_t keycode) sizeof(buf)); wchar_t ch; mbtowc(&ch, buf, sizeof(buf)); - if (len > 0 && iswprint(ch) && (entry->drun || !iswblank(ch))) { + if (len > 0 && iswprint(ch)) { if (entry->input_length < N_ELEM(entry->input) - 1) { entry->input[entry->input_length] = ch; entry->input_length++; diff --git a/src/string_vec.c b/src/string_vec.c index 464c450..50dd813 100644 --- a/src/string_vec.c +++ b/src/string_vec.c @@ -122,14 +122,9 @@ struct string_vec string_vec_filter( for (size_t i = 0; i < vec->count; i++) { int32_t search_score; if (fuzzy) { - search_score = fuzzy_match(substr, vec->buf[i].string); + search_score = fuzzy_match_words(substr, vec->buf[i].string); } else { - char *c = strcasestr(vec->buf[i].string, substr); - if (c == NULL) { - search_score = INT32_MIN; - } else { - search_score = vec->buf[i].string - c; - } + search_score = fuzzy_match_simple_words(substr, vec->buf[i].string); } if (search_score != INT32_MIN) { string_vec_add(&filt, vec->buf[i].string); |