Adding emoji-highlight patch

This commit is contained in:
bakkeby 2021-05-24 13:29:40 +02:00
parent b6103ff6a7
commit 82aa682b40
7 changed files with 287 additions and 28 deletions

View File

@ -26,7 +26,7 @@ dmenu, how to install it and how it works.
### Changelog: ### Changelog:
2021-05-23 - Adding support for `ctrl+v` to paste 2021-05-23 - Adding support for `ctrl+v` to paste and adding emoji-highlight patch
2021-05-17 - Added the restrict return, no sort, gridnav and plain-prompt (listfullwidth) patches 2021-05-17 - Added the restrict return, no sort, gridnav and plain-prompt (listfullwidth) patches
@ -81,6 +81,9 @@ dmenu, how to install it and how it works.
with the current input as the last argument and update the option list according to the with the current input as the last argument and update the option list according to the
output of that command output of that command
- [emoji-highlight](https://tools.suckless.org/dmenu/patches/emoji-highlight/)
- this patch will allow for emojis on the left side with a colored background when selected
- [fuzzyhighlight](https://tools.suckless.org/dmenu/patches/fuzzyhighlight/) - [fuzzyhighlight](https://tools.suckless.org/dmenu/patches/fuzzyhighlight/)
- intended to be combined with the fuzzymatch patch, this makes it so that fuzzy matches are - intended to be combined with the fuzzymatch patch, this makes it so that fuzzy matches are
highlighted highlighted

View File

@ -57,12 +57,11 @@ static const unsigned int alphas[][3] = {
}; };
#endif // ALPHA_PATCH #endif // ALPHA_PATCH
#if XRESOURCES_PATCH static
static char *colors[][2] = #if !XRESOURCES_PATCH
#else const
static const char *colors[][2] =
#endif // XRESOURCES_PATCH #endif // XRESOURCES_PATCH
{ char *colors[][2] = {
/* fg bg */ /* fg bg */
[SchemeNorm] = { "#bbbbbb", "#222222" }, [SchemeNorm] = { "#bbbbbb", "#222222" },
[SchemeSel] = { "#eeeeee", "#005577" }, [SchemeSel] = { "#eeeeee", "#005577" },
@ -77,6 +76,14 @@ static const char *colors[][2] =
#if HIGHPRIORITY_PATCH #if HIGHPRIORITY_PATCH
[SchemeHp] = { "#bbbbbb", "#333333" }, [SchemeHp] = { "#bbbbbb", "#333333" },
#endif // HIGHPRIORITY_PATCH #endif // HIGHPRIORITY_PATCH
#if EMOJI_HIGHLIGHT_PATCH
[SchemeHover] = { "#ffffff", "#353D4B" },
[SchemeGreen] = { "#ffffff", "#52E067" },
[SchemeRed] = { "#ffffff", "#e05252" },
[SchemeYellow] = { "#ffffff", "#e0c452" },
[SchemeBlue] = { "#ffffff", "#5280e0" },
[SchemePurple] = { "#ffffff", "#9952e0" },
#endif // EMOJI_HIGHLIGHT_PATCH
}; };
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ /* -l option; if nonzero, dmenu uses vertical list with given number of lines */
static unsigned int lines = 0; static unsigned int lines = 0;
@ -86,6 +93,7 @@ static unsigned int columns = 0;
#endif // GRID_PATCH #endif // GRID_PATCH
#if LINE_HEIGHT_PATCH #if LINE_HEIGHT_PATCH
static unsigned int lineheight = 0; /* -h option; minimum height of a menu line */ static unsigned int lineheight = 0; /* -h option; minimum height of a menu line */
static unsigned int min_lineheight = 8;
#endif // LINE_HEIGHT_PATCH #endif // LINE_HEIGHT_PATCH
#if NAVHISTORY_PATCH #if NAVHISTORY_PATCH
static unsigned int maxhist = 15; static unsigned int maxhist = 15;

162
dmenu.c
View File

@ -69,6 +69,14 @@ enum {
#if HIGHPRIORITY_PATCH #if HIGHPRIORITY_PATCH
SchemeHp, SchemeHp,
#endif // HIGHPRIORITY_PATCH #endif // HIGHPRIORITY_PATCH
#if EMOJI_HIGHLIGHT_PATCH
SchemeHover,
SchemeGreen,
SchemeYellow,
SchemeBlue,
SchemePurple,
SchemeRed,
#endif // EMOJI_HIGHLIGHT_PATCH
SchemeLast, SchemeLast,
}; /* color schemes */ }; /* color schemes */
@ -142,6 +150,10 @@ static int use_text_input = 0;
#if PRESELECT_PATCH #if PRESELECT_PATCH
static unsigned int preselected = 0; static unsigned int preselected = 0;
#endif // PRESELECT_PATCH #endif // PRESELECT_PATCH
#if EMOJI_HIGHLIGHT_PATCH
static int commented = 0;
static int animated = 0;
#endif // EMOJI_HIGHLIGHT_PATCH
static Atom clip, utf8; static Atom clip, utf8;
#if WMTYPE_PATCH #if WMTYPE_PATCH
@ -279,6 +291,118 @@ 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
char *text = item->stext;
#else
char *text = item->text;
#endif // TSV_PATCH
#if EMOJI_HIGHLIGHT_PATCH
int iscomment = 0;
if (text[0] == '>') {
if (text[1] == '>') {
iscomment = 3;
switch (text[2]) {
case 'r':
drw_setscheme(drw, scheme[SchemeRed]);
break;
case 'g':
drw_setscheme(drw, scheme[SchemeGreen]);
break;
case 'y':
drw_setscheme(drw, scheme[SchemeYellow]);
break;
case 'b':
drw_setscheme(drw, scheme[SchemeBlue]);
break;
case 'p':
drw_setscheme(drw, scheme[SchemePurple]);
break;
#if HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH
case 'h':
drw_setscheme(drw, scheme[SchemeNormHighlight]);
break;
#endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH
case 's':
drw_setscheme(drw, scheme[SchemeSel]);
break;
default:
iscomment = 1;
drw_setscheme(drw, scheme[SchemeNorm]);
break;
}
} else {
drw_setscheme(drw, scheme[SchemeNorm]);
iscomment = 1;
}
} else if (text[0] == ':') {
iscomment = 2;
if (item == sel) {
switch (text[1]) {
case 'r':
drw_setscheme(drw, scheme[SchemeRed]);
break;
case 'g':
drw_setscheme(drw, scheme[SchemeGreen]);
break;
case 'y':
drw_setscheme(drw, scheme[SchemeYellow]);
break;
case 'b':
drw_setscheme(drw, scheme[SchemeBlue]);
break;
case 'p':
drw_setscheme(drw, scheme[SchemePurple]);
break;
#if HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH
case 'h':
drw_setscheme(drw, scheme[SchemeNormHighlight]);
break;
#endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH
case 's':
drw_setscheme(drw, scheme[SchemeSel]);
break;
default:
drw_setscheme(drw, scheme[SchemeSel]);
iscomment = 0;
break;
}
} else {
drw_setscheme(drw, scheme[SchemeNorm]);
}
}
#endif // EMOJI_HIGHLIGHT_PATCH
#if EMOJI_HIGHLIGHT_PATCH
int temppadding = 0;
if (iscomment == 2) {
if (text[2] == ' ') {
temppadding = drw->fonts->h * 3;
animated = 1;
char dest[1000];
strcpy(dest, text);
dest[6] = '\0';
#if LINE_HEIGHT_PATCH
drw_text(drw, x, y, temppadding, MAX(lineheight, bh), temppadding / 2.6, dest + 3, 0);
#else
drw_text(drw, x, y, temppadding, bh, temppadding / 2.6, dest + 3, 0);
#endif // LINE_HEIGHT_PATCH
iscomment = 6;
drw_setscheme(drw, sel == item ? scheme[SchemeHover] : scheme[SchemeNorm]);
}
}
char *output;
if (commented) {
static char onestr[2];
onestr[0] = text[0];
onestr[1] = '\0';
output = onestr;
} else {
output = text;
}
#endif // EMOJI_HIGHLIGHT_PATCH
if (item == sel) if (item == sel)
drw_setscheme(drw, scheme[SchemeSel]); drw_setscheme(drw, scheme[SchemeSel]);
#if HIGHPRIORITY_PATCH #if HIGHPRIORITY_PATCH
@ -298,23 +422,36 @@ drawitem(struct item *item, int x, int y, int w)
else else
drw_setscheme(drw, scheme[SchemeNorm]); drw_setscheme(drw, scheme[SchemeNorm]);
r = drw_text(drw, x, y, w, bh, lrpad / 2 r = drw_text(drw
#if TSV_PATCH #if EMOJI_HIGHLIGHT_PATCH
, item->stext , x + ((iscomment == 6) ? temppadding : 0)
#else #else
, item->text , x
#endif // TSV_PATCH #endif // EMOJI_HIGHLIGHT_PATCH
, y
, w
, bh
#if EMOJI_HIGHLIGHT_PATCH
, commented ? (bh - drw_fontset_getwidth(drw, output)) / 2 : lrpad / 2
#else
, lrpad / 2
#endif // EMOJI_HIGHLIGHT_PATCH
#if EMOJI_HIGHLIGHT_PATCH
, output + iscomment
#else
, text
#endif // EMOJI_HIGHLIGHT_PATCH
, 0 , 0
#if PANGO_PATCH #if PANGO_PATCH
, True , True
#endif // PANGO_PATCH #endif // PANGO_PATCH
); );
#if PANGO_PATCH
#else
r = drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
#endif // PANGO_PATCH
#if HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH #if HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH
#if EMOJI_HIGHLIGHT_PATCH
drawhighlights(item, output + iscomment, x + ((iscomment == 6) ? temppadding : 0), y, w);
#else
drawhighlights(item, x, y, w); drawhighlights(item, x, y, w);
#endif // EMOJI_HIGHLIGHT_PATCH
#endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH #endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH
return r; return r;
} }
@ -1755,7 +1892,7 @@ main(int argc, char *argv[])
#if LINE_HEIGHT_PATCH #if LINE_HEIGHT_PATCH
else if(!strcmp(argv[i], "-h")) { /* minimum height of one menu line */ else if(!strcmp(argv[i], "-h")) { /* minimum height of one menu line */
lineheight = atoi(argv[++i]); lineheight = atoi(argv[++i]);
lineheight = MAX(lineheight,8); /* reasonable default in case of value too small/negative */ lineheight = MAX(lineheight, min_lineheight); /* reasonable default in case of value too small/negative */
} }
#endif // LINE_HEIGHT_PATCH #endif // LINE_HEIGHT_PATCH
else if (!strcmp(argv[i], "-nb")) /* normal background color */ else if (!strcmp(argv[i], "-nb")) /* normal background color */
@ -1847,6 +1984,11 @@ main(int argc, char *argv[])
lrpad = drw->fonts->h; lrpad = drw->fonts->h;
#endif // PANGO_PATCH #endif // PANGO_PATCH
#if LINE_HEIGHT_PATCH
if (lineheight == -1)
lineheight = drw->fonts->h * 2.5;
#endif // LINE_HEIGHT_PATCH
#ifdef __OpenBSD__ #ifdef __OpenBSD__
if (pledge("stdio rpath", NULL) == -1) if (pledge("stdio rpath", NULL) == -1)
die("pledge"); die("pledge");

View File

@ -1,17 +1,29 @@
static void static void
#if EMOJI_HIGHLIGHT_PATCH
drawhighlights(struct item *item, char *output, int x, int y, int maxw)
#else
drawhighlights(struct item *item, int x, int y, int maxw) drawhighlights(struct item *item, int x, int y, int maxw)
#endif // EMOJI_HIGHLIGHT_PATCH
{ {
int i, indent; int i, indent;
char *highlight; char *highlight;
char c; char c;
if (!(strlen(item->text) && strlen(text))) #if EMOJI_HIGHLIGHT_PATCH
char *itemtext = output;
#elif TSV_PATCH
char *itemtext = item->stext;
#else
char *itemtext = item->text;
#endif // TSV_PATCH
if (!(strlen(itemtext) && strlen(text)))
return; return;
drw_setscheme(drw, scheme[item == sel drw_setscheme(drw, scheme[item == sel
? SchemeSelHighlight ? SchemeSelHighlight
: SchemeNormHighlight]); : SchemeNormHighlight]);
for (i = 0, highlight = item->text; *highlight && text[i];) { for (i = 0, highlight = itemtext; *highlight && text[i];) {
#if FUZZYMATCH_PATCH #if FUZZYMATCH_PATCH
if (!fstrncmp(&(*highlight), &text[i], 1)) if (!fstrncmp(&(*highlight), &text[i], 1))
#else #else
@ -21,7 +33,7 @@ drawhighlights(struct item *item, int x, int y, int maxw)
/* get indentation */ /* get indentation */
c = *highlight; c = *highlight;
*highlight = '\0'; *highlight = '\0';
indent = TEXTW(item->text); indent = TEXTW(itemtext);
*highlight = c; *highlight = c;
/* highlight character */ /* highlight character */

View File

@ -1,20 +1,31 @@
static void static void
#if EMOJI_HIGHLIGHT_PATCH
drawhighlights(struct item *item, char *output, int x, int y, int maxw)
#else
drawhighlights(struct item *item, int x, int y, int maxw) drawhighlights(struct item *item, int x, int y, int maxw)
#endif // EMOJI_HIGHLIGHT_PATCH
{ {
char restorechar, tokens[sizeof text], *highlight, *token; char restorechar, tokens[sizeof text], *highlight, *token;
int indentx, highlightlen; int indentx, highlightlen;
#if EMOJI_HIGHLIGHT_PATCH
char *itemtext = output;
#elif TSV_PATCH
char *itemtext = item->stext;
#else
char *itemtext = item->text;
#endif // TSV_PATCH
drw_setscheme(drw, scheme[item == sel ? SchemeSelHighlight : SchemeNormHighlight]); drw_setscheme(drw, scheme[item == sel ? SchemeSelHighlight : SchemeNormHighlight]);
strcpy(tokens, text); strcpy(tokens, text);
for (token = strtok(tokens, " "); token; token = strtok(NULL, " ")) { for (token = strtok(tokens, " "); token; token = strtok(NULL, " ")) {
highlight = fstrstr(item->text, token); highlight = fstrstr(itemtext, token);
while (highlight) { while (highlight) {
// Move item str end, calc width for highlight indent, & restore // Move item str end, calc width for highlight indent, & restore
highlightlen = highlight - item->text; highlightlen = highlight - itemtext;
restorechar = *highlight; restorechar = *highlight;
item->text[highlightlen] = '\0'; itemtext[highlightlen] = '\0';
indentx = TEXTW(item->text); indentx = TEXTW(itemtext);
item->text[highlightlen] = restorechar; itemtext[highlightlen] = restorechar;
// Move highlight str end, draw highlight, & restore // Move highlight str end, draw highlight, & restore
restorechar = highlight[strlen(token)]; restorechar = highlight[strlen(token)];

View File

@ -45,7 +45,17 @@ readxresources(void)
colors[SchemeOut][ColFg] = strdup(xval.addr); colors[SchemeOut][ColFg] = strdup(xval.addr);
else else
colors[SchemeOut][ColFg] = strdup(colors[SchemeOut][ColFg]); colors[SchemeOut][ColFg] = strdup(colors[SchemeOut][ColFg]);
#if FUZZYHIGHLIGHT_PATCH #if MORECOLOR_PATCH
if (XrmGetResource(xdb, "dmenu.midbackground", "*", &type, &xval))
colors[SchemeMid][ColBg] = strdup(xval.addr);
else
colors[SchemeMid][ColBg] = strdup(colors[SchemeMid][ColBg]);
if (XrmGetResource(xdb, "dmenu.midforeground", "*", &type, &xval))
colors[SchemeMid][ColFg] = strdup(xval.addr);
else
colors[SchemeMid][ColFg] = strdup(colors[SchemeMid][ColFg]);
#endif // MORECOLOR_PATCH
#if HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH
if (XrmGetResource(xdb, "dmenu.selhlbackground", "*", &type, &xval)) if (XrmGetResource(xdb, "dmenu.selhlbackground", "*", &type, &xval))
colors[SchemeSelHighlight][ColBg] = strdup(xval.addr); colors[SchemeSelHighlight][ColBg] = strdup(xval.addr);
else else
@ -62,8 +72,67 @@ readxresources(void)
colors[SchemeNormHighlight][ColFg] = strdup(xval.addr); colors[SchemeNormHighlight][ColFg] = strdup(xval.addr);
else else
colors[SchemeNormHighlight][ColFg] = strdup(colors[SchemeNormHighlight][ColFg]); colors[SchemeNormHighlight][ColFg] = strdup(colors[SchemeNormHighlight][ColFg]);
#endif // FUZZYHIGHLIGHT_PATCH #endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH
#if HIGHPRIORITY_PATCH
if (XrmGetResource(xdb, "dmenu.hpbackground", "*", &type, &xval))
colors[SchemeHp][ColBg] = strdup(xval.addr);
else
colors[SchemeHp][ColBg] = strdup(colors[SchemeHp][ColBg]);
if (XrmGetResource(xdb, "dmenu.hpforeground", "*", &type, &xval))
colors[SchemeHp][ColFg] = strdup(xval.addr);
else
colors[SchemeHp][ColFg] = strdup(colors[SchemeHp][ColFg]);
#endif // HIGHPRIORITY_PATCH
#if EMOJI_HIGHLIGHT_PATCH
if (XrmGetResource(xdb, "dmenu.hoverbackground", "*", &type, &xval))
colors[SchemeHover][ColBg] = strdup(xval.addr);
else
colors[SchemeHover][ColBg] = strdup(colors[SchemeHover][ColBg]);
if (XrmGetResource(xdb, "dmenu.hoverforeground", "*", &type, &xval))
colors[SchemeHover][ColFg] = strdup(xval.addr);
else
colors[SchemeHover][ColFg] = strdup(colors[SchemeHover][ColFg]);
if (XrmGetResource(xdb, "dmenu.greenbackground", "*", &type, &xval))
colors[SchemeGreen][ColBg] = strdup(xval.addr);
else
colors[SchemeGreen][ColBg] = strdup(colors[SchemeGreen][ColBg]);
if (XrmGetResource(xdb, "dmenu.greenforeground", "*", &type, &xval))
colors[SchemeGreen][ColFg] = strdup(xval.addr);
else
colors[SchemeGreen][ColFg] = strdup(colors[SchemeGreen][ColFg]);
if (XrmGetResource(xdb, "dmenu.yellowbackground", "*", &type, &xval))
colors[SchemeYellow][ColBg] = strdup(xval.addr);
else
colors[SchemeYellow][ColBg] = strdup(colors[SchemeYellow][ColBg]);
if (XrmGetResource(xdb, "dmenu.yellowforeground", "*", &type, &xval))
colors[SchemeYellow][ColFg] = strdup(xval.addr);
else
colors[SchemeYellow][ColFg] = strdup(colors[SchemeYellow][ColFg]);
if (XrmGetResource(xdb, "dmenu.bluebackground", "*", &type, &xval))
colors[SchemeBlue][ColBg] = strdup(xval.addr);
else
colors[SchemeBlue][ColBg] = strdup(colors[SchemeBlue][ColBg]);
if (XrmGetResource(xdb, "dmenu.blueforeground", "*", &type, &xval))
colors[SchemeBlue][ColFg] = strdup(xval.addr);
else
colors[SchemeBlue][ColFg] = strdup(colors[SchemeBlue][ColFg]);
if (XrmGetResource(xdb, "dmenu.purplebackground", "*", &type, &xval))
colors[SchemePurple][ColBg] = strdup(xval.addr);
else
colors[SchemePurple][ColBg] = strdup(colors[SchemePurple][ColBg]);
if (XrmGetResource(xdb, "dmenu.purpleforeground", "*", &type, &xval))
colors[SchemePurple][ColFg] = strdup(xval.addr);
else
colors[SchemePurple][ColFg] = strdup(colors[SchemePurple][ColFg]);
if (XrmGetResource(xdb, "dmenu.redbackground", "*", &type, &xval))
colors[SchemeRed][ColBg] = strdup(xval.addr);
else
colors[SchemeRed][ColBg] = strdup(colors[SchemeRed][ColBg]);
if (XrmGetResource(xdb, "dmenu.redforeground", "*", &type, &xval))
colors[SchemeRed][ColFg] = strdup(xval.addr);
else
colors[SchemeRed][ColFg] = strdup(colors[SchemeRed][ColFg]);
#endif // EMOJI_HIGHLIGHT_PATCH
XrmDestroyDatabase(xdb); XrmDestroyDatabase(xdb);
} }
} }

View File

@ -43,6 +43,15 @@
*/ */
#define DYNAMIC_OPTIONS_PATCH 0 #define DYNAMIC_OPTIONS_PATCH 0
/* This patch will allow for emojis on the left side with a colored background when selected.
* To test this try running:
* $ echo -e ":b here\n:p there\n:r and here" | ./dmenu -p "Search..." -W 400 -l 20 -i -h -1
* NB: the original patch came embedded with the the xyw patch, the morecolors patch and the
* line height patch and as such is intended to be combined with these.
* https://tools.suckless.org/dmenu/patches/emoji-highlight/
*/
#define EMOJI_HIGHLIGHT_PATCH 0
/* This patch make it so that fuzzy matches gets highlighted and is therefore meant /* This patch make it so that fuzzy matches gets highlighted and is therefore meant
* to be used together with the fuzzymatch patch. * to be used together with the fuzzymatch patch.
* https://tools.suckless.org/dmenu/patches/fuzzyhighlight/ * https://tools.suckless.org/dmenu/patches/fuzzyhighlight/
@ -259,8 +268,10 @@
*/ */
#define REJECTNOMATCH_PATCH 0 #define REJECTNOMATCH_PATCH 0
/* This patch adds a '-r' option which disables Shift-Return and Ctrl-Return. /* This patch adds a '-1' option which disables Shift-Return and Ctrl-Return.
* This guarantees that dmenu will only output one item, and that item was read from stdin. * This guarantees that dmenu will only output one item, and that item was read from stdin.
* The original patch used '-r'. This was changed to '-1' to avoid conflict with the incremental
* patch.
* https://tools.suckless.org/dmenu/patches/restrict-return/ * https://tools.suckless.org/dmenu/patches/restrict-return/
*/ */
#define RESTRICT_RETURN_PATCH 0 #define RESTRICT_RETURN_PATCH 0
@ -304,6 +315,9 @@
* dmenu.foreground : normal foreground color * dmenu.foreground : normal foreground color
* dmenu.selbackground : selected background color * dmenu.selbackground : selected background color
* dmenu.selforeground : selected foreground color * dmenu.selforeground : selected foreground color
*
* See patch/xresources.c for more color settings.
*
* https://tools.suckless.org/dmenu/patches/xresources/ * https://tools.suckless.org/dmenu/patches/xresources/
*/ */
#define XRESOURCES_PATCH 0 #define XRESOURCES_PATCH 0