dmenu-navhistory-4.6.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) 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 +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();