From 0717b35fe32a2d42a6afb29593650fe84421160d Mon Sep 17 00:00:00 2001 From: mrsu Date: Thu, 27 Apr 2023 13:04:29 +0100 Subject: [PATCH] patch fuzzy find --- config.def.h | 1 + config.h | 1 + config.mk | 2 +- dmenu | Bin 42864 -> 43120 bytes dmenu.c | 89 ++++++++++++++++ dmenu.o | Bin 32432 -> 34592 bytes patches/dmenu-fuzzymatch-4.9.diff | 163 ++++++++++++++++++++++++++++++ stest | Bin 16408 -> 16408 bytes 8 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 patches/dmenu-fuzzymatch-4.9.diff diff --git a/config.def.h b/config.def.h index 0370c4a..8ddc0b3 100644 --- a/config.def.h +++ b/config.def.h @@ -2,6 +2,7 @@ /* Default settings; can be overriden by command line. */ static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ +static int fuzzy = 1; /* -F option; if 0, dmenu doesn't use fuzzy matching */ /* -fn option overrides fonts[0]; default X11 font or font set */ static const char *fonts[] = { "Hack Nerd Font:size=14", diff --git a/config.h b/config.h index 0370c4a..8ddc0b3 100644 --- a/config.h +++ b/config.h @@ -2,6 +2,7 @@ /* Default settings; can be overriden by command line. */ static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ +static int fuzzy = 1; /* -F option; if 0, dmenu doesn't use fuzzy matching */ /* -fn option overrides fonts[0]; default X11 font or font set */ static const char *fonts[] = { "Hack Nerd Font:size=14", diff --git a/config.mk b/config.mk index 566348b..fd6ff05 100644 --- a/config.mk +++ b/config.mk @@ -21,7 +21,7 @@ FREETYPEINC = /usr/include/freetype2 # includes and libs INCS = -I$(X11INC) -I$(FREETYPEINC) -LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) +LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lm # flags CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) diff --git a/dmenu b/dmenu index b7cdf6c038ee2b9bb3f593601c49dac1b62186dd..1b775aea0c3020064dee6bf2435f50005917ba7e 100755 GIT binary patch delta 13583 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 E0U^Xts{jB1 diff --git a/dmenu.c b/dmenu.c index 62f1089..486e4a9 100644 --- a/dmenu.c +++ b/dmenu.c @@ -1,6 +1,7 @@ /* See LICENSE file for copyright and license details. */ #include #include +#include #include #include #include @@ -32,6 +33,7 @@ struct item { char *text; struct item *left, *right; int out; + double distance; }; static char text[BUFSIZ] = ""; @@ -227,9 +229,94 @@ grabkeyboard(void) die("cannot grab keyboard"); } +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 ? 0 : da->distance < db->distance ? -1 : 1; +} + +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; /* pointer */ + sidx = eidx = -1; /* start of match, end of match */ + /* walk through item text */ + for (i = 0; i < itext_len && (c = it->text[i]); i++) { + /* fuzzy match pattern */ + if (!fstrncmp(&text[pidx], &c, 1)) { + if(sidx == -1) + sidx = i; + pidx++; + if (pidx == text_len) { + eidx = i; + break; + } + } + } + /* build list of matches */ + if (eidx != -1) { + /* compute distance */ + /* add penalty if match starts late (log(sidx+2)) + * add penalty for long a match without many matching characters */ + it->distance = log(sidx + 2) + (double)(eidx - sidx - text_len); + /* fprintf(stderr, "distance %s %f\n", it->text, it->distance); */ + 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 match(void) { + if (fuzzy) { + fuzzymatch(); + return; + } static char **tokv = NULL; static int tokn = 0; @@ -735,6 +822,8 @@ main(int argc, char *argv[]) topbar = 0; else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ fast = 1; + else if (!strcmp(argv[i], "-F")) /* grabs keyboard before reading stdin */ + fuzzy = 0; else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ fstrncmp = strncasecmp; fstrstr = cistrstr; diff --git a/dmenu.o b/dmenu.o index d6b3028a48c6810e78181352f4cfb89d439e1aa6..c53306dec3a76912b7c87d5018f2fb9597c03dbd 100644 GIT binary patch literal 34592 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 N&hY|gq`jH{e*iozJ|6%8 literal 32432 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 +Date: Wed, 26 Jun 2019 13:25:10 +0200 +Subject: [PATCH] Add support for fuzzy-matching + +--- + config.def.h | 1 + + config.mk | 2 +- + dmenu.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 91 insertions(+), 1 deletion(-) + +diff --git a/config.def.h b/config.def.h +index 1edb647..51612b9 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -2,6 +2,7 @@ + /* Default settings; can be overriden by command line. */ + + static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ ++static int fuzzy = 1; /* -F option; if 0, dmenu doesn't use fuzzy matching */ + /* -fn option overrides fonts[0]; default X11 font or font set */ + static const char *fonts[] = { + "monospace:size=10" +diff --git a/config.mk b/config.mk +index 0929b4a..d14309a 100644 +--- a/config.mk ++++ b/config.mk +@@ -20,7 +20,7 @@ FREETYPEINC = /usr/include/freetype2 + + # includes and libs + INCS = -I$(X11INC) -I$(FREETYPEINC) +-LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) ++LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lm + + # flags + CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) +diff --git a/dmenu.c b/dmenu.c +index 6b8f51b..96ddc98 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -1,6 +1,7 @@ + /* See LICENSE file for copyright and license details. */ + #include + #include ++#include + #include + #include + #include +@@ -32,6 +33,7 @@ struct item { + char *text; + struct item *left, *right; + int out; ++ double distance; + }; + + static char text[BUFSIZ] = ""; +@@ -210,9 +212,94 @@ grabkeyboard(void) + die("cannot grab keyboard"); + } + ++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 ? 0 : da->distance < db->distance ? -1 : 1; ++} ++ ++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; /* pointer */ ++ sidx = eidx = -1; /* start of match, end of match */ ++ /* walk through item text */ ++ for (i = 0; i < itext_len && (c = it->text[i]); i++) { ++ /* fuzzy match pattern */ ++ if (!fstrncmp(&text[pidx], &c, 1)) { ++ if(sidx == -1) ++ sidx = i; ++ pidx++; ++ if (pidx == text_len) { ++ eidx = i; ++ break; ++ } ++ } ++ } ++ /* build list of matches */ ++ if (eidx != -1) { ++ /* compute distance */ ++ /* add penalty if match starts late (log(sidx+2)) ++ * add penalty for long a match without many matching characters */ ++ it->distance = log(sidx + 2) + (double)(eidx - sidx - text_len); ++ /* fprintf(stderr, "distance %s %f\n", it->text, it->distance); */ ++ 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 + match(void) + { ++ if (fuzzy) { ++ fuzzymatch(); ++ return; ++ } + static char **tokv = NULL; + static int tokn = 0; + +@@ -702,6 +789,8 @@ main(int argc, char *argv[]) + topbar = 0; + else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ + fast = 1; ++ else if (!strcmp(argv[i], "-F")) /* grabs keyboard before reading stdin */ ++ fuzzy = 0; + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ + fstrncmp = strncasecmp; + fstrstr = cistrstr; +-- +2.22.0 + diff --git a/stest b/stest index 70beb89899a3280084496c57c189eac3870e7d98..2ea6c385cfc90d92adfefed5cbde772d25d60090 100755 GIT binary patch delta 458 zcmZ{hze~eV5XbM5+U5yDh2k%i;#36lYcaGnxCnMpadZ$ni4lwxad7fE83!@tM2a|c zakqUAcJf~k!NIMg-6{y7o3(iz9K7Z3bKLiSa5auKj^QgSjl#f6)sKsLuE)ULzg|;g zw&)xusf<(1Qe;N7(8Pa*T$XWS>RIOd?Q`L-xd9#a_)hD4t5*-vthiTi)a0RYd}J)q zV(P#{NI(t&((wRzs@^66M!=RiG2jF&OU`)S7=Q|El22wl2B5%JpMPz5ixwl4GjR|I z)S^@~&F3i8%S={7jyk%DoTiN|29!58afdFA-SM{6r(~Nh^^6s)Q{K#?Puu3T61vn- zCYshWVklbni`G}37EI<#iBFA!!|Iai^wp=Xq%PS-hYe@6MWq-a8*a|2;yNslKMAPe OI<)Vm(Gop3tNZ{-xLtDq delta 439 zcmY+AF-yZx6ov0is>u_C6iTaNZ3}`fO;QnxEf0%}qeCYr1&ffa4uUS4;vk(&xgu|H z$X{rqU|sYN2#)n1WVBQ5X4D4-4wASdz9xaX>9IJ5>^fybZFfvKBumd?%6Mh ze$X$y=~45tVzGv-G^krCGa*UPFrrXWNTq6-&3+7mv+4*bb{|1-K J=7TZMDZk3>UkU&K