| dmenu-fuzzymatch-5.3.diff - sites - public wiki contents of suckless.org | |
| git clone git://git.suckless.org/sites | |
| Log | |
| Files | |
| Refs | |
| --- | |
| dmenu-fuzzymatch-5.3.diff (5690B) | |
| --- | |
| 1 From d166c2c90f777f5a80f628d493cdcf7bf03034b8 Mon Sep 17 00:00:00 2001 | |
| 2 From: Justinas Grigas <[email protected]> | |
| 3 Date: Mon, 17 Jun 2024 02:52:15 +0100 | |
| 4 Subject: [PATCH] fuzzymatch: Add support for fuzzy-matching | |
| 5 | |
| 6 This version of the patch updates the manpage. | |
| 7 --- | |
| 8 config.def.h | 1 + | |
| 9 config.mk | 2 +- | |
| 10 dmenu.1 | 5 ++- | |
| 11 dmenu.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++- | |
| 12 4 files changed, 95 insertions(+), 3 deletions(-) | |
| 13 | |
| 14 diff --git a/config.def.h b/config.def.h | |
| 15 index 1edb647..a4e6174 100644 | |
| 16 --- a/config.def.h | |
| 17 +++ b/config.def.h | |
| 18 @@ -2,6 +2,7 @@ | |
| 19 /* Default settings; can be overriden by command line. */ | |
| 20 | |
| 21 static int topbar = 1; /* -b option; if 0, dmenu … | |
| 22 +static int fuzzy = 1; /* -F option; if 0, dmenu … | |
| 23 /* -fn option overrides fonts[0]; default X11 font or font set */ | |
| 24 static const char *fonts[] = { | |
| 25 "monospace:size=10" | |
| 26 diff --git a/config.mk b/config.mk | |
| 27 index 137f7c8..6a19175 100644 | |
| 28 --- a/config.mk | |
| 29 +++ b/config.mk | |
| 30 @@ -21,7 +21,7 @@ FREETYPEINC = /usr/include/freetype2 | |
| 31 | |
| 32 # includes and libs | |
| 33 INCS = -I$(X11INC) -I$(FREETYPEINC) | |
| 34 -LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) | |
| 35 +LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lm | |
| 36 | |
| 37 # flags | |
| 38 CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX… | |
| 39 diff --git a/dmenu.1 b/dmenu.1 | |
| 40 index 323f93c..e2c5ef4 100644 | |
| 41 --- a/dmenu.1 | |
| 42 +++ b/dmenu.1 | |
| 43 @@ -3,7 +3,7 @@ | |
| 44 dmenu \- dynamic menu | |
| 45 .SH SYNOPSIS | |
| 46 .B dmenu | |
| 47 -.RB [ \-bfiv ] | |
| 48 +.RB [ \-bFfiv ] | |
| 49 .RB [ \-l | |
| 50 .IR lines ] | |
| 51 .RB [ \-m | |
| 52 @@ -40,6 +40,9 @@ which lists programs in the user's $PATH and runs the … | |
| 53 .B \-b | |
| 54 dmenu appears at the bottom of the screen. | |
| 55 .TP | |
| 56 +.B \-F | |
| 57 +disables fuzzy matching. | |
| 58 +.TP | |
| 59 .B \-f | |
| 60 dmenu grabs the keyboard before reading stdin if not reading from a tty… | |
| 61 is faster, but will lock up X until stdin reaches end\-of\-file. | |
| 62 diff --git a/dmenu.c b/dmenu.c | |
| 63 index 40f93e0..03e1f45 100644 | |
| 64 --- a/dmenu.c | |
| 65 +++ b/dmenu.c | |
| 66 @@ -1,6 +1,7 @@ | |
| 67 /* See LICENSE file for copyright and license details. */ | |
| 68 #include <ctype.h> | |
| 69 #include <locale.h> | |
| 70 +#include <math.h> | |
| 71 #include <stdio.h> | |
| 72 #include <stdlib.h> | |
| 73 #include <string.h> | |
| 74 @@ -31,6 +32,7 @@ struct item { | |
| 75 char *text; | |
| 76 struct item *left, *right; | |
| 77 int out; | |
| 78 + double distance; | |
| 79 }; | |
| 80 | |
| 81 static char text[BUFSIZ] = ""; | |
| 82 @@ -226,9 +228,93 @@ grabkeyboard(void) | |
| 83 die("cannot grab keyboard"); | |
| 84 } | |
| 85 | |
| 86 +int | |
| 87 +compare_distance(const void *a, const void *b) | |
| 88 +{ | |
| 89 + struct item *da = *(struct item **) a; | |
| 90 + struct item *db = *(struct item **) b; | |
| 91 + | |
| 92 + if (!db) | |
| 93 + return 1; | |
| 94 + if (!da) | |
| 95 + return -1; | |
| 96 + | |
| 97 + return da->distance == db->distance ? 0 : da->distance < db->di… | |
| 98 +} | |
| 99 + | |
| 100 +void | |
| 101 +fuzzymatch(void) | |
| 102 +{ | |
| 103 + /* bang - we have so much memory */ | |
| 104 + struct item *it; | |
| 105 + struct item **fuzzymatches = NULL; | |
| 106 + char c; | |
| 107 + int number_of_matches = 0, i, pidx, sidx, eidx; | |
| 108 + int text_len = strlen(text), itext_len; | |
| 109 + | |
| 110 + matches = matchend = NULL; | |
| 111 + | |
| 112 + /* walk through all items */ | |
| 113 + for (it = items; it && it->text; ++it) { | |
| 114 + if (text_len) { | |
| 115 + itext_len = strlen(it->text); | |
| 116 + pidx = 0; /* pointer */ | |
| 117 + sidx = eidx = -1; /* start of match, end of mat… | |
| 118 + /* walk through item text */ | |
| 119 + for (i = 0; i < itext_len && (c = it->text[i]);… | |
| 120 + /* fuzzy match pattern */ | |
| 121 + if (!fstrncmp(&text[pidx], &c, 1)) { | |
| 122 + if(sidx == -1) | |
| 123 + sidx = i; | |
| 124 + ++pidx; | |
| 125 + if (pidx == text_len) { | |
| 126 + eidx = i; | |
| 127 + break; | |
| 128 + } | |
| 129 + } | |
| 130 + } | |
| 131 + /* build list of matches */ | |
| 132 + if (eidx != -1) { | |
| 133 + /* compute distance */ | |
| 134 + /* add penalty if match starts late (lo… | |
| 135 + * add penalty for long a match without… | |
| 136 + it->distance = log(sidx + 2) + (double)… | |
| 137 + /* fprintf(stderr, "distance %s %f\n", … | |
| 138 + appenditem(it, &matches, &matchend); | |
| 139 + ++number_of_matches; | |
| 140 + } | |
| 141 + } else { | |
| 142 + appenditem(it, &matches, &matchend); | |
| 143 + } | |
| 144 + } | |
| 145 + | |
| 146 + if (number_of_matches) { | |
| 147 + /* initialize array with matches */ | |
| 148 + if (!(fuzzymatches = realloc(fuzzymatches, | |
| 149 + number_of_matches * sizeof… | |
| 150 + die("cannot realloc %u bytes:", number_of_match… | |
| 151 + for (i = 0, it = matches; it && i < number_of_matches; … | |
| 152 + fuzzymatches[i] = it; | |
| 153 + /* sort matches according to distance */ | |
| 154 + qsort(fuzzymatches, number_of_matches, sizeof(struct it… | |
| 155 + /* rebuild list of matches */ | |
| 156 + matches = matchend = NULL; | |
| 157 + for (i = 0, it = fuzzymatches[i]; i < number_of_matches… | |
| 158 + it->text; ++i, it = fuzzymatches[i]) | |
| 159 + appenditem(it, &matches, &matchend); | |
| 160 + free(fuzzymatches); | |
| 161 + } | |
| 162 + curr = sel = matches; | |
| 163 + calcoffsets(); | |
| 164 +} | |
| 165 + | |
| 166 static void | |
| 167 match(void) | |
| 168 { | |
| 169 + if (fuzzy) { | |
| 170 + fuzzymatch(); | |
| 171 + return; | |
| 172 + } | |
| 173 static char **tokv = NULL; | |
| 174 static int tokn = 0; | |
| 175 | |
| 176 @@ -715,7 +801,7 @@ setup(void) | |
| 177 static void | |
| 178 usage(void) | |
| 179 { | |
| 180 - die("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m… | |
| 181 + die("usage: dmenu [-bFfiv] [-l lines] [-p prompt] [-fn font] [-… | |
| 182 " [-nb color] [-nf color] [-sb color] [-sf colo… | |
| 183 } | |
| 184 | |
| 185 @@ -732,6 +818,8 @@ main(int argc, char *argv[]) | |
| 186 exit(0); | |
| 187 } else if (!strcmp(argv[i], "-b")) /* appears at the bo… | |
| 188 topbar = 0; | |
| 189 + else if (!strcmp(argv[i], "-F")) /* disables fuzzy ma… | |
| 190 + fuzzy = 0; | |
| 191 else if (!strcmp(argv[i], "-f")) /* grabs keyboard be… | |
| 192 fast = 1; | |
| 193 else if (!strcmp(argv[i], "-i")) { /* case-insensitive … | |
| 194 -- | |
| 195 2.45.2 | |
| 196 |