On Wed 07 Dec 2011 11:18:30 PM PST, Suraj N. Kurapati wrote:
> I have updated (attached) the dmenu history patch[1] to apply against
> the current tip revision 471:60d97462ff9d.  

There was a bug in my adaptation: only 1 item was written to histfile.
I'm attaching a new patch that fixes this bug and also removes the
HIST_SIZE limit, allowing the history to be infinitely long.  I'll
leave it to the user to prune their history file if it's getting big.

> [1]: http://tools.suckless.org/dmenu/patches/history
> [2]: https://github.com/sunaku/.dmenu/compare/tip...history

-- 
If Machiavelli were a hacker, he'd have worked for the CSSG.
                -- Phil Lapsley
>From ed83ee03b913ef76b48556c6c65c54ca9f6871a8 Mon Sep 17 00:00:00 2001
From: "Suraj N. Kurapati" <sun...@gmail.com>
Date: Wed, 7 Dec 2011 22:33:10 -0800
Subject: [PATCH] dmenu-tip-history.diff (adapted to new hg tip)

http://tools.suckless.org/dmenu/patches/history
---
 dmenu.1 |    5 ++++
 dmenu.c |   66 +++++++++++++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 57 insertions(+), 14 deletions(-)

diff --git a/dmenu.1 b/dmenu.1
index 5f74463..33a9599 100644
--- a/dmenu.1
+++ b/dmenu.1
@@ -20,6 +20,8 @@ dmenu \- dynamic menu
 .IR color ]
 .RB [ \-sf
 .IR color ]
+.RB [ \-hist
+.IR "<filename>" ]
 .RB [ \-v ]
 .P
 .BR dmenu_run " ..."
@@ -70,6 +72,9 @@ defines the selected background color.
 .BI \-sf " color"
 defines the selected foreground color.
 .TP
+.BI \-hist " <histfile>"
+the file to use for history
+.TP
 .B \-v
 prints version information to stdout, then exits.
 .SH USAGE
diff --git a/dmenu.c b/dmenu.c
index 019fa3e..50d4142 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -61,9 +61,36 @@ static Item *prev, *curr, *next, *sel;
 static Window win;
 static XIC xic;
 
+static char *histfile = NULL;
+static size_t histsize = 0;
+
 static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
 static char *(*fstrstr)(const char *, const char *) = strstr;
 
+static int
+writehistory(char *command) {
+	size_t i = 0;
+	FILE *f;
+
+	if(!histfile || strlen(command) <= 0)
+		return 0;
+
+	if((f = fopen(histfile, "w"))) {
+		fputs(command, f);
+		fputc('\n', f);
+		for(; i < histsize; i++) {
+			if(strcmp(command, items[i].text) != 0) {
+				fputs(items[i].text, f);
+				fputc('\n', f);
+			}
+		}
+		fclose(f);
+		return 1;
+	}
+
+	return 0;
+}
+
 int
 main(int argc, char *argv[]) {
 	Bool fast = False;
@@ -100,6 +127,8 @@ main(int argc, char *argv[]) {
 			selbgcolor = argv[++i];
 		else if(!strcmp(argv[i], "-sf"))  /* selected foreground color */
 			selfgcolor = argv[++i];
+		else if(!strcmp(argv[i], "-hist"))
+			histfile = argv[++i];
 		else
 			usage();
 
@@ -352,6 +381,7 @@ keypress(XKeyEvent *ev) {
 	case XK_Return:
 	case XK_KP_Enter:
 		puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
+		writehistory(sel ? sel->text : text);
 		exit(EXIT_SUCCESS);
 	case XK_Right:
 		if(text[cursor] != '\0') {
@@ -459,20 +489,28 @@ paste(void) {
 void
 readstdin(void) {
 	char buf[sizeof text], *p, *maxstr = NULL;
-	size_t i, max = 0, size = 0;
-
-	/* read each line from stdin and add it to the item list */
-	for(i = 0; fgets(buf, sizeof buf, stdin); i++) {
-		if(i+1 >= size / sizeof *items)
-			if(!(items = realloc(items, (size += BUFSIZ))))
-				eprintf("cannot realloc %u bytes:", size);
-		if((p = strchr(buf, '\n')))
-			*p = '\0';
-		if(!(items[i].text = strdup(buf)))
-			eprintf("cannot strdup %u bytes:", strlen(buf)+1);
-		if(strlen(items[i].text) > max)
-			max = strlen(maxstr = items[i].text);
+	size_t i = 0, max = 0, size = 0;
+#define readstdin_internals(the_input_file) \
+	for(; fgets(buf, sizeof buf, the_input_file); i++) {\
+		if(i+1 >= size / sizeof *items)\
+			if(!(items = realloc(items, (size += BUFSIZ))))\
+				eprintf("cannot realloc %u bytes:", size);\
+		if((p = strchr(buf, '\n')))\
+			*p = '\0';\
+		if(!(items[i].text = strdup(buf)))\
+			eprintf("cannot strdup %u bytes:", strlen(buf)+1);\
+		if(strlen(items[i].text) > max)\
+			max = strlen(maxstr = items[i].text);\
+	}\
+	/* lines from the history file must appear first in menu */
+	FILE *f;
+	if(histfile && (f = fopen(histfile, "r"))) {
+		readstdin_internals(f);
+		histsize = i;
+		fclose(f);
 	}
+	/* read each line from stdin and add it to the item list */
+	readstdin_internals(stdin);
 	if(items)
 		items[i].text = NULL;
 	inputw = maxstr ? textw(dc, maxstr) : 0;
@@ -594,7 +632,7 @@ setup(void) {
 
 void
 usage(void) {
-	fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font]\n"
+	fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-hist file] [-fn font]\n"
 	      "             [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr);
 	exit(EXIT_FAILURE);
 }
-- 
1.7.8

Reply via email to