[PATCH 1/3] Typofix

From: Klemens Nanni <kl3_AT_posteo.org>
Date: Mon, 11 Jan 2016 13:26:37 +0100

---
 config.def.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config.def.h b/config.def.h
index 8db1dda..dcffd38 100644
--- a/config.def.h
+++ b/config.def.h
_AT_@ -6,7 +6,7 @@ static int topbar = 1;                      /* -b  option; if 0, dmenu appears a
 static const char *fonts[] = {
 	"monospace:size=10"
 };
-static const char *prompt      = NULL;      /* -p  option; prompt to the elft of input field */
+static const char *prompt      = NULL;      /* -p  option; prompt to the left of input field */
 static const char *normbgcolor = "#222222"; /* -nb option; normal background                 */
 static const char *normfgcolor = "#bbbbbb"; /* -nf option; normal foreground                 */
 static const char *selbgcolor  = "#005577"; /* -sb option; selected background               */
-- 
2.6.2
--------------050705050102030307060402
Content-Type: text/x-patch;
 name="dmenu-git-20161101-fuzzymatch.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="dmenu-git-20161101-fuzzymatch.diff"
diff --git a/dmenu.c b/dmenu.c
index 4f22ffe..c2fc3ee 100644
--- a/dmenu.c
+++ b/dmenu.c
_AT_@ -33,6 +33,7 @@ struct item {
 	char *text;
 	struct item *left, *right;
 	int out;
+	int distance;
 };
 
 static char text[BUFSIZ] = "";
_AT_@ -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)
 {
_AT_@ -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
_AT_@ -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);
_AT_@ -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();
_AT_@ -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;
--------------050705050102030307060402
Content-Type: text/x-patch;
 name="dmenu-git-20161101-hide-single-newline.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="dmenu-git-20161101-hide-single-newline.diff"
diff --git a/dmenu.c b/dmenu.c
index e0c2f80..ef25442 100644
--- a/dmenu.c
+++ b/dmenu.c
_AT_@ -487,6 +487,7 @@ readstdin(void)
 	}
 	if (items)
 		items[i].text = NULL;
+	if (i == 1 && items[0].text[0] == '\0') items = realloc(items, 0);
 	inputw = maxstr ? TEXTW(maxstr) : 0;
 	lines = MIN(lines, i);
 }
--------------050705050102030307060402
Content-Type: text/x-patch;
 name="dmenu-git-20161101-instant.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="dmenu-git-20161101-instant.diff"
diff --git a/config.def.h b/config.def.h
index 8db1dda..f941d84 100644
--- a/config.def.h
+++ b/config.def.h
_AT_@ -2,6 +2,8 @@
 /* Default settings; can be overriden by command line. */
 
 static int topbar = 1;                      /* -b  option; if 0, dmenu appears at bottom     */
+static int instant = 0;                     /* -n option; if 1, dmenu ends immediately on a
+					       distinct match */
 /* -fn option overrides fonts[0]; default X11 font or font set */
 static const char *fonts[] = {
 	"monospace:size=10"
diff --git a/dmenu.c b/dmenu.c
index e0c2f80..340baa9 100644
--- a/dmenu.c
+++ b/dmenu.c
_AT_@ -250,6 +250,11 @@ match(void)
 		matchend = substrend;
 	}
 	curr = sel = matches;
+	if(instant && matches && matches==matchend && !lsubstr) {
+		puts(matches->next);
+		cleanup;
+		exit(0);
+	}
 	calcoffsets();
 }
 
_AT_@ -632,7 +637,9 @@ main(int argc, char *argv[])
 		else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
 			fstrncmp = strncasecmp;
 			fstrstr = cistrstr;
-		} else if (i + 1 == argc)
+		} else if (!strcmp(argv[i], "-n")) /* instant match */
+			instant = !instant;
+		else if (i + 1 == argc)
 			usage();
 		/* these options take one argument */
 		else if (!strcmp(argv[i], "-l"))   /* number of lines in vertical list */
--------------050705050102030307060402--
Received on Mon Sep 17 2001 - 00:00:00 CEST

This archive was generated by hypermail 2.3.0 : Mon Jan 11 2016 - 19:00:14 CET