Skip to content

Commit

Permalink
patch: apply fuzzy match patch
Browse files Browse the repository at this point in the history
  • Loading branch information
fsareshwala committed Jun 23, 2020
1 parent 160d47c commit 6dcedef
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 2 deletions.
3 changes: 2 additions & 1 deletion config.def.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* See LICENSE file for copyright and license details. */
/* Default settings; can be overriden by command line. */

static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
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 */
static int centered = 0; /* -c option; centers dmenu on screen */
static int min_width = 500; /* minimum width when centered */
/* -fn option overrides fonts[0]; default X11 font or font set */
Expand Down
2 changes: 1 addition & 1 deletion config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
89 changes: 89 additions & 0 deletions dmenu.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* See LICENSE file for copyright and license details. */
#include <ctype.h>
#include <locale.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand Down Expand Up @@ -32,6 +33,7 @@ struct item {
char *text;
struct item *left, *right;
int out;
double distance;
};

static char text[BUFSIZ] = "";
Expand Down Expand Up @@ -258,9 +260,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;

Expand Down Expand Up @@ -774,6 +861,8 @@ main(int argc, char *argv[])
fast = 1;
else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */
centered = 1;
else if (!strcmp(argv[i], "-F")) /* fuzzy item matching */
fuzzy = 0;
else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
fstrncmp = strncasecmp;
fstrstr = cistrstr;
Expand Down

0 comments on commit 6dcedef

Please sign in to comment.