Introduction
Introduction Statistics Contact Development Disclaimer Help
dmenu-dynamicoptions-5.0.diff - sites - public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log
Files
Refs
---
dmenu-dynamicoptions-5.0.diff (5263B)
---
1 From f70735c476c25da46f9e44b835ac967e0dfa4d85 Mon Sep 17 00:00:00 2001
2 From: Ziad EL KHOURY HANNA <[email protected]>
3 Date: Mon, 29 Nov 2021 17:36:35 +0100
4 Subject: [PATCH] add `-dy` flag for dynamic menu updating
5
6 `-dy` flag makes dmenu run the command given to it whenever input is
7 changed with the current input as the last argument and update the
8 option list according to the output of that command.
9
10 Based on dynamic options patch by ttmx <[email protected]>.
11 Adds proper quoting of the given command.
12 Adds option to man file documentation.
13 ---
14 config.def.h | 1 +
15 dmenu.1 | 5 ++++
16 dmenu.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++-----
17 3 files changed, 70 insertions(+), 6 deletions(-)
18
19 diff --git a/config.def.h b/config.def.h
20 index 1edb647..035b877 100644
21 --- a/config.def.h
22 +++ b/config.def.h
23 @@ -7,6 +7,7 @@ static const char *fonts[] = {
24 "monospace:size=10"
25 };
26 static const char *prompt = NULL; /* -p option; prompt to th…
27 +static const char *dynamic = NULL; /* -dy option; dynamic comm…
28 static const char *colors[SchemeLast][2] = {
29 /* fg bg */
30 [SchemeNorm] = { "#bbbbbb", "#222222" },
31 diff --git a/dmenu.1 b/dmenu.1
32 index 323f93c..1ae3fe3 100644
33 --- a/dmenu.1
34 +++ b/dmenu.1
35 @@ -22,6 +22,8 @@ dmenu \- dynamic menu
36 .IR color ]
37 .RB [ \-w
38 .IR windowid ]
39 +.RB [ \-dy
40 +.IR command ]
41 .P
42 .BR dmenu_run " ..."
43 .SH DESCRIPTION
44 @@ -80,6 +82,9 @@ prints version information to stdout, then exits.
45 .TP
46 .BI \-w " windowid"
47 embed into windowid.
48 +.TP
49 +.BI \-dy " command"
50 +runs command whenever input changes to update menu items.
51 .SH USAGE
52 dmenu is completely controlled by the keyboard. Items are selected usi…
53 arrow keys, page up, page down, home, and end.
54 diff --git a/dmenu.c b/dmenu.c
55 index 65f25ce..6780122 100644
56 --- a/dmenu.c
57 +++ b/dmenu.c
58 @@ -44,6 +44,7 @@ static struct item *items = NULL;
59 static struct item *matches, *matchend;
60 static struct item *prev, *curr, *next, *sel;
61 static int mon = -1, screen;
62 +static unsigned int max_lines = 0;
63
64 static Atom clip, utf8;
65 static Display *dpy;
66 @@ -210,6 +211,47 @@ grabkeyboard(void)
67 die("cannot grab keyboard");
68 }
69
70 +static void readstdin(FILE* stream);
71 +
72 +static void
73 +refreshoptions()
74 +{
75 + int dynlen = strlen(dynamic);
76 + int cmdlen = dynlen + 4;
77 + char *cmd;
78 + char *c;
79 + char *t = text;
80 + while (*t)
81 + cmdlen += *t++ == '\'' ? 4 : 1;
82 + cmd = malloc(cmdlen);
83 + if (cmd == NULL)
84 + die("cannot malloc %u bytes:", cmdlen);
85 + strcpy(cmd, dynamic);
86 + t = text;
87 + c = cmd + dynlen;
88 + *(c++) = ' ';
89 + *(c++) = '\'';
90 + while (*t) {
91 + // prefix ' with '\'
92 + if (*t == '\'') {
93 + *(c++) = '\'';
94 + *(c++) = '\\';
95 + *(c++) = '\'';
96 + }
97 + *(c++) = *(t++);
98 + }
99 + *(c++) = '\'';
100 + *(c++) = 0;
101 + FILE *stream = popen(cmd, "r");
102 + if (!stream)
103 + die("could not popen dynamic command (%s):", cmd);
104 + readstdin(stream);
105 + int r = pclose(stream);
106 + if (r == -1)
107 + die("could not pclose dynamic command");
108 + free(cmd);
109 +}
110 +
111 static void
112 match(void)
113 {
114 @@ -221,6 +263,16 @@ match(void)
115 size_t len, textsize;
116 struct item *item, *lprefix, *lsubstr, *prefixend, *substrend;
117
118 + if (dynamic) {
119 + refreshoptions();
120 + matches = matchend = NULL;
121 + for (item = items; item && item->text; item++)
122 + appenditem(item, &matches, &matchend);
123 + curr = sel = matches;
124 + calcoffsets();
125 + return;
126 + }
127 +
128 strcpy(buf, text);
129 /* separate input text into tokens to be matched individually */
130 for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NU…
131 @@ -519,14 +571,14 @@ paste(void)
132 }
133
134 static void
135 -readstdin(void)
136 +readstdin(FILE* stream)
137 {
138 char buf[sizeof text], *p;
139 size_t i, imax = 0, size = 0;
140 unsigned int tmpmax = 0;
141
142 /* read each line from stdin and add it to the item list */
143 - for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
144 + for (i = 0; fgets(buf, sizeof buf, stream); i++) {
145 if (i + 1 >= size / sizeof *items)
146 if (!(items = realloc(items, (size += BUFSIZ))))
147 die("cannot realloc %u bytes:", size);
148 @@ -544,7 +596,7 @@ readstdin(void)
149 if (items)
150 items[i].text = NULL;
151 inputw = items ? TEXTW(items[imax].text) : 0;
152 - lines = MIN(lines, i);
153 + lines = MIN(max_lines, i);
154 }
155
156 static void
157 @@ -690,7 +742,8 @@ static void
158 usage(void)
159 {
160 fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] […
161 - " [-nb color] [-nf color] [-sb color] [-sf co…
162 + " [-nb color] [-nf color] [-sb color] [-sf co…
163 + " [-dy command]\n", stderr);
164 exit(1);
165 }
166
167 @@ -733,6 +786,8 @@ main(int argc, char *argv[])
168 colors[SchemeSel][ColFg] = argv[++i];
169 else if (!strcmp(argv[i], "-w")) /* embedding window …
170 embed = argv[++i];
171 + else if (!strcmp(argv[i], "-dy")) /* dynamic command t…
172 + dynamic = argv[++i] && *argv[i] ? argv[i] : NUL…
173 else
174 usage();
175
176 @@ -757,11 +812,14 @@ main(int argc, char *argv[])
177 die("pledge");
178 #endif
179
180 + max_lines = lines;
181 if (fast && !isatty(0)) {
182 grabkeyboard();
183 - readstdin();
184 + if (!dynamic)
185 + readstdin(stdin);
186 } else {
187 - readstdin();
188 + if (!dynamic)
189 + readstdin(stdin);
190 grabkeyboard();
191 }
192 setup();
193 --
194 2.34.1
195
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.