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 +0800 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 lines */ 7 static unsigned int lines = 0; 8 +static unsigned int maxhist = 15; 9 +static int histnodup = 1; /* if 0, record repeated histories */ 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] != '\n'; 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 newline */ 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 newline */ 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 : text); 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 font] [-m monitor]\n" 153 + fputs("usage: dmenu [-b] [-f] [-H histfile] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" 154 " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); 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 in vertical list */ 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();