dmenu-json-4.9-r2.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
dmenu-json-4.9-r2.diff (6200B)
---
1 diff --git a/config.mk b/config.mk
2 index 0929b4a..4627988 100644
3 --- a/config.mk
4 +++ b/config.mk
5 @@ -18,13 +18,19 @@ FREETYPEINC = /usr/include/freetype2
6 # OpenBSD (uncomment)
7 #FREETYPEINC = $(X11INC)/freetype2
8
9 +# jansson
10 +JANSSONINC = `pkg-config --cflags jansson`
11 +JANSSONLIBS = `pkg-config --libs jansson`
12 +# uncomment on RHEL for strcasecmp
13 +#EXTRAFLAGS=-D_GNU_SOURCE
14 +
15 # includes and libs
16 -INCS = -I$(X11INC) -I$(FREETYPEINC)
17 -LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS)
18 +INCS = -I$(X11INC) -I$(FREETYPEINC) $(JANSSONINC)
19 +LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) $(JANSSONLIBS)
20
21 # flags
22 -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
23 -CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS)
24 +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) $(EXTRAFLAGS)
25 +CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS)
26 LDFLAGS = $(LIBS)
27
28 # compiler and linker
29 diff --git a/dmenu.c b/dmenu.c
30 index 65f25ce..58c1e23 100644
31 --- a/dmenu.c
32 +++ b/dmenu.c
33 @@ -15,6 +15,7 @@
34 #include <X11/extensions/Xinerama.h>
35 #endif
36 #include <X11/Xft/Xft.h>
37 +#include <jansson.h>
38
39 #include "drw.h"
40 #include "util.h"
41 @@ -32,6 +33,7 @@ struct item {
42 char *text;
43 struct item *left, *right;
44 int out;
45 + json_t *json;
46 };
47
48 static char text[BUFSIZ] = "";
49 @@ -40,6 +42,8 @@ static int bh, mw, mh;
50 static int inputw = 0, promptw;
51 static int lrpad; /* sum of left and right padding */
52 static size_t cursor;
53 +static size_t items_sz = 0;
54 +static size_t items_ln = 0;
55 static struct item *items = NULL;
56 static struct item *matches, *matchend;
57 static struct item *prev, *curr, *next, *sel;
58 @@ -58,6 +62,18 @@ static Clr *scheme[SchemeLast];
59 static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
60 static char *(*fstrstr)(const char *, const char *) = strstr;
61
62 +static void listjson(json_t *obj);
63 +static json_t *json = NULL;
64 +
65 +static struct item *
66 +itemnew(void)
67 +{
68 + if (items_ln + 1 >= (items_sz / sizeof *items))
69 + if (!(items = realloc(items, (items_sz += BUFSIZ))))
70 + die("cannot realloc %u bytes:", items_sz);
71 + return &items[items_ln++];
72 +}
73 +
74 static void
75 appenditem(struct item *item, struct item **list, struct item **last)
76 {
77 @@ -221,6 +237,8 @@ match(void)
78 size_t len, textsize;
79 struct item *item, *lprefix, *lsubstr, *prefixend, *substrend;
80
81 + if (json)
82 + fstrstr = strcasestr;
83 strcpy(buf, text);
84 /* separate input text into tokens to be matched individually */
85 for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " "))
86 @@ -464,7 +482,19 @@ insert:
87 break;
88 case XK_Return:
89 case XK_KP_Enter:
90 - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
91 + if (sel && sel->json) {
92 + if (json_is_object(sel->json)) {
93 + listjson(sel->json);
94 + text[0] = '\0';
95 + match();
96 + drawmenu();
97 + break;
98 + } else {
99 + puts(json_string_value(sel->json));
100 + }
101 + } else {
102 + puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
103 + }
104 if (!(ev->state & ControlMask)) {
105 cleanup();
106 exit(0);
107 @@ -519,32 +549,71 @@ paste(void)
108 }
109
110 static void
111 +readjson(const char *path)
112 +{
113 + json_error_t jerr;
114 +
115 + if (!(json = json_load_file(path, 0, &jerr)))
116 + die("%s @ line: %i - %s", jerr.text, jerr.line, path);
117 +}
118 +
119 +static void
120 +listjson(json_t *obj)
121 +{
122 + void *iter;
123 + unsigned imax = 0;
124 + unsigned tmpmax = 0;
125 + struct item *item;
126 +
127 + items_ln = 0;
128 + iter = json_object_iter(obj);
129 + while (iter) {
130 + item = itemnew();
131 + item->text = (char*) json_object_iter_key(iter);
132 + item->json = json_object_iter_value(iter);
133 + item->out = 0;
134 + drw_font_getexts(drw->fonts, item->text, strlen(item->text),
135 + &tmpmax, NULL);
136 + if (tmpmax > inputw) {
137 + inputw = tmpmax;
138 + imax = items_ln - 1;
139 + }
140 + iter = json_object_iter_next(obj, iter);
141 + }
142 + if (items)
143 + items[items_ln].text = NULL;
144 + inputw = items ? TEXTW(items[imax].text) : 0;
145 + lines = MIN(lines, items_ln - 1);
146 +}
147 +
148 +static void
149 readstdin(void)
150 {
151 char buf[sizeof text], *p;
152 - size_t i, imax = 0, size = 0;
153 + size_t i;
154 + unsigned int imax = 0;
155 unsigned int tmpmax = 0;
156 + struct item *item;
157
158 /* read each line from stdin and add it to the item list */
159 for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
160 - if (i + 1 >= size / sizeof *items)
161 - if (!(items = realloc(items, (size += BUFSIZ))))
162 - die("cannot realloc %u bytes:", size);
163 + item = itemnew();
164 if ((p = strchr(buf, '\n')))
165 *p = '\0';
166 - if (!(items[i].text = strdup(buf)))
167 + if (!(item->text = strdup(buf)))
168 die("cannot strdup %u bytes:", strlen(buf) + 1);
169 - items[i].out = 0;
170 + item->json = NULL;
171 + item->out = 0;
172 drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL);
173 if (tmpmax > inputw) {
174 inputw = tmpmax;
175 - imax = i;
176 + imax = items_ln - 1;
177 }
178 }
179 if (items)
180 - items[i].text = NULL;
181 + items[items_ln].text = NULL;
182 inputw = items ? TEXTW(items[imax].text) : 0;
183 - lines = MIN(lines, i);
184 + lines = MIN(lines, items_ln);
185 }
186
187 static void
188 @@ -689,8 +758,9 @@ setup(void)
189 static void
190 usage(void)
191 {
192 - fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
193 - " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
194 + fputs("usage: dmenu [-bfiv] [-j json-file] [-l lines] [-p prompt]\n"
195 + " [-fn font] [-m monitor] [-nb color] [-nf color]\n"
196 + " [-sb color] [-sf color] [-w windowid]\n", stderr);
197 exit(1);
198 }
199
200 @@ -715,6 +785,8 @@ main(int argc, char *argv[])
201 } else if (i + 1 == argc)
202 usage();
203 /* these options take one argument */
204 + else if (!strcmp(argv[i], "-j"))
205 + readjson(argv[++i]);
206 else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */
207 lines = atoi(argv[++i]);
208 else if (!strcmp(argv[i], "-m"))
209 @@ -759,9 +831,15 @@ main(int argc, char *argv[])
210
211 if (fast && !isatty(0)) {
212 grabkeyboard();
213 - readstdin();
214 + if (json)
215 + listjson(json);
216 + else
217 + readstdin();
218 } else {
219 - readstdin();
220 + if (json)
221 + listjson(json);
222 + else
223 + readstdin();
224 grabkeyboard();
225 }
226 setup();