| dmenu-navhistory-4.6.diff - sites - public wiki contents of suckless.org | |
| git clone git://git.suckless.org/sites | |
| Log | |
| Files | |
| Refs | |
| --- | |
| dmenu-navhistory-4.6.diff (4677B) | |
| --- | |
| 1 diff -urp dmenu-4.6/config.def.h dmenu-4.6-patched/config.def.h | |
| 2 --- dmenu-4.6/config.def.h 2015-11-09 06:42:21.000000000 +0800 | |
| 3 +++ dmenu-4.6-patched/config.def.h 2016-04-03 10:59:02.413544865 … | |
| 4 @@ -15,3 +15,5 @@ static const char *outbgcolor = "#00fff | |
| 5 static const char *outfgcolor = "#000000"; | |
| 6 /* -l option; if nonzero, dmenu uses vertical list with given number of… | |
| 7 static unsigned int lines = 0; | |
| 8 +static unsigned int maxhist = 15; | |
| 9 +static int histnodup = 1; /* if 0, record repeated his… | |
| 10 diff -urp dmenu-4.6/dmenu.c dmenu-4.6-patched/dmenu.c | |
| 11 --- dmenu-4.6/dmenu.c 2015-11-09 06:42:21.000000000 +0800 | |
| 12 +++ dmenu-4.6-patched/dmenu.c 2016-04-03 10:54:51.798552270 +0800 | |
| 13 @@ -52,6 +52,10 @@ static XIC xic; | |
| 14 static ClrScheme scheme[SchemeLast]; | |
| 15 static Drw *drw; | |
| 16 | |
| 17 +static char *histfile; | |
| 18 +static char *histbuf, *histptr; | |
| 19 +static size_t histsz; | |
| 20 + | |
| 21 #include "config.h" | |
| 22 | |
| 23 static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; | |
| 24 @@ -278,6 +282,105 @@ nextrune(int inc) | |
| 25 } | |
| 26 | |
| 27 static void | |
| 28 +loadhistory(void) | |
| 29 +{ | |
| 30 + FILE *fp = NULL; | |
| 31 + size_t sz; | |
| 32 + | |
| 33 + if (!histfile) | |
| 34 + return; | |
| 35 + if (!(fp = fopen(histfile, "r"))) | |
| 36 + return; | |
| 37 + fseek(fp, 0, SEEK_END); | |
| 38 + sz = ftell(fp); | |
| 39 + fseek(fp, 0, SEEK_SET); | |
| 40 + if (sz) { | |
| 41 + histsz = sz + 1 + BUFSIZ; | |
| 42 + if (!(histbuf = malloc(histsz))) { | |
| 43 + fprintf(stderr, "warning: cannot malloc %lu "\ | |
| 44 + "bytes", histsz); | |
| 45 + } else { | |
| 46 + histptr = histbuf + fread(histbuf, 1, sz, fp); | |
| 47 + if (histptr <= histbuf) { /* fread error */ | |
| 48 + free(histbuf); | |
| 49 + histbuf = NULL; | |
| 50 + return; | |
| 51 + } | |
| 52 + if (histptr[-1] != '\n') | |
| 53 + *histptr++ = '\n'; | |
| 54 + histptr[BUFSIZ - 1] = '\0'; | |
| 55 + *histptr = '\0'; | |
| 56 + histsz = histptr - histbuf + BUFSIZ; | |
| 57 + } | |
| 58 + } | |
| 59 + fclose(fp); | |
| 60 +} | |
| 61 + | |
| 62 +static void | |
| 63 +navhistory(int dir) | |
| 64 +{ | |
| 65 + char *p; | |
| 66 + size_t len = 0, textlen; | |
| 67 + | |
| 68 + if (!histbuf) | |
| 69 + return; | |
| 70 + if (dir > 0) { | |
| 71 + if (histptr == histbuf + histsz - BUFSIZ) | |
| 72 + return; | |
| 73 + while (*histptr && *histptr++ != '\n'); | |
| 74 + for (p = histptr; *p && *p++ != '\n'; len++); | |
| 75 + } else { | |
| 76 + if (histptr == histbuf) | |
| 77 + return; | |
| 78 + if (histptr == histbuf + histsz - BUFSIZ) { | |
| 79 + textlen = strlen(text); | |
| 80 + textlen = MIN(textlen, BUFSIZ - 1); | |
| 81 + strncpy(histptr, text, textlen); | |
| 82 + histptr[textlen] = '\0'; | |
| 83 + } | |
| 84 + for (histptr--; histptr != histbuf && histptr[-1] != '\… | |
| 85 + histptr--, len++); | |
| 86 + } | |
| 87 + len = MIN(len, BUFSIZ - 1); | |
| 88 + strncpy(text, histptr, len); | |
| 89 + text[len] = '\0'; | |
| 90 + cursor = len; | |
| 91 + match(); | |
| 92 +} | |
| 93 +static void | |
| 94 +savehistory(char *str) | |
| 95 +{ | |
| 96 + unsigned int n, len = 0; | |
| 97 + size_t slen; | |
| 98 + char *p; | |
| 99 + FILE *fp; | |
| 100 + | |
| 101 + if (!histfile || !maxhist) | |
| 102 + return; | |
| 103 + if (!(slen = strlen(str))) | |
| 104 + return; | |
| 105 + if (histbuf && maxhist > 1) { | |
| 106 + p = histbuf + histsz - BUFSIZ - 1; /* skip the last new… | |
| 107 + if (histnodup) { | |
| 108 + for (; p != histbuf && p[-1] != '\n'; p--, len+… | |
| 109 + n++; | |
| 110 + if (slen == len && !strncmp(p, str, len)) { | |
| 111 + return; | |
| 112 + } | |
| 113 + } | |
| 114 + for (; p != histbuf; p--, len++) | |
| 115 + if (p[-1] == '\n' && ++n + 1 > maxhist) | |
| 116 + break; | |
| 117 + fp = fopen(histfile, "w"); | |
| 118 + fwrite(p, 1, len + 1, fp); /* plus the last newl… | |
| 119 + } else { | |
| 120 + fp = fopen(histfile, "w"); | |
| 121 + } | |
| 122 + fwrite(str, 1, strlen(str), fp); | |
| 123 + fclose(fp); | |
| 124 +} | |
| 125 + | |
| 126 +static void | |
| 127 keypress(XKeyEvent *ev) | |
| 128 { | |
| 129 char buf[32]; | |
| 130 @@ -341,6 +444,8 @@ keypress(XKeyEvent *ev) | |
| 131 case XK_j: ksym = XK_Next; break; | |
| 132 case XK_k: ksym = XK_Prior; break; | |
| 133 case XK_l: ksym = XK_Down; break; | |
| 134 + case XK_p: navhistory(-1); buf[0]=0; break; | |
| 135 + case XK_n: navhistory(1); buf[0]=0; break; | |
| 136 default: | |
| 137 return; | |
| 138 } | |
| 139 @@ -416,6 +521,8 @@ keypress(XKeyEvent *ev) | |
| 140 case XK_KP_Enter: | |
| 141 puts((sel && !(ev->state & ShiftMask)) ? sel->text : te… | |
| 142 if (!(ev->state & ControlMask)) { | |
| 143 + savehistory((sel && !(ev->state & ShiftMask)) | |
| 144 + ? sel->text : text); | |
| 145 cleanup(); | |
| 146 exit(0); | |
| 147 } | |
| 148 @@ -608,7 +715,7 @@ setup(void) | |
| 149 static void | |
| 150 usage(void) | |
| 151 { | |
| 152 - fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn … | |
| 153 + fputs("usage: dmenu [-b] [-f] [-H histfile] [-i] [-l lines] [-p… | |
| 154 " [-nb color] [-nf color] [-sb color] [-sf co… | |
| 155 exit(1); | |
| 156 } | |
| 157 @@ -633,6 +740,8 @@ main(int argc, char *argv[]) | |
| 158 } else if (i + 1 == argc) | |
| 159 usage(); | |
| 160 /* these options take one argument */ | |
| 161 + else if (!strcmp(argv[i], "-H")) | |
| 162 + histfile = argv[++i]; | |
| 163 else if (!strcmp(argv[i], "-l")) /* number of lines i… | |
| 164 lines = atoi(argv[++i]); | |
| 165 else if (!strcmp(argv[i], "-m")) | |
| 166 @@ -665,6 +774,7 @@ main(int argc, char *argv[]) | |
| 167 if (!drw->fontcount) | |
| 168 die("no fonts could be loaded.\n"); | |
| 169 drw_setscheme(drw, &scheme[SchemeNorm]); | |
| 170 + loadhistory(); | |
| 171 | |
| 172 if (fast) { | |
| 173 grabkeyboard(); |