summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhil Jones <philj56@gmail.com>2022-09-07 14:20:59 +0100
committerPhil Jones <philj56@gmail.com>2022-09-07 14:34:39 +0100
commitadc683b7fa847bc1776e3bece532c39aff12b039 (patch)
tree73e1550421a7833c5d9d843c7bcdf1a070fdc7ef /src
parente72f81799b1184d6b1b1bf8f70ec32d9cc139556 (diff)
Allow space-separated, per-word matches.
Diffstat (limited to 'src')
-rw-r--r--src/desktop_vec.c18
-rw-r--r--src/fuzzy_match.c51
-rw-r--r--src/fuzzy_match.h2
-rw-r--r--src/main.c2
-rw-r--r--src/string_vec.c9
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 */
diff --git a/src/main.c b/src/main.c
index fa4ca48..dae7e12 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);