----
- 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