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