aboutsummaryrefslogtreecommitdiffstats
path: root/dmenu.c
diff options
context:
space:
mode:
authorterminaldweller <thabogre@gmail.com>2022-04-22 06:17:11 +0000
committerterminaldweller <thabogre@gmail.com>2022-04-22 06:17:11 +0000
commita00ff69b44e0bac8e453ce34a2b7346dde283433 (patch)
tree14b478addca650aa2249347dae65a735cb2982f3 /dmenu.c
parentadded center patch (diff)
downloaddmenu-a00ff69b44e0bac8e453ce34a2b7346dde283433.tar.gz
dmenu-a00ff69b44e0bac8e453ce34a2b7346dde283433.zip
added dynamic patch
Diffstat (limited to 'dmenu.c')
-rw-r--r--dmenu.c68
1 files changed, 62 insertions, 6 deletions
diff --git a/dmenu.c b/dmenu.c
index e940e57..3dfbeb8 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -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();