Adding dynamic options patch

This commit is contained in:
bakkeby 2020-08-05 12:27:15 +02:00
parent ee3e48fe0b
commit 73d2405635
9 changed files with 111 additions and 3 deletions

View File

@ -15,7 +15,7 @@ Refer to [https://tools.suckless.org/dmenu/](https://tools.suckless.org/dmenu/)
### Changelog:
2020-08-05 - Added the grid patch
2020-08-05 - Added the grid and dynamic options patches
2020-06-13 - Added the pango patch
@ -51,6 +51,9 @@ Refer to [https://tools.suckless.org/dmenu/](https://tools.suckless.org/dmenu/)
- enables color emoji in dmenu by removing a workaround for a BadLength error in the Xft library when color glyphs are used
- enabling this will crash dmenu on encountering such glyphs unless you also have an updated Xft library that can handle them
- [dynamic_options](https://tools.suckless.org/dmenu/patches/dynamicoptions/)
- adds a flag (`-dy`) which makes dmenu run the command given to it whenever input is changed with the current input as the last argument and update the option list according to the output of that command
- [fuzzyhighlight](https://tools.suckless.org/dmenu/patches/fuzzyhighlight/)
- intended to be combined with the fuzzymatch patch, this makes it so that fuzzy matches are highlighted

View File

@ -32,6 +32,9 @@ static const char *fonts[] =
};
#endif // PANGO_PATCH
static const char *prompt = NULL; /* -p option; prompt to the left of input field */
#if DYNAMIC_OPTIONS_PATCH
static const char *dynamic = NULL; /* -dy option; dynamic command to run on input change */
#endif // DYNAMIC_OPTIONS_PATCH
#if ALPHA_PATCH
static const unsigned int baralpha = 0xd0;

31
dmenu.c
View File

@ -449,6 +449,11 @@ grabkeyboard(void)
static void
match(void)
{
#if DYNAMIC_OPTIONS_PATCH
if (dynamic && *dynamic)
refreshoptions();
#endif // DYNAMIC_OPTIONS_PATCH
#if FUZZYMATCH_PATCH
if (fuzzy) {
fuzzymatch();
@ -494,8 +499,13 @@ match(void)
for (i = 0; i < tokc; i++)
if (!fstrstr(item->text, tokv[i]))
break;
#if DYNAMIC_OPTIONS_PATCH
if (i != tokc && !(dynamic && *dynamic)) /* not all tokens match */
continue;
#else
if (i != tokc) /* not all tokens match */
continue;
#endif // DYNAMIC_OPTIONS_PATCH
/* exact matches go first, then prefixes, then substrings */
if (!tokc || !fstrncmp(text, item->text, textsize))
appenditem(item, &matches, &matchend);
@ -936,7 +946,7 @@ readstdin(void)
#endif // PASSWORD_PATCH
/* 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, stdin); i++) {
if (i + 1 >= size / sizeof *items)
if (!(items = realloc(items, (size += BUFSIZ))))
die("cannot realloc %u bytes:", size);
@ -1265,9 +1275,12 @@ usage(void)
#endif // GRID_PATCH
"[-l lines] [-p prompt] [-fn font] [-m monitor]"
"\n [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]"
#if ALPHA_PATCH || BORDER_PATCH || INITIALTEXT_PATCH || LINE_HEIGHT_PATCH || NAVHISTORY_PATCH || XYW_PATCH
#if ALPHA_PATCH || BORDER_PATCH || INITIALTEXT_PATCH || LINE_HEIGHT_PATCH || NAVHISTORY_PATCH || XYW_PATCH || DYNAMIC_OPTIONS_PATCH
"\n "
#endif
#if DYNAMIC_OPTIONS_PATCH
" [ -dy command]"
#endif // DYNAMIC_OPTIONS_PATCH
#if ALPHA_PATCH
" [ -o opacity]"
#endif // ALPHA_PATCH
@ -1418,6 +1431,10 @@ main(int argc, char *argv[])
#endif // FUZZYHIGHLIGHT_PATCH
else if (!strcmp(argv[i], "-w")) /* embedding window id */
embed = argv[++i];
#if DYNAMIC_OPTIONS_PATCH
else if (!strcmp(argv[i], "-dy")) /* dynamic command to run */
dynamic = argv[++i];
#endif // DYNAMIC_OPTIONS_PATCH
#if BORDER_PATCH
else if (!strcmp(argv[i], "-bw")) /* border width around dmenu */
border_width = atoi(argv[++i]);
@ -1486,9 +1503,19 @@ main(int argc, char *argv[])
#else
if (fast && !isatty(0)) {
grabkeyboard();
#if DYNAMIC_OPTIONS_PATCH
if (!(dynamic && *dynamic))
readstdin();
#else
readstdin();
#endif // DYNAMIC_OPTIONS_PATCH
} else {
#if DYNAMIC_OPTIONS_PATCH
if (!(dynamic && *dynamic))
readstdin();
#else
readstdin();
#endif // DYNAMIC_OPTIONS_PATCH
grabkeyboard();
}
#endif // NON_BLOCKING_STDIN_PATCH

56
patch/dynamicoptions.c Normal file
View File

@ -0,0 +1,56 @@
static void
refreshoptions()
{
int dynlen = strlen(dynamic);
char* cmd= malloc(dynlen + strlen(text) + 2);
if (cmd == NULL)
die("malloc:");
sprintf(cmd, "%s %s", dynamic, text);
FILE *stream = popen(cmd, "r");
if (!stream)
die("popen(%s):", cmd);
readstream(stream);
int pc = pclose(stream);
if (pc == -1)
die("pclose:");
free(cmd);
curr = sel = items;
}
static void
readstream(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, stream); i++) {
if (i + 1 >= size / sizeof *items)
if (!(items = realloc(items, (size += BUFSIZ))))
die("cannot realloc %u bytes:", size);
if ((p = strchr(buf, '\n')))
*p = '\0';
if (!(items[i].text = strdup(buf)))
die("cannot strdup %u bytes:", strlen(buf) + 1);
items[i].out = 0;
#if PANGO_PATCH
drw_font_getexts(drw->font, buf, strlen(buf), &tmpmax, NULL, True);
#else
drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL);
#endif // PANGO_PATCH
if (tmpmax > inputw) {
inputw = tmpmax;
imax = i;
}
}
if (items)
items[i].text = NULL;
#if PANGO_PATCH
inputw = items ? TEXTWM(items[imax].text) : 0;
#else
inputw = items ? TEXTW(items[imax].text) : 0;
#endif // PANGO_PATCH
if (!dynamic || !*dynamic)
lines = MIN(lines, i);
}

2
patch/dynamicoptions.h Normal file
View File

@ -0,0 +1,2 @@
static void refreshoptions();
static void readstream(FILE* stream);

View File

@ -7,6 +7,9 @@
#if FUZZYMATCH_PATCH
#include "fuzzymatch.c"
#endif
#if DYNAMIC_OPTIONS_PATCH
#include "dynamicoptions.c"
#endif
#if MOUSE_SUPPORT_PATCH
#include "mousesupport.c"
#endif

View File

@ -1,3 +1,6 @@
#if DYNAMIC_OPTIONS_PATCH
#include "dynamicoptions.h"
#endif
#if NON_BLOCKING_STDIN_PATCH
#include "nonblockingstdin.h"
#endif

View File

@ -28,7 +28,11 @@ readstdin(void)
die("cannot strdup %u bytes:", strlen(buf)+1);
if (strlen(item->text) > max) {
max = strlen(maxstr = item->text);
#if PANGO_PATCH
inputw = maxstr ? TEXTWM(maxstr) : 0;
#else
inputw = maxstr ? TEXTW(maxstr) : 0;
#endif // PANGO_PATCH
}
*end = item;
end = &item->next;

View File

@ -31,6 +31,13 @@
*/
#define COLOR_EMOJI_PATCH 0
/* This patch adds a flag (-dy) which makes dmenu run the command given to it whenever input
* is changed with the current input as the last argument and update the option list according
* to the output of that command.
* https://tools.suckless.org/dmenu/patches/dynamicoptions/
*/
#define DYNAMIC_OPTIONS_PATCH 0
/* This patch make it so that fuzzy matches gets highlighted and is therefore meant
* to be used together with the fuzzymatch patch.
* https://tools.suckless.org/dmenu/patches/fuzzyhighlight/