diff options
author | terminaldweller <thabogre@gmail.com> | 2022-04-22 06:17:11 +0000 |
---|---|---|
committer | terminaldweller <thabogre@gmail.com> | 2022-04-22 06:17:11 +0000 |
commit | a00ff69b44e0bac8e453ce34a2b7346dde283433 (patch) | |
tree | 14b478addca650aa2249347dae65a735cb2982f3 /dmenu.c | |
parent | added center patch (diff) | |
download | dmenu-a00ff69b44e0bac8e453ce34a2b7346dde283433.tar.gz dmenu-a00ff69b44e0bac8e453ce34a2b7346dde283433.zip |
added dynamic patch
Diffstat (limited to '')
-rw-r--r-- | dmenu.c | 68 |
1 files changed, 62 insertions, 6 deletions
@@ -62,6 +62,7 @@ static struct item *items = NULL; static struct item *matches, *matchend; static struct item *prev, *curr, *next, *sel; static int mon = -1, screen; +static unsigned int max_lines = 0; static Atom clip, utf8; static Display *dpy; @@ -302,6 +303,45 @@ static void grabkeyboard(void) { die("cannot grab keyboard"); } +static void readstdin(FILE *stream); + +static void refreshoptions() { + int dynlen = strlen(dynamic); + int cmdlen = dynlen + 4; + char *cmd; + char *c; + char *t = text; + while (*t) + cmdlen += *t++ == '\'' ? 4 : 1; + cmd = malloc(cmdlen); + if (cmd == NULL) + die("cannot malloc %u bytes:", cmdlen); + strcpy(cmd, dynamic); + t = text; + c = cmd + dynlen; + *(c++) = ' '; + *(c++) = '\''; + while (*t) { + // prefix ' with '\' + if (*t == '\'') { + *(c++) = '\''; + *(c++) = '\\'; + *(c++) = '\''; + } + *(c++) = *(t++); + } + *(c++) = '\''; + *(c++) = 0; + FILE *stream = popen(cmd, "r"); + if (!stream) + die("could not popen dynamic command (%s):", cmd); + readstdin(stream); + int r = pclose(stream); + if (r == -1) + die("could not pclose dynamic command"); + free(cmd); +} + int compare_distance(const void *a, const void *b) { struct item *da = *(struct item **)a; struct item *db = *(struct item **)b; @@ -398,6 +438,16 @@ static void match(void) { size_t len, textsize; struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; + if (dynamic) { + refreshoptions(); + matches = matchend = NULL; + for (item = items; item && item->text; item++) + appenditem(item, &matches, &matchend); + curr = sel = matches; + calcoffsets(); + return; + } + strcpy(buf, text); /* separate input text into tokens to be matched individually */ for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " ")) @@ -777,13 +827,13 @@ static void paste(void) { drawmenu(); } -static void readstdin(void) { +static void readstdin(FILE *stream) { char buf[sizeof text], *p; size_t i, imax = 0, size = 0; unsigned int tmpmax = 0; /* read each line from stdin and add it to the item list */ - for (i = 0; fgets(buf, sizeof buf, stdin); i++) { + for (i = 0; fgets(buf, sizeof buf, stream); i++) { if (i + 1 >= size / sizeof *items) if (!(items = realloc(items, (size += BUFSIZ)))) die("cannot realloc %u bytes:", size); @@ -814,7 +864,7 @@ static void readstdin(void) { if (items) items[i].text = NULL; inputw = items ? TEXTW(items[imax].text) : 0; - lines = MIN(lines, i); + lines = MIN(max_lines, i); } void resource_load(XrmDatabase db, char *name, enum resource_type rtype, @@ -1009,7 +1059,8 @@ static void usage(void) { fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" " [-nb color] [-nf color] [-sb color] [-sf color]\n" " [-nhb color] [-nhf color] [-shb color] [-shf color]\n" - " [-d separator] [-D separator] [-w windowid]\n", + " [-d separator] [-D separator] [-dy command] [-w " + "windowid]\n", stderr); exit(1); } @@ -1074,6 +1125,8 @@ int main(int argc, char *argv[]) { separator_reverse = argv[i][1] == '|'; } else if (!strcmp(argv[i], "-w")) /* embedding window id */ embed = argv[++i]; + else if (!strcmp(argv[i], "-dy")) /* dynamic command to run */ + dynamic = argv[++i] && *argv[i] ? argv[i] : NULL; else usage(); @@ -1097,11 +1150,14 @@ int main(int argc, char *argv[]) { die("pledge"); #endif + max_lines = lines; if (fast && !isatty(0)) { grabkeyboard(); - readstdin(); + if (!dynamic) + readstdin(stdin); } else { - readstdin(); + if (!dynamic) + readstdin(stdin); grabkeyboard(); } setup(); |