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