sites

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

commit 27e32cdbaa3141f85d845df2288897dec8e7584f
parent ca33dd0080acf6eb8987e88ffd47b10028d3a550
Author: phi <crispyfrog@163.com>
Date:   Mon,  4 Apr 2016 18:58:46 +0800

Add a new patch navhistory for dmenu

Diffstat:
Atools.suckless.org/dmenu/patches/dmenu-4.6-navhistory.diff | 173+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atools.suckless.org/dmenu/patches/navhistory.md | 19+++++++++++++++++++
2 files changed, 192 insertions(+), 0 deletions(-)

diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.6-navhistory.diff b/tools.suckless.org/dmenu/patches/dmenu-4.6-navhistory.diff @@ -0,0 +1,173 @@ +diff -urp dmenu-4.6/config.def.h dmenu-4.6-patched/config.def.h +--- dmenu-4.6/config.def.h 2015-11-09 06:42:21.000000000 +0800 ++++ dmenu-4.6-patched/config.def.h 2016-04-03 10:59:02.413544865 +0800 +@@ -15,3 +15,5 @@ static const char *outbgcolor = "#00fff + static const char *outfgcolor = "#000000"; + /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ + static unsigned int lines = 0; ++static unsigned int maxhist = 15; ++static int histnodup = 1; /* if 0, record repeated histories */ +diff -urp dmenu-4.6/dmenu.c dmenu-4.6-patched/dmenu.c +--- dmenu-4.6/dmenu.c 2015-11-09 06:42:21.000000000 +0800 ++++ dmenu-4.6-patched/dmenu.c 2016-04-03 10:54:51.798552270 +0800 +@@ -52,6 +52,10 @@ static XIC xic; + static ClrScheme scheme[SchemeLast]; + static Drw *drw; + ++static char *histfile; ++static char *histbuf, *histptr; ++static size_t histsz; ++ + #include "config.h" + + static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; +@@ -278,6 +282,105 @@ nextrune(int inc) + } + + static void ++loadhistory(void) ++{ ++ FILE *fp = NULL; ++ size_t sz; ++ ++ if (!histfile) ++ return; ++ if (!(fp = fopen(histfile, "r"))) ++ return; ++ fseek(fp, 0, SEEK_END); ++ sz = ftell(fp); ++ fseek(fp, 0, SEEK_SET); ++ if (sz) { ++ histsz = sz + 1 + BUFSIZ; ++ if (!(histbuf = malloc(histsz))) { ++ fprintf(stderr, "warning: cannot malloc %lu "\ ++ "bytes", histsz); ++ } else { ++ histptr = histbuf + fread(histbuf, 1, sz, fp); ++ if (histptr <= histbuf) { /* fread error */ ++ free(histbuf); ++ histbuf = NULL; ++ return; ++ } ++ if (histptr[-1] != '\n') ++ *histptr++ = '\n'; ++ histptr[BUFSIZ - 1] = '\0'; ++ *histptr = '\0'; ++ histsz = histptr - histbuf + BUFSIZ; ++ } ++ } ++ fclose(fp); ++} ++ ++static void ++navhistory(int dir) ++{ ++ char *p; ++ size_t len = 0, textlen; ++ ++ if (!histbuf) ++ return; ++ if (dir > 0) { ++ if (histptr == histbuf + histsz - BUFSIZ) ++ return; ++ while (*histptr && *histptr++ != '\n'); ++ for (p = histptr; *p && *p++ != '\n'; len++); ++ } else { ++ if (histptr == histbuf) ++ return; ++ if (histptr == histbuf + histsz - BUFSIZ) { ++ textlen = strlen(text); ++ textlen = MIN(textlen, BUFSIZ - 1); ++ strncpy(histptr, text, textlen); ++ histptr[textlen] = '\0'; ++ } ++ for (histptr--; histptr != histbuf && histptr[-1] != '\n'; ++ histptr--, len++); ++ } ++ len = MIN(len, BUFSIZ - 1); ++ strncpy(text, histptr, len); ++ text[len] = '\0'; ++ cursor = len; ++ match(); ++} ++static void ++savehistory(char *str) ++{ ++ unsigned int n, len = 0; ++ size_t slen; ++ char *p; ++ FILE *fp; ++ ++ if (!histfile || !maxhist) ++ return; ++ if (!(slen = strlen(str))) ++ return; ++ if (histbuf && maxhist > 1) { ++ p = histbuf + histsz - BUFSIZ - 1; /* skip the last newline */ ++ if (histnodup) { ++ for (; p != histbuf && p[-1] != '\n'; p--, len++); ++ n++; ++ if (slen == len && !strncmp(p, str, len)) { ++ return; ++ } ++ } ++ for (; p != histbuf; p--, len++) ++ if (p[-1] == '\n' && ++n + 1 > maxhist) ++ break; ++ fp = fopen(histfile, "w"); ++ fwrite(p, 1, len + 1, fp); /* plus the last newline */ ++ } else { ++ fp = fopen(histfile, "w"); ++ } ++ fwrite(str, 1, strlen(str), fp); ++ fclose(fp); ++} ++ ++static void + keypress(XKeyEvent *ev) + { + char buf[32]; +@@ -341,6 +444,8 @@ 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; + } +@@ -416,6 +521,8 @@ keypress(XKeyEvent *ev) + 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); + } +@@ -608,7 +715,7 @@ setup(void) + static void + usage(void) + { +- fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" ++ fputs("usage: dmenu [-b] [-f] [-H histfile] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); + exit(1); + } +@@ -633,6 +740,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")) +@@ -665,6 +774,7 @@ main(int argc, char *argv[]) + if (!drw->fontcount) + die("no fonts could be loaded.\n"); + drw_setscheme(drw, &scheme[SchemeNorm]); ++ loadhistory(); + + if (fast) { + grabkeyboard(); diff --git a/tools.suckless.org/dmenu/patches/navhistory.md b/tools.suckless.org/dmenu/patches/navhistory.md @@ -0,0 +1,19 @@ +# navhistory + +## Description + +This patch provides dmenu the ability for history navigation similar to that +of bash. Press alt+p for the previous history and alt+n for the next. + +## Configuration + +Set the maximum number of histories with a new variable 'maxhist' in config.h. +By default, it only records a new history if it is not the same as the last one. +To change this behaviour, set 'histnodup' to 0 in config.h. + +## Download + +* [dmenu-4.6-navhistory.diff](dmenu-4.6-navhistory.diff) (4677b) (20160404) + +## Author +* phi <crispyforg@163.com>