dmenu-dynamicoptions-20200526-410003e0.diff (3728B)
1 From 410003e0d776f4038befbc3d2483a75c7e59b38f Mon Sep 17 00:00:00 2001 2 From: Tiago Teles <tiago.sequeira.teles@gmail.com> 3 Date: Tue, 26 May 2020 18:49:13 +0100 4 Subject: [PATCH] dynamic menu updating added '-dy $command' will run `$command 5 $currentinput` on input change and replace the options on dmenu with the 6 output of said command. 7 8 --- 9 config.def.h | 1 + 10 dmenu.c | 43 ++++++++++++++++++++++++++++++++++++------- 11 2 files changed, 37 insertions(+), 7 deletions(-) 12 13 diff --git a/config.def.h b/config.def.h 14 index 1edb6477..035b8777 100644 15 --- a/config.def.h 16 +++ b/config.def.h 17 @@ -7,6 +7,7 @@ static const char *fonts[] = { 18 "monospace:size=10" 19 }; 20 static const char *prompt = NULL; /* -p option; prompt to the left of input field */ 21 +static const char *dynamic = NULL; /* -dy option; dynamic command to run on input change */ 22 static const char *colors[SchemeLast][2] = { 23 /* fg bg */ 24 [SchemeNorm] = { "#bbbbbb", "#222222" }, 25 diff --git a/dmenu.c b/dmenu.c 26 index 6b8f51b5..2d7f2178 100644 27 --- a/dmenu.c 28 +++ b/dmenu.c 29 @@ -210,9 +210,33 @@ grabkeyboard(void) 30 die("cannot grab keyboard"); 31 } 32 33 +static void readstdin(FILE* stream); 34 + 35 +static void 36 +refreshoptions(){ 37 + int dynlen = strlen(dynamic); 38 + char* cmd= malloc(dynlen + strlen(text)+2); 39 + if(!cmd || cmd == NULL) 40 + die("malloc:"); 41 + sprintf(cmd,"%s %s",dynamic, text); 42 + FILE *stream = popen(cmd, "r"); 43 + if(!stream) 44 + die("popen(%s):",cmd); 45 + readstdin(stream); 46 + int pc = pclose(stream); 47 + if(pc == -1) 48 + die("pclose:"); 49 + free(cmd); 50 + curr = sel = items; 51 +} 52 + 53 static void 54 match(void) 55 { 56 + if(dynamic && *dynamic){ 57 + refreshoptions(); 58 + } 59 + 60 static char **tokv = NULL; 61 static int tokn = 0; 62 63 @@ -234,7 +258,7 @@ match(void) 64 for (i = 0; i < tokc; i++) 65 if (!fstrstr(item->text, tokv[i])) 66 break; 67 - if (i != tokc) /* not all tokens match */ 68 + if (i != tokc && !(dynamic && *dynamic)) /* not all tokens match */ 69 continue; 70 /* exact matches go first, then prefixes, then substrings */ 71 if (!tokc || !fstrncmp(text, item->text, textsize)) 72 @@ -519,14 +543,14 @@ paste(void) 73 } 74 75 static void 76 -readstdin(void) 77 +readstdin(FILE* stream) 78 { 79 char buf[sizeof text], *p; 80 size_t i, imax = 0, size = 0; 81 unsigned int tmpmax = 0; 82 83 /* read each line from stdin and add it to the item list */ 84 - for (i = 0; fgets(buf, sizeof buf, stdin); i++) { 85 + for (i = 0; fgets(buf, sizeof buf, stream); i++) { 86 if (i + 1 >= size / sizeof *items) 87 if (!(items = realloc(items, (size += BUFSIZ)))) 88 die("cannot realloc %u bytes:", size); 89 @@ -544,7 +568,8 @@ readstdin(void) 90 if (items) 91 items[i].text = NULL; 92 inputw = items ? TEXTW(items[imax].text) : 0; 93 - lines = MIN(lines, i); 94 + if (!dynamic || !*dynamic) 95 + lines = MIN(lines, i); 96 } 97 98 static void 99 @@ -683,7 +708,7 @@ static void 100 usage(void) 101 { 102 fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" 103 - " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); 104 + " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n" "[-dy command]\n", stderr); 105 exit(1); 106 } 107 108 @@ -726,6 +751,8 @@ main(int argc, char *argv[]) 109 colors[SchemeSel][ColFg] = argv[++i]; 110 else if (!strcmp(argv[i], "-w")) /* embedding window id */ 111 embed = argv[++i]; 112 + else if (!strcmp(argv[i], "-dy")) /* dynamic command to run */ 113 + dynamic = argv[++i]; 114 else 115 usage(); 116 117 @@ -754,9 +781,11 @@ main(int argc, char *argv[]) 118 119 if (fast && !isatty(0)) { 120 grabkeyboard(); 121 - readstdin(); 122 + if(!(dynamic && *dynamic)) 123 + readstdin(stdin); 124 } else { 125 - readstdin(); 126 + if(!(dynamic && *dynamic)) 127 + readstdin(stdin); 128 grabkeyboard(); 129 } 130 setup(); 131 -- 132 2.26.2 133