Adding separator patch

This patch is simpler than, and superior to, the TSV patch and as
such takes precedence if both are combined.

Also addressed some compatibility issues and compilation errors.
This commit is contained in:
bakkeby 2022-09-05 14:08:27 +02:00
parent 036d2b0d08
commit dc169b1971
9 changed files with 98 additions and 25 deletions

View File

@ -28,7 +28,8 @@ Browsing patches? There is a [map of patches](https://coggle.it/diagram/YjT2DD6j
### Changelog: ### Changelog:
2022-09-05 - Removed the json patch due to maintenance and compatibility reasons 2022-09-05 - Removed the json patch due to maintenance and compatibility reasons, added the
separator patch
2022-09-04 - Added the fzfexpect patch 2022-09-04 - Added the fzfexpect patch
@ -232,6 +233,10 @@ Browsing patches? There is a [map of patches](https://coggle.it/diagram/YjT2DD6j
- this patch adds support for text scrolling - this patch adds support for text scrolling
- it doesn't append `...` for long input anymore as it can handle long text - it doesn't append `...` for long input anymore as it can handle long text
- [separator](https://tools.suckless.org/dmenu/patches/separator/)
- adds `-d` and `-D` flags which separates the input into two halves; one half to be
displayed in dmenu and the other to be printed to stdout
- [symbols](https://tools.suckless.org/dmenu/patches/symbols/) - [symbols](https://tools.suckless.org/dmenu/patches/symbols/)
- allows the symbols, which are printed in dmenu to indicate that either the input is too - allows the symbols, which are printed in dmenu to indicate that either the input is too
long or there are too many options to be shown in dmenu in one line, to be defined long or there are too many options to be shown in dmenu in one line, to be defined

77
dmenu.c
View File

@ -76,9 +76,11 @@ enum {
struct item { struct item {
char *text; char *text;
#if TSV_PATCH #if SEPARATOR_PATCH
char *text_output;
#elif TSV_PATCH
char *stext; char *stext;
#endif // TSV_PATCH #endif // SEPARATOR_PATCH | TSV_PATCH
struct item *left, *right; struct item *left, *right;
#if NON_BLOCKING_STDIN_PATCH #if NON_BLOCKING_STDIN_PATCH
struct item *next; struct item *next;
@ -104,6 +106,11 @@ static char text[BUFSIZ] = "";
static char pipeout[8] = " | dmenu"; static char pipeout[8] = " | dmenu";
#endif // PIPEOUT_PATCH #endif // PIPEOUT_PATCH
static char *embed; static char *embed;
#if SEPARATOR_PATCH
static char separator;
static int separator_greedy;
static int separator_reverse;
#endif // SEPARATOR_PATCH
static int bh, mw, mh; static int bh, mw, mh;
#if XYW_PATCH #if XYW_PATCH
static int dmx = 0, dmy = 0; /* put dmenu at these x and y offsets */ static int dmx = 0, dmy = 0; /* put dmenu at these x and y offsets */
@ -297,7 +304,7 @@ static int
drawitem(struct item *item, int x, int y, int w) drawitem(struct item *item, int x, int y, int w)
{ {
int r; int r;
#if TSV_PATCH #if TSV_PATCH && !SEPARATOR_PATCH
char *text = item->stext; char *text = item->stext;
#else #else
char *text = item->text; char *text = item->text;
@ -644,7 +651,6 @@ drawmenu(void)
#endif // PANGO_PATCH #endif // PANGO_PATCH
); );
} }
fprintf(stderr, "bbbb\n" );
x += w; x += w;
for (item = curr; item != next; item = item->right) { for (item = curr; item != next; item = item->right) {
#if SYMBOLS_PATCH #if SYMBOLS_PATCH
@ -652,14 +658,13 @@ drawmenu(void)
#else #else
stw = TEXTW(">"); stw = TEXTW(">");
#endif // SYMBOLS_PATCH #endif // SYMBOLS_PATCH
#if TSV_PATCH #if TSV_PATCH && !SEPARATOR_PATCH
itw = textw_clamp(item->stext, mw - x - stw - rpad); itw = textw_clamp(item->stext, mw - x - stw - rpad);
#else #else
itw = textw_clamp(item->text, mw - x - stw - rpad); itw = textw_clamp(item->text, mw - x - stw - rpad);
#endif // PANGO_PATCH | TSV_PATCH #endif // TSV_PATCH
x = drawitem(item, x, 0, itw); x = drawitem(item, x, 0, itw);
} }
fprintf(stderr, "ajaj\n" );
if (next) { if (next) {
#if SYMBOLS_PATCH #if SYMBOLS_PATCH
w = TEXTW(symbol_2); w = TEXTW(symbol_2);
@ -680,7 +685,6 @@ drawmenu(void)
); );
} }
} }
#if NUMBERS_PATCH #if NUMBERS_PATCH
drw_setscheme(drw, scheme[SchemeNorm]); drw_setscheme(drw, scheme[SchemeNorm]);
drw_text(drw, mw - rpad, 0, TEXTW(numbers), bh, lrpad / 2, numbers, 0); drw_text(drw, mw - rpad, 0, TEXTW(numbers), bh, lrpad / 2, numbers, 0);
@ -1044,8 +1048,10 @@ keypress(XKeyEvent *ev)
XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
utf8, utf8, win, CurrentTime); utf8, utf8, win, CurrentTime);
return; return;
#if FZFEXPECT_PATCH
case XK_x: expect("ctrl-x", ev); break; case XK_x: expect("ctrl-x", ev); break;
case XK_z: expect("ctrl-z", ev); break; case XK_z: expect("ctrl-z", ev); break;
#endif // FZFEXPECT_PATCH
case XK_Left: case XK_Left:
case XK_KP_Left: case XK_KP_Left:
movewordedge(-1); movewordedge(-1);
@ -1237,12 +1243,22 @@ insert:
printf("%d\n", (sel && !(ev->state & ShiftMask)) ? sel->index : -1); printf("%d\n", (sel && !(ev->state & ShiftMask)) ? sel->index : -1);
#endif // PRINTINDEX_PATCH #endif // PRINTINDEX_PATCH
else else
#if SEPARATOR_PATCH
puts((sel && !(ev->state & ShiftMask)) ? sel->text_output : text);
#else
puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
#endif // SEPARATOR_PATCH
#elif PRINTINDEX_PATCH #elif PRINTINDEX_PATCH
if (print_index) if (print_index)
printf("%d\n", (sel && !(ev->state & ShiftMask)) ? sel->index : -1); printf("%d\n", (sel && !(ev->state & ShiftMask)) ? sel->index : -1);
else else
#if SEPARATOR_PATCH
puts((sel && !(ev->state & ShiftMask)) ? sel->text_output : text);
#else
puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
#endif // SEPARATOR_PATCH
#elif SEPARATOR_PATCH
puts((sel && !(ev->state & ShiftMask)) ? sel->text_output : text);
#else #else
puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
#endif // PIPEOUT_PATCH | PRINTINPUTTEXT_PATCH | PRINTINDEX_PATCH #endif // PIPEOUT_PATCH | PRINTINPUTTEXT_PATCH | PRINTINDEX_PATCH
@ -1402,9 +1418,11 @@ static void
readstdin(void) readstdin(void)
{ {
char *line = NULL; char *line = NULL;
#if TSV_PATCH #if SEPARATOR_PATCH
char *p;
#elif TSV_PATCH
char *buf, *p; char *buf, *p;
#endif // TSV_PATCH #endif // SEPARATOR_PATCH | TSV_PATCH
size_t size = 0; size_t size = 0;
size_t i, junk; size_t i, junk;
@ -1426,13 +1444,26 @@ readstdin(void)
line[len - 1] = '\0'; line[len - 1] = '\0';
items[i].text = line; items[i].text = line;
#if TSV_PATCH #if SEPARATOR_PATCH
buf = strdup(line); if (separator && (p = separator_greedy ?
strrchr(items[i].text, separator) : strchr(items[i].text, separator))) {
*p = '\0';
items[i].text_output = ++p;
} else {
items[i].text_output = items[i].text;
}
if (separator_reverse) {
p = items[i].text;
items[i].text = items[i].text_output;
items[i].text_output = p;
}
#elif TSV_PATCH
if (!(buf = strdup(line)))
die("cannot strdup %u bytes:", strlen(line) + 1);
if ((p = strchr(buf, '\t'))) if ((p = strchr(buf, '\t')))
*p = '\0'; *p = '\0';
if (!(items[i].stext = strdup(buf))) items[i].stext = buf;
die("cannot strdup %zu bytes:", strlen(line) + 1); #endif // SEPARATOR_PATCH | TSV_PATCH
#endif // TSV_PATCH
#if MULTI_SELECTION_PATCH #if MULTI_SELECTION_PATCH
items[i].id = i; /* for multiselect */ items[i].id = i; /* for multiselect */
#if PRINTINDEX_PATCH #if PRINTINDEX_PATCH
@ -1815,7 +1846,7 @@ usage(void)
#endif // GRID_PATCH #endif // GRID_PATCH
"[-l lines] [-p prompt] [-fn font] [-m monitor]" "[-l lines] [-p prompt] [-fn font] [-m monitor]"
"\n [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]" "\n [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]"
#if ALPHA_PATCH || BORDER_PATCH || HIGHPRIORITY_PATCH || INITIALTEXT_PATCH || LINE_HEIGHT_PATCH || NAVHISTORY_PATCH || XYW_PATCH || DYNAMIC_OPTIONS_PATCH || FZFEXPECT_PATCH #if DYNAMIC_OPTIONS_PATCH || FZFEXPECT_PATCH || ALPHA_PATCH || BORDER_PATCH || HIGHPRIORITY_PATCH
"\n " "\n "
#endif #endif
#if DYNAMIC_OPTIONS_PATCH #if DYNAMIC_OPTIONS_PATCH
@ -1833,10 +1864,12 @@ usage(void)
#if HIGHPRIORITY_PATCH #if HIGHPRIORITY_PATCH
" [-hb color] [-hf color] [-hp items]" " [-hb color] [-hf color] [-hp items]"
#endif // HIGHPRIORITY_PATCH #endif // HIGHPRIORITY_PATCH
#if INITIALTEXT_PATCH || LINE_HEIGHT_PATCH || PRESELECT_PATCH || NAVHISTORY_PATCH || XYW_PATCH
"\n "
#endif
#if INITIALTEXT_PATCH #if INITIALTEXT_PATCH
" [-it text]" " [-it text]"
#endif // INITIALTEXT_PATCH #endif // INITIALTEXT_PATCH
"\n "
#if LINE_HEIGHT_PATCH #if LINE_HEIGHT_PATCH
" [-h height]" " [-h height]"
#endif // LINE_HEIGHT_PATCH #endif // LINE_HEIGHT_PATCH
@ -1852,6 +1885,9 @@ usage(void)
#if HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH #if HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH
"\n [-nhb color] [-nhf color] [-shb color] [-shf color]" // highlight colors "\n [-nhb color] [-nhf color] [-shb color] [-shf color]" // highlight colors
#endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH #endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH
#if SEPARATOR_PATCH
"\n [-d separator] [-D separator]"
#endif // SEPARATOR_PATCH
"\n", stderr); "\n", stderr);
exit(1); exit(1);
} }
@ -2031,6 +2067,13 @@ main(int argc, char *argv[])
#endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH #endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH
else if (!strcmp(argv[i], "-w")) /* embedding window id */ else if (!strcmp(argv[i], "-w")) /* embedding window id */
embed = argv[++i]; embed = argv[++i];
#if SEPARATOR_PATCH
else if (!strcmp(argv[i], "-d") || /* field separator */
(separator_greedy = !strcmp(argv[i], "-D"))) {
separator = argv[++i][0];
separator_reverse = argv[i][1] == '|';
}
#endif // SEPARATOR_PATCH
#if PRESELECT_PATCH #if PRESELECT_PATCH
else if (!strcmp(argv[i], "-ps")) /* preselected item */ else if (!strcmp(argv[i], "-ps")) /* preselected item */
preselected = atoi(argv[++i]); preselected = atoi(argv[++i]);

View File

@ -33,7 +33,20 @@ readstream(FILE* stream)
*p = '\0'; *p = '\0';
if (!(items[i].text = strdup(buf))) if (!(items[i].text = strdup(buf)))
die("cannot strdup %u bytes:", strlen(buf) + 1); die("cannot strdup %u bytes:", strlen(buf) + 1);
#if TSV_PATCH #if SEPARATOR_PATCH
if (separator && (p = separator_greedy ?
strrchr(items[i].text, separator) : strchr(items[i].text, separator))) {
*p = '\0';
items[i].text_output = ++p;
} else {
items[i].text_output = items[i].text;
}
if (separator_reverse) {
p = items[i].text;
items[i].text = items[i].text_output;
items[i].text_output = p;
}
#elif TSV_PATCH
if ((p = strchr(buf, '\t'))) if ((p = strchr(buf, '\t')))
*p = '\0'; *p = '\0';
if (!(items[i].stext = strdup(buf))) if (!(items[i].stext = strdup(buf)))

View File

@ -11,7 +11,7 @@ drawhighlights(struct item *item, int x, int y, int maxw)
#if EMOJI_HIGHLIGHT_PATCH #if EMOJI_HIGHLIGHT_PATCH
char *itemtext = output; char *itemtext = output;
#elif TSV_PATCH #elif TSV_PATCH && !SEPARATOR_PATCH
char *itemtext = item->stext; char *itemtext = item->stext;
#else #else
char *itemtext = item->text; char *itemtext = item->text;

View File

@ -9,11 +9,11 @@ drawhighlights(struct item *item, int x, int y, int maxw)
int indentx, highlightlen; int indentx, highlightlen;
#if EMOJI_HIGHLIGHT_PATCH #if EMOJI_HIGHLIGHT_PATCH
char *itemtext = output; char *itemtext = output;
#elif TSV_PATCH #elif TSV_PATCH && !SEPARATOR_PATCH
char *itemtext = item->stext; char *itemtext = item->stext;
#else #else
char *itemtext = item->text; char *itemtext = item->text;
#endif // TSV_PATCH #endif // EMOJI_HIGHLIGHT_PATCH | TSV_PATCH
drw_setscheme(drw, scheme[item == sel ? SchemeSelHighlight : SchemeNormHighlight]); drw_setscheme(drw, scheme[item == sel ? SchemeSelHighlight : SchemeNormHighlight]);
strcpy(tokens, text); strcpy(tokens, text);

2
patch/highpriority.h Normal file
View File

@ -0,0 +1,2 @@
static int arrayhas(char **list, int length, char *item);

View File

@ -1,9 +1,6 @@
#if CENTER_PATCH #if CENTER_PATCH
#include "center.c" #include "center.c"
#endif #endif
#if DYNAMIC_OPTIONS_PATCH
#include "dynamicoptions.c"
#endif
#if FUZZYHIGHLIGHT_PATCH #if FUZZYHIGHLIGHT_PATCH
#include "fuzzyhighlight.c" #include "fuzzyhighlight.c"
#elif HIGHLIGHT_PATCH #elif HIGHLIGHT_PATCH
@ -18,6 +15,9 @@
#if HIGHPRIORITY_PATCH #if HIGHPRIORITY_PATCH
#include "highpriority.c" #include "highpriority.c"
#endif #endif
#if DYNAMIC_OPTIONS_PATCH
#include "dynamicoptions.c"
#endif
#if MULTI_SELECTION_PATCH #if MULTI_SELECTION_PATCH
#include "multiselect.c" #include "multiselect.c"
#endif #endif

View File

@ -4,6 +4,9 @@
#if FZFEXPECT_PATCH #if FZFEXPECT_PATCH
#include "fzfexpect.h" #include "fzfexpect.h"
#endif #endif
#if HIGHPRIORITY_PATCH
#include "highpriority.h"
#endif
#if NON_BLOCKING_STDIN_PATCH #if NON_BLOCKING_STDIN_PATCH
#include "nonblockingstdin.h" #include "nonblockingstdin.h"
#endif #endif

View File

@ -297,6 +297,13 @@
*/ */
#define SCROLL_PATCH 0 #define SCROLL_PATCH 0
/* This patch adds -d and -D flags which separates the input into two halves; one half to be
* displayed in dmenu and the other to be printed to stdout. This patch takes precedence over
* the TSV patch.
* https://tools.suckless.org/dmenu/patches/separator/
*/
#define SEPARATOR_PATCH 0
/* This patch allows the symbols, which are printed in dmenu to indicate that either the input /* This patch allows the symbols, which are printed in dmenu to indicate that either the input
* is too long or there are too many options to be shown in dmenu in one line, to be defined. * is too long or there are too many options to be shown in dmenu in one line, to be defined.
* https://tools.suckless.org/dmenu/patches/symbols/ * https://tools.suckless.org/dmenu/patches/symbols/