From 6af26c335bd24d54e4cb5b7ad61984d7c2570780 Mon Sep 17 00:00:00 2001 From: Andrea Brancaleoni Date: Tue, 10 Nov 2015 19:50:35 +0100 Subject: [PATCH] dmenu: add fuzzymatch optional support --- srcpkgs/dmenu/files/fuzzymatch.patch | 147 +++++++++++++++++++++++++++ srcpkgs/dmenu/template | 11 ++ 2 files changed, 158 insertions(+) create mode 100644 srcpkgs/dmenu/files/fuzzymatch.patch diff --git a/srcpkgs/dmenu/files/fuzzymatch.patch b/srcpkgs/dmenu/files/fuzzymatch.patch new file mode 100644 index 00000000000..5216f8a2d7e --- /dev/null +++ b/srcpkgs/dmenu/files/fuzzymatch.patch @@ -0,0 +1,147 @@ +From 34e4ada60c7ca73cfdd83a02c7416af39dfc0dc0 Mon Sep 17 00:00:00 2001 +From: Andrea Brancaleoni +Date: Tue, 10 Nov 2015 19:29:45 +0100 +Subject: [PATCH] fuzzymatch-4.6 + +--- + dmenu.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 85 insertions(+), 4 deletions(-) + +diff --git a/dmenu.c b/dmenu.c +index a07f8e3..c26ecfc 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -32,6 +32,7 @@ struct item { + char *text; + struct item *left, *right; + int out; ++ int distance; + }; + + static char text[BUFSIZ] = ""; +@@ -253,6 +254,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) + { +@@ -263,7 +344,7 @@ insert(const char *str, ssize_t n) + if (n > 0) + memcpy(&text[cursor], str, n); + cursor += n; +- match(); ++ fuzzymatch(); + } + + static size_t +@@ -308,7 +389,7 @@ keypress(XKeyEvent *ev) + + case XK_k: /* delete right */ + text[cursor] = '\0'; +- match(); ++ fuzzymatch(); + break; + case XK_u: /* delete left */ + insert(NULL, 0 - cursor); +@@ -442,7 +523,7 @@ keypress(XKeyEvent *ev) + strncpy(text, sel->text, sizeof text - 1); + text[sizeof text - 1] = '\0'; + cursor = strlen(text); +- match(); ++ fuzzymatch(); + break; + } + drawmenu(); +@@ -584,7 +665,7 @@ setup(void) + } + promptw = (prompt && *prompt) ? TEXTW(prompt) : 0; + inputw = MIN(inputw, mw/3); +- match(); ++ fuzzymatch(); + + /* create menu window */ + swa.override_redirect = True; +-- +2.6.3 + diff --git a/srcpkgs/dmenu/template b/srcpkgs/dmenu/template index a83567382b9..4b9b8ef369f 100644 --- a/srcpkgs/dmenu/template +++ b/srcpkgs/dmenu/template @@ -10,6 +10,17 @@ homepage="http://tools.suckless.org/dmenu/" distfiles="http://dl.suckless.org/tools/${pkgname}-${version}.tar.gz" checksum=4a7a24008a621c3cd656155ad91ab8136db8f0d3b9ec56dafeec518cabda96b3 +build_options="fuzzymatch" +desc_option_fuzzymatch="Enable Fuzzymatch support" + +pre_build() { + local srcdir="${XBPS_SRCDISTDIR}/${pkgname}-${version}/" + if [ "$build_option_fuzzymatch" ]; then + msg_normal "Applying fuzzymatch patches" + patch -p1 < "${FILESDIR}/fuzzymatch.patch" + fi +} + do_build() { cp ${FILESDIR}/config.h config.h sed -i -e "s|^FREETYPEINC|#FREETYPEINC|g" \