sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit f759877d393eaed126dfc8e56932c49e7581a181
parent 63becf49518e10e2050fb890f2cd10e2084f1617
Author: Max Schillinger <maxschillinger@web.de>
Date:   Fri,  9 Jul 2021 17:41:34 +0200

[dmenu][patch][navhistory] Bug fix: Write first entry to history file

- Bug fix: Don't skip writing first entry to history file. This happened for
  `histnodup` = 1 (default) plus `histsz` = 0 (value when starting with an
  empty history).
- Rename `dmenu-navhistory-20200709.diff` to `dmenu-navhistory-5.0.diff`
  because the only change to dmenu since 2020-07-09 was bumping the
  version number to 5.0.

Diffstat:
Dtools.suckless.org/dmenu/patches/navhistory/dmenu-navhistory-20200709.diff | 241-------------------------------------------------------------------------------
Atools.suckless.org/dmenu/patches/navhistory/dmenu-navhistory-5.0.diff | 256+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtools.suckless.org/dmenu/patches/navhistory/index.md | 2+-
3 files changed, 257 insertions(+), 242 deletions(-)

diff --git a/tools.suckless.org/dmenu/patches/navhistory/dmenu-navhistory-20200709.diff b/tools.suckless.org/dmenu/patches/navhistory/dmenu-navhistory-20200709.diff @@ -1,241 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 1edb647..e3e1b53 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -15,6 +15,8 @@ static const char *colors[SchemeLast][2] = { - }; - /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ - static unsigned int lines = 0; -+static unsigned int maxhist = 64; -+static int histnodup = 1; /* if 0, record repeated histories */ - - /* - * Characters not considered part of a word while deleting words -diff --git a/dmenu.1 b/dmenu.1 -index 323f93c..ff496dd 100644 ---- a/dmenu.1 -+++ b/dmenu.1 -@@ -22,6 +22,8 @@ dmenu \- dynamic menu - .IR color ] - .RB [ \-w - .IR windowid ] -+.RB [ \-H -+.IR histfile ] - .P - .BR dmenu_run " ..." - .SH DESCRIPTION -@@ -80,6 +82,9 @@ prints version information to stdout, then exits. - .TP - .BI \-w " windowid" - embed into windowid. -+.TP -+.BI \-H " histfile" -+save input in histfile and use it for history navigation. - .SH USAGE - dmenu is completely controlled by the keyboard. Items are selected using the - arrow keys, page up, page down, home, and end. -diff --git a/dmenu.c b/dmenu.c -index 65f25ce..9d15f78 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -53,6 +53,10 @@ static XIC xic; - static Drw *drw; - static Clr *scheme[SchemeLast]; - -+static char *histfile; -+static char **history; -+static size_t histsz, histpos; -+ - #include "config.h" - - static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; -@@ -304,6 +308,129 @@ movewordedge(int dir) - } - } - -+static void -+loadhistory(void) -+{ -+ FILE *fp = NULL; -+ static size_t cap = 0; -+ size_t llen; -+ char *line; -+ -+ if (!histfile) { -+ return; -+ } -+ -+ fp = fopen(histfile, "r"); -+ if (!fp) { -+ return; -+ } -+ -+ for (;;) { -+ line = NULL; -+ llen = 0; -+ if (-1 == getline(&line, &llen, fp)) { -+ if (ferror(fp)) { -+ die("failed to read history"); -+ } -+ free(line); -+ break; -+ } -+ -+ if (cap == histsz) { -+ cap += 64 * sizeof(char*); -+ history = realloc(history, cap); -+ if (!history) { -+ die("failed to realloc memory"); -+ } -+ } -+ strtok(line, "\n"); -+ history[histsz] = line; -+ histsz++; -+ } -+ histpos = histsz; -+ -+ if (fclose(fp)) { -+ die("failed to close file %s", histfile); -+ } -+} -+ -+static void -+navhistory(int dir) -+{ -+ static char def[BUFSIZ]; -+ char *p = NULL; -+ size_t len = 0; -+ -+ if (!history || histpos + 1 == 0) -+ return; -+ -+ if (histsz == histpos) { -+ strncpy(def, text, sizeof(def)); -+ } -+ -+ switch(dir) { -+ case 1: -+ if (histpos < histsz - 1) { -+ p = history[++histpos]; -+ } else if (histpos == histsz - 1) { -+ p = def; -+ histpos++; -+ } -+ break; -+ case -1: -+ if (histpos > 0) { -+ p = history[--histpos]; -+ } -+ break; -+ } -+ if (p == NULL) { -+ return; -+ } -+ -+ len = MIN(strlen(p), BUFSIZ - 1); -+ strncpy(text, p, len); -+ text[len] = '\0'; -+ cursor = len; -+ match(); -+} -+ -+static void -+savehistory(char *input) -+{ -+ unsigned int i; -+ FILE *fp; -+ -+ if (!histfile || -+ 0 == maxhist || -+ 0 == strlen(input)) { -+ goto out; -+ } -+ -+ fp = fopen(histfile, "w"); -+ if (!fp) { -+ die("failed to open %s", histfile); -+ } -+ for (i = histsz < maxhist ? 0 : histsz - maxhist; i < histsz; i++) { -+ if (0 >= fprintf(fp, "%s\n", history[i])) { -+ die("failed to write to %s", histfile); -+ } -+ } -+ if (!histnodup || (histsz > 0 && strcmp(input, history[histsz-1]) != 0)) { /* TODO */ -+ if (0 >= fputs(input, fp)) { -+ die("failed to write to %s", histfile); -+ } -+ } -+ if (fclose(fp)) { -+ die("failed to close file %s", histfile); -+ } -+ -+out: -+ for (i = 0; i < histsz; i++) { -+ free(history[i]); -+ } -+ free(history); -+} -+ - static void - keypress(XKeyEvent *ev) - { -@@ -388,6 +515,14 @@ keypress(XKeyEvent *ev) - case XK_j: ksym = XK_Next; break; - case XK_k: ksym = XK_Prior; break; - case XK_l: ksym = XK_Down; break; -+ case XK_p: -+ navhistory(-1); -+ buf[0]=0; -+ break; -+ case XK_n: -+ navhistory(1); -+ buf[0]=0; -+ break; - default: - return; - } -@@ -466,6 +601,8 @@ insert: - case XK_KP_Enter: - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); - if (!(ev->state & ControlMask)) { -+ savehistory((sel && !(ev->state & ShiftMask)) -+ ? sel->text : text); - cleanup(); - exit(0); - } -@@ -690,7 +827,8 @@ static void - usage(void) - { - fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" -- " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); -+ " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n" -+ " [-H histfile]", stderr); - exit(1); - } - -@@ -715,6 +853,8 @@ main(int argc, char *argv[]) - } else if (i + 1 == argc) - usage(); - /* these options take one argument */ -+ else if (!strcmp(argv[i], "-H")) -+ histfile = argv[++i]; - else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ - lines = atoi(argv[++i]); - else if (!strcmp(argv[i], "-m")) -@@ -757,6 +897,8 @@ main(int argc, char *argv[]) - die("pledge"); - #endif - -+ loadhistory(); -+ - if (fast && !isatty(0)) { - grabkeyboard(); - readstdin(); -diff --git a/dmenu_run b/dmenu_run -index 834ede5..59ec622 100755 ---- a/dmenu_run -+++ b/dmenu_run -@@ -1,2 +1,2 @@ - #!/bin/sh --dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} & -+dmenu_path | dmenu -H "${XDG_CACHE_HOME:-$HOME/.cache/}/dmenu_run.hist" "$@" | ${SHELL:-"/bin/sh"} & diff --git a/tools.suckless.org/dmenu/patches/navhistory/dmenu-navhistory-5.0.diff b/tools.suckless.org/dmenu/patches/navhistory/dmenu-navhistory-5.0.diff @@ -0,0 +1,256 @@ +From a4a08baf35edb6b50ed14f76e99d0c6fe790759d Mon Sep 17 00:00:00 2001 +From: Max Schillinger <maxschillinger@web.de> +Date: Fri, 9 Jul 2021 17:17:36 +0200 +Subject: [PATCH] Bug fix: Writing first entry to history file was skipped + +--- + config.def.h | 2 + + dmenu.1 | 5 ++ + dmenu.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++- + dmenu_run | 2 +- + 4 files changed, 151 insertions(+), 2 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 1edb647..e3e1b53 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -15,6 +15,8 @@ static const char *colors[SchemeLast][2] = { + }; + /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ + static unsigned int lines = 0; ++static unsigned int maxhist = 64; ++static int histnodup = 1; /* if 0, record repeated histories */ + + /* + * Characters not considered part of a word while deleting words +diff --git a/dmenu.1 b/dmenu.1 +index 323f93c..ff496dd 100644 +--- a/dmenu.1 ++++ b/dmenu.1 +@@ -22,6 +22,8 @@ dmenu \- dynamic menu + .IR color ] + .RB [ \-w + .IR windowid ] ++.RB [ \-H ++.IR histfile ] + .P + .BR dmenu_run " ..." + .SH DESCRIPTION +@@ -80,6 +82,9 @@ prints version information to stdout, then exits. + .TP + .BI \-w " windowid" + embed into windowid. ++.TP ++.BI \-H " histfile" ++save input in histfile and use it for history navigation. + .SH USAGE + dmenu is completely controlled by the keyboard. Items are selected using the + arrow keys, page up, page down, home, and end. +diff --git a/dmenu.c b/dmenu.c +index 65f25ce..5023257 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -53,6 +53,10 @@ static XIC xic; + static Drw *drw; + static Clr *scheme[SchemeLast]; + ++static char *histfile; ++static char **history; ++static size_t histsz, histpos; ++ + #include "config.h" + + static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; +@@ -304,6 +308,129 @@ movewordedge(int dir) + } + } + ++static void ++loadhistory(void) ++{ ++ FILE *fp = NULL; ++ static size_t cap = 0; ++ size_t llen; ++ char *line; ++ ++ if (!histfile) { ++ return; ++ } ++ ++ fp = fopen(histfile, "r"); ++ if (!fp) { ++ return; ++ } ++ ++ for (;;) { ++ line = NULL; ++ llen = 0; ++ if (-1 == getline(&line, &llen, fp)) { ++ if (ferror(fp)) { ++ die("failed to read history"); ++ } ++ free(line); ++ break; ++ } ++ ++ if (cap == histsz) { ++ cap += 64 * sizeof(char*); ++ history = realloc(history, cap); ++ if (!history) { ++ die("failed to realloc memory"); ++ } ++ } ++ strtok(line, "\n"); ++ history[histsz] = line; ++ histsz++; ++ } ++ histpos = histsz; ++ ++ if (fclose(fp)) { ++ die("failed to close file %s", histfile); ++ } ++} ++ ++static void ++navhistory(int dir) ++{ ++ static char def[BUFSIZ]; ++ char *p = NULL; ++ size_t len = 0; ++ ++ if (!history || histpos + 1 == 0) ++ return; ++ ++ if (histsz == histpos) { ++ strncpy(def, text, sizeof(def)); ++ } ++ ++ switch(dir) { ++ case 1: ++ if (histpos < histsz - 1) { ++ p = history[++histpos]; ++ } else if (histpos == histsz - 1) { ++ p = def; ++ histpos++; ++ } ++ break; ++ case -1: ++ if (histpos > 0) { ++ p = history[--histpos]; ++ } ++ break; ++ } ++ if (p == NULL) { ++ return; ++ } ++ ++ len = MIN(strlen(p), BUFSIZ - 1); ++ strncpy(text, p, len); ++ text[len] = '\0'; ++ cursor = len; ++ match(); ++} ++ ++static void ++savehistory(char *input) ++{ ++ unsigned int i; ++ FILE *fp; ++ ++ if (!histfile || ++ 0 == maxhist || ++ 0 == strlen(input)) { ++ goto out; ++ } ++ ++ fp = fopen(histfile, "w"); ++ if (!fp) { ++ die("failed to open %s", histfile); ++ } ++ for (i = histsz < maxhist ? 0 : histsz - maxhist; i < histsz; i++) { ++ if (0 >= fprintf(fp, "%s\n", history[i])) { ++ die("failed to write to %s", histfile); ++ } ++ } ++ if (histsz == 0 || !histnodup || (histsz > 0 && strcmp(input, history[histsz-1]) != 0)) { /* TODO */ ++ if (0 >= fputs(input, fp)) { ++ die("failed to write to %s", histfile); ++ } ++ } ++ if (fclose(fp)) { ++ die("failed to close file %s", histfile); ++ } ++ ++out: ++ for (i = 0; i < histsz; i++) { ++ free(history[i]); ++ } ++ free(history); ++} ++ + static void + keypress(XKeyEvent *ev) + { +@@ -388,6 +515,14 @@ keypress(XKeyEvent *ev) + case XK_j: ksym = XK_Next; break; + case XK_k: ksym = XK_Prior; break; + case XK_l: ksym = XK_Down; break; ++ case XK_p: ++ navhistory(-1); ++ buf[0]=0; ++ break; ++ case XK_n: ++ navhistory(1); ++ buf[0]=0; ++ break; + default: + return; + } +@@ -466,6 +601,8 @@ insert: + case XK_KP_Enter: + puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); + if (!(ev->state & ControlMask)) { ++ savehistory((sel && !(ev->state & ShiftMask)) ++ ? sel->text : text); + cleanup(); + exit(0); + } +@@ -690,7 +827,8 @@ static void + usage(void) + { + fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" +- " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); ++ " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n" ++ " [-H histfile]", stderr); + exit(1); + } + +@@ -715,6 +853,8 @@ main(int argc, char *argv[]) + } else if (i + 1 == argc) + usage(); + /* these options take one argument */ ++ else if (!strcmp(argv[i], "-H")) ++ histfile = argv[++i]; + else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ + lines = atoi(argv[++i]); + else if (!strcmp(argv[i], "-m")) +@@ -757,6 +897,8 @@ main(int argc, char *argv[]) + die("pledge"); + #endif + ++ loadhistory(); ++ + if (fast && !isatty(0)) { + grabkeyboard(); + readstdin(); +diff --git a/dmenu_run b/dmenu_run +index 834ede5..59ec622 100755 +--- a/dmenu_run ++++ b/dmenu_run +@@ -1,2 +1,2 @@ + #!/bin/sh +-dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} & ++dmenu_path | dmenu -H "${XDG_CACHE_HOME:-$HOME/.cache/}/dmenu_run.hist" "$@" | ${SHELL:-"/bin/sh"} & +-- +2.25.1 + diff --git a/tools.suckless.org/dmenu/patches/navhistory/index.md b/tools.suckless.org/dmenu/patches/navhistory/index.md @@ -14,8 +14,8 @@ To change this behaviour, set 'histnodup' to 0 in config.h. Download -------- +* [dmenu-navhistory-5.0.diff](dmenu-navhistory-5.0.diff) * [dmenu-navhistory-4.6.diff](dmenu-navhistory-4.6.diff) -* [dmenu-navhistory-20200709.diff](dmenu-navhistory-20200709.diff) ### With Search This patch extends navhist with history-search functionality. Press