dmenu-json-4.9-r2.diff - sites - public wiki contents of suckless.org | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
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… | |
23 -CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS) | |
24 +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX… | |
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(NU… | |
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 : te… | |
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->t… | |
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->t… | |
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,… | |
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] [… | |
193 - " [-nb color] [-nf color] [-sb color] [-sf co… | |
194 + fputs("usage: dmenu [-bfiv] [-j json-file] [-l lines] [-p promp… | |
195 + " [-fn font] [-m monitor] [-nb color] [-nf co… | |
196 + " [-sb color] [-sf color] [-w windowid]\n", s… | |
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 i… | |
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(); |