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