commit bf855bf3633535109899c72365de7120cd4b28aa
parent 101b4f823dfba334524ef46990d60885e9bff477
Author: FRIGN <dev@frign.de>
Date: Tue, 20 Oct 2015 21:53:40 +0200
Update fuzzymatch patch
Reflecting recent changes in the codebase and using common practices.
Diffstat:
3 files changed, 144 insertions(+), 158 deletions(-)
diff --git a/tools.suckless.org/dmenu/patches/dmenu-git-20151020-fuzzymatch.diff b/tools.suckless.org/dmenu/patches/dmenu-git-20151020-fuzzymatch.diff
@@ -0,0 +1,135 @@
+diff --git a/dmenu.c b/dmenu.c
+index 4f22ffe..c2fc3ee 100644
+--- a/dmenu.c
++++ b/dmenu.c
+@@ -33,6 +33,7 @@ struct item {
+ char *text;
+ struct item *left, *right;
+ bool out;
++ int distance;
+ };
+
+ static char text[BUFSIZ] = "";
+@@ -254,6 +255,86 @@ match(void)
+ calcoffsets();
+ }
+
++int
++compare_distance(const void *a, const void *b)
++{
++ struct item *da = *(struct item **) a;
++ struct item *db = *(struct item **) b;
++
++ if (!db)
++ return 1;
++ if (!da)
++ return -1;
++
++ return da->distance - db->distance;
++}
++
++void
++fuzzymatch(void)
++{
++ /* bang - we have so much memory */
++ struct item *it;
++ 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 (it = items; it && it->text; it++) {
++ if (text_len) {
++ itext_len = strlen(it->text);
++ pidx = 0;
++ sidx = eidx = -1;
++ /* walk through item text */
++ for (i = 0; i < itext_len && (c = it->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 */
++ it->distance = eidx - sidx + (itext_len - eidx + sidx) / 3;
++ appenditem(it, &matches, &matchend);
++ number_of_matches++;
++ }
++ } else {
++ appenditem(it, &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, it = matches; it && i < number_of_matches; i++, it = it->right) {
++ fuzzymatches[i] = it;
++ }
++ /* 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, it = fuzzymatches[i]; i < number_of_matches && it && \
++ it->text; i++, it = fuzzymatches[i]) {
++ appenditem(it, &matches, &matchend);
++ }
++ free(fuzzymatches);
++ }
++ curr = sel = matches;
++ calcoffsets();
++}
++
+ static void
+ insert(const char *str, ssize_t n)
+ {
+@@ -264,7 +345,7 @@ insert(const char *str, ssize_t n)
+ if (n > 0)
+ memcpy(&text[cursor], str, n);
+ cursor += n;
+- match();
++ fuzzymatch();
+ }
+
+ static size_t
+@@ -309,7 +390,7 @@ keypress(XKeyEvent *ev)
+
+ case XK_k: /* delete right */
+ text[cursor] = '\0';
+- match();
++ fuzzymatch();
+ break;
+ case XK_u: /* delete left */
+ insert(NULL, 0 - cursor);
+@@ -443,7 +524,7 @@ keypress(XKeyEvent *ev)
+ strncpy(text, sel->text, sizeof text - 1);
+ text[sizeof text - 1] = '\0';
+ cursor = strlen(text);
+- match();
++ fuzzymatch();
+ break;
+ }
+ drawmenu();
+@@ -585,7 +666,7 @@ setup(void)
+ }
+ promptw = (prompt && *prompt) ? TEXTW(prompt) : 0;
+ inputw = MIN(inputw, mw/3);
+- match();
++ fuzzymatch();
+
+ /* create menu window */
+ swa.override_redirect = True;
diff --git a/tools.suckless.org/dmenu/patches/dmenu-git-fuzzymatch.diff b/tools.suckless.org/dmenu/patches/dmenu-git-fuzzymatch.diff
@@ -1,143 +0,0 @@
-Author: Jan Christoph Ebersbach <jceb@e-jc.de>
-URL: http://tools.suckless.org/dmenu/patches/fuzzymatch
-Add add fuzzy matching to dmenu
-
-Index: dmenu-patches/dmenu/dmenu.c
-===================================================================
---- dmenu-patches.orig/dmenu/dmenu.c
-+++ dmenu-patches/dmenu/dmenu.c
-@@ -23,12 +23,14 @@ struct Item {
- char *text;
- Item *left, *right;
- Bool out;
-+ int distance;
- };
-
- static void appenditem(Item *item, Item **list, Item **last);
- static void calcoffsets(void);
- static char *cistrstr(const char *s, const char *sub);
- static void drawmenu(void);
-+static void fuzzymatch(void);
- static void grabkeyboard(void);
- static void insert(const char *str, ssize_t n);
- static void keypress(XKeyEvent *ev);
-@@ -231,7 +233,7 @@ insert(const char *str, ssize_t n) {
- if(n > 0)
- memcpy(&text[cursor], str, n);
- cursor += n;
-- match();
-+ fuzzymatch();
- }
-
- void
-@@ -264,7 +266,7 @@ keypress(XKeyEvent *ev) {
-
- case XK_k: /* delete right */
- text[cursor] = '\0';
-- match();
-+ fuzzymatch();
- break;
- case XK_u: /* delete left */
- insert(NULL, 0 - cursor);
-@@ -393,7 +395,7 @@ keypress(XKeyEvent *ev) {
- strncpy(text, sel->text, sizeof text - 1);
- text[sizeof text - 1] = '\0';
- cursor = strlen(text);
-- match();
-+ fuzzymatch();
- break;
- }
- drawmenu();
-@@ -597,7 +599,7 @@ setup(void) {
- }
- promptw = (prompt && *prompt) ? textw(dc, prompt) : 0;
- inputw = MIN(inputw, mw/3);
-- match();
-+ fuzzymatch();
-
- /* create menu window */
- swa.override_redirect = True;
-Index: dmenu-patches/dmenu/fuzzymatch.c
-===================================================================
---- /dev/null
-+++ dmenu-patches/dmenu/fuzzymatch.c
-@@ -0,0 +1,79 @@
-+int
-+compare_distance(const void *a, const void *b) {
-+ Item const *da = *(Item **) a;
-+ Item const *db = *(Item **) b;
-+ if(!db)
-+ return 1;
-+ if(!da)
-+ return -1;
-+ return da->distance - db->distance;
-+}
-+
-+void
-+fuzzymatch(void) {
-+ /* bang - we have so much memory */
-+ Item *item;
-+ Item **fuzzymatches = NULL;
-+ char c;
-+ int number_of_matches = 0, i, pidx, sidx, eidx;
-+ int text_len = strlen(text), itext_len;
-+
-+ matches = matchend = NULL;
-+
-+ /* suppress compiler warning for unused match function */
-+ if(0)
-+ match();
-+
-+ /* 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(Item*))))
-+ eprintf("cannot realloc %u bytes:", number_of_matches * sizeof(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(Item*), compare_distance);
-+ /* rebuild list of matches */
-+ matches = matchend = NULL;
-+ for(i = 0, item = fuzzymatches[i]; i < number_of_matches && item && \
-+ item->text; i++, item = fuzzymatches[i]) {
-+ appenditem(item, &matches, &matchend);
-+ }
-+ free(fuzzymatches);
-+ }
-+ curr = sel = matches;
-+ calcoffsets();
-+}
diff --git a/tools.suckless.org/dmenu/patches/fuzzymatch.md b/tools.suckless.org/dmenu/patches/fuzzymatch.md
@@ -1,26 +1,20 @@
-Fuzzy matching support
-======================
+fuzzymatch
+==========
Description
-----------
-This patch adds support for fuzzy matching to dmenu. It allows you to type
-non-consecutive portions of the string you want to match.
-
-Usage
------
-
-* Apply patch and include `fuzzymatch.c` in `config.h`.
-
-`#include fuzzymatch.c`
+This patch adds support for fuzzy matching to dmenu, allowing users to type
+non-consecutive portions of the string to be matched.
Download
--------
-* [dmenu git](dmenu-git-fuzzymatch.diff) applies cleanly against 13a529ce63364544bdc851dfd5d3aa2ef8740914
-* [dmenu 4.5](dmenu-4.5-fuzzymatch.diff)
+* [dmenu-4.5-fuzzymatch.diff](dmenu-4.5-fuzzymatch.diff)
+* [dmenu-git-20151020-fuzzymatch.diff](dmenu-git-20151020-fuzzymatch.diff)
-History
+Authors
------
-Created by [Jan Christoph Ebersbach](https://github.com/jceb/dmenu-patches).
+* Jan Christoph Ebersbach - jceb@e-jc.de
+* Laslo Hunhold - dev@frign.de (st-git-20151020 port)