---- - dmenu.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 83 insertions(+), 4 deletions(-) - -diff --git a/dmenu.c b/dmenu.c -index e0c2f80..b4a6f70 100644 ---- a/dmenu.c -+++ b/dmenu.c -_AT_@ -32,6 +32,7 @@ struct item { - char *text; - struct item *left, *right; - int out; -+ int distance; - }; - - static char text[BUFSIZ] = ""; -_AT_@ -253,6 +254,84 @@ match(void) - calcoffsets(); - } - -+static int -+compare_distance(const void *a, const void *b) -+{ -+ struct item const *da = *(struct item **) a; -+ struct item const *db = *(struct item **) b; -+ -+ if (!db) -+ return 1; -+ if (!da) -+ return -1; -+ return da->distance - db->distance; -+} -+ -+static void -+fuzzymatch(void) -+{ -+ struct item *item; -+ struct item **fuzzymatches = NULL; -+ char c; -+ int number_of_matches = 0, i, pidx, sidx, eidx; -+ int text_len = strlen(text), itext_len; -+ -+ matches = matchend = NULL; -+ -+ /* walk through all items */ -+ for (item = items; item && item->text; item++) { -+ if (text_len) { -+ itext_len = strlen(item->text); -+ pidx = 0; -+ sidx = eidx = -1; -+ /* walk through item text */ -+ for (i = 0; i < itext_len && (c = item->text[i]); i++) { -+ /* fuzzy match pattern */ -+ if (text[pidx] == c) { -+ if (sidx == -1) -+ sidx = i; -+ pidx++; -+ if (pidx == text_len) { -+ eidx = i; -+ break; -+ } -+ } -+ } -+ /* build list of matches */ -+ if (eidx != -1) { -+ /* compute distance */ -+ /* factor in 30% of sidx and distance between eidx and total -+ * text length .. let's see how it works */ -+ item->distance = eidx - sidx + (itext_len - eidx + sidx) / 3; -+ appenditem(item, &matches, &matchend); -+ number_of_matches++; -+ } -+ } -+ else -+ appenditem(item, &matches, &matchend); -+ } -+ -+ if (number_of_matches) { -+ /* initialize array with matches */ -+ if (!(fuzzymatches = realloc(fuzzymatches, number_of_matches * sizeof(struct item*)))) -+ die("cannot realloc %u bytes:", number_of_matches * sizeof(struct item *)); -+ for (i = 0, item = matches; item && i < number_of_matches; i++, item = item->right) -+ fuzzymatches[i] = item; -+ -+ /* sort matches according to distance */ -+ qsort(fuzzymatches, number_of_matches, sizeof(struct item *), compare_distance); -+ /* rebuild list of matches */ -+ matches = matchend = NULL; -+ for (i = 0, item = fuzzymatches[0]; i < number_of_matches && item && \ -+ item->text; item = fuzzymatches[i], i++) -+ appenditem(item, &matches, &matchend); -+ -+ free(fuzzymatches); -+ } -+ curr = sel = matches; -+ calcoffsets(); -+} -+ - static void - insert(const char *str, ssize_t n) - { -_AT_@ -263,7 +342,7 @@ insert(const char *str, ssize_t n) - if (n > 0) - memcpy(&text[cursor], str, n); - cursor += n; -- match(); -+ fuzzymatch(); - } - - static size_t -_AT_@ -308,7 +387,7 @@ keypress(XKeyEvent *ev) - - case XK_k: /* delete right */ - text[cursor] = 'Received on Sat Jul 02 2016 - 12:39:57 CEST
This archive was generated by hypermail 2.3.0 : Sat Jul 02 2016 - 12:48:14 CEST