Hello, I have updated (attached) the dmenu history patch[1] to apply against the current tip revision 471:60d97462ff9d. Parts of the readstdin() function had to be run twice, so I did a quick & dirty #define, knowing that the C experts in the Suckless Community can suggest better ways.
This patch is also available[2] in my dmenu mirror on GitHub. Cheers. [1]: http://tools.suckless.org/dmenu/patches/history [2]: https://github.com/sunaku/.dmenu/compare/tip...history -- Nobody said computers were going to be polite.
>From eec5666cb9d666dd67d0b7ebf6f4f0b399e9fbdf 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 | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 59 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..4f3a8d3 100644 --- a/dmenu.c +++ b/dmenu.c @@ -18,6 +18,8 @@ #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define HIST_SIZE 20 + typedef struct Item Item; struct Item { char *text; @@ -61,9 +63,37 @@ static Item *prev, *curr, *next, *sel; static Window win; static XIC xic; +static char hist[HIST_SIZE][1024]; +static char *histfile = NULL; +static int hcnt = 0; + static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; +static int +writehistory(char *command) { + int i = 0; + FILE *f; + + if(!histfile || strlen(command) <= 0) + return 0; + + if((f = fopen(histfile, "w"))) { + fputs(command, f); + fputc('\n', f); + for(; i < hcnt; i++) { + if(strcmp(command, hist[i]) != 0) { + fputs(hist[i], f); + fputc('\n', f); + } + } + fclose(f); + return 1; + } + + return 0; +} + int main(int argc, char *argv[]) { Bool fast = False; @@ -100,6 +130,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 +384,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 +492,27 @@ 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); + 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 +634,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 histfile] [-fn font]\n" " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); exit(EXIT_FAILURE); } -- 1.7.8