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_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();