mirror of
https://github.com/mintycube/dmenu.git
synced 2024-10-22 14:05:48 +02:00
Refactoring highlight and fuzzyhighlight patches
Follow-up on pull request #16 this change refactors and combines the highlight and fuzzy highlight patches into one highlight function. Overall it does not make any sense using: - fuzzy highlighting when exact matching is used or - exact highlighting when fuzzy matching is used As such it makes sense to combine the two such that: - exact highlighting is used when exact matching is used and - fuzzy highlighting is used when fuzzy matching is used The FUZZYHIGHLIGHT_PATCH toggle has been removed in favour of HIGHLIGHT_PATCH. The FUZZYMATCH_PATCH toggle controls whether fuzzy matching is enabled. Enable both FUZZYMATCH_PATCH and HIGHLIGHT_PATCH to enable fuzzy highlighting. Additionally the fuzzy highlight patch only supported single-byte characters and would break when encountering multi-byte UTF-8 characters. This was reported ref. #24. This refactoring includes a change to work out the UTF-8 character length for a given character rather than assuming that every character uses one byte.
This commit is contained in:
parent
af373aa1cc
commit
e74a659468
@ -67,10 +67,10 @@ static const unsigned int alphas[][3] = {
|
||||
#if MORECOLOR_PATCH
|
||||
[SchemeMid] = { OPAQUE, baralpha, borderalpha },
|
||||
#endif // MORECOLOR_PATCH
|
||||
#if HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH
|
||||
#if HIGHLIGHT_PATCH
|
||||
[SchemeSelHighlight] = { OPAQUE, baralpha, borderalpha },
|
||||
[SchemeNormHighlight] = { OPAQUE, baralpha, borderalpha },
|
||||
#endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH
|
||||
#endif // HIGHLIGHT_PATCH
|
||||
#if HIGHPRIORITY_PATCH
|
||||
[SchemeHp] = { OPAQUE, baralpha, borderalpha },
|
||||
#endif // HIGHPRIORITY_PATCH
|
||||
@ -100,10 +100,10 @@ char *colors[][2] = {
|
||||
#if MORECOLOR_PATCH
|
||||
[SchemeMid] = { "#eeeeee", "#770000" },
|
||||
#endif // MORECOLOR_PATCH
|
||||
#if HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH
|
||||
#if HIGHLIGHT_PATCH
|
||||
[SchemeSelHighlight] = { "#ffc978", "#005577" },
|
||||
[SchemeNormHighlight] = { "#ffc978", "#222222" },
|
||||
#endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH
|
||||
#endif // HIGHLIGHT_PATCH
|
||||
#if HIGHPRIORITY_PATCH
|
||||
[SchemeHp] = { "#bbbbbb", "#333333" },
|
||||
#endif // HIGHPRIORITY_PATCH
|
||||
|
26
dmenu.c
26
dmenu.c
@ -55,10 +55,10 @@ enum {
|
||||
#if MORECOLOR_PATCH
|
||||
SchemeMid,
|
||||
#endif // MORECOLOR_PATCH
|
||||
#if HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH
|
||||
#if HIGHLIGHT_PATCH
|
||||
SchemeNormHighlight,
|
||||
SchemeSelHighlight,
|
||||
#endif // HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH
|
||||
#endif // HIGHLIGHT_PATCH
|
||||
#if HIGHPRIORITY_PATCH
|
||||
SchemeHp,
|
||||
#endif // HIGHPRIORITY_PATCH
|
||||
@ -330,11 +330,11 @@ drawitem(struct item *item, int x, int y, int w)
|
||||
case 'p':
|
||||
drw_setscheme(drw, scheme[SchemePurple]);
|
||||
break;
|
||||
#if HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH
|
||||
#if HIGHLIGHT_PATCH
|
||||
case 'h':
|
||||
drw_setscheme(drw, scheme[SchemeNormHighlight]);
|
||||
break;
|
||||
#endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH
|
||||
#endif // HIGHLIGHT_PATCH
|
||||
case 's':
|
||||
drw_setscheme(drw, scheme[SchemeSel]);
|
||||
break;
|
||||
@ -366,11 +366,11 @@ drawitem(struct item *item, int x, int y, int w)
|
||||
case 'p':
|
||||
drw_setscheme(drw, scheme[SchemePurple]);
|
||||
break;
|
||||
#if HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH
|
||||
#if HIGHLIGHT_PATCH
|
||||
case 'h':
|
||||
drw_setscheme(drw, scheme[SchemeNormHighlight]);
|
||||
break;
|
||||
#endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH
|
||||
#endif // HIGHLIGHT_PATCH
|
||||
case 's':
|
||||
drw_setscheme(drw, scheme[SchemeSel]);
|
||||
break;
|
||||
@ -471,13 +471,13 @@ drawitem(struct item *item, int x, int y, int w)
|
||||
, True
|
||||
#endif // PANGO_PATCH
|
||||
);
|
||||
#if HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH
|
||||
#if HIGHLIGHT_PATCH
|
||||
#if EMOJI_HIGHLIGHT_PATCH
|
||||
drawhighlights(item, output + iscomment, x + ((iscomment == 6) ? temppadding : 0), y, w);
|
||||
#else
|
||||
drawhighlights(item, x, y, w);
|
||||
#endif // EMOJI_HIGHLIGHT_PATCH
|
||||
#endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH
|
||||
#endif // HIGHLIGHT_PATCH
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -1383,7 +1383,7 @@ paste(void)
|
||||
|
||||
#if ALPHA_PATCH
|
||||
static void
|
||||
xinitvisual()
|
||||
xinitvisual(void)
|
||||
{
|
||||
XVisualInfo *infos;
|
||||
XRenderPictFormat *fmt;
|
||||
@ -1912,9 +1912,9 @@ usage(void)
|
||||
#if XYW_PATCH
|
||||
" [-X xoffset] [-Y yoffset] [-W width]" // (arguments made upper case due to conflicts)
|
||||
#endif // XYW_PATCH
|
||||
#if HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH
|
||||
#if HIGHLIGHT_PATCH
|
||||
"\n [-nhb color] [-nhf color] [-shb color] [-shf color]" // highlight colors
|
||||
#endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH
|
||||
#endif // HIGHLIGHT_PATCH
|
||||
#if SEPARATOR_PATCH
|
||||
"\n [-d separator] [-D separator]"
|
||||
#endif // SEPARATOR_PATCH
|
||||
@ -2096,7 +2096,7 @@ main(int argc, char *argv[])
|
||||
else if (!strcmp(argv[i], "-hp"))
|
||||
hpitems = tokenize(argv[++i], ",", &hplength);
|
||||
#endif // HIGHPRIORITY_PATCH
|
||||
#if HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH
|
||||
#if HIGHLIGHT_PATCH
|
||||
else if (!strcmp(argv[i], "-nhb")) /* normal hi background color */
|
||||
colors[SchemeNormHighlight][ColBg] = argv[++i];
|
||||
else if (!strcmp(argv[i], "-nhf")) /* normal hi foreground color */
|
||||
@ -2105,7 +2105,7 @@ main(int argc, char *argv[])
|
||||
colors[SchemeSelHighlight][ColBg] = argv[++i];
|
||||
else if (!strcmp(argv[i], "-shf")) /* selected hi foreground color */
|
||||
colors[SchemeSelHighlight][ColFg] = argv[++i];
|
||||
#endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH
|
||||
#endif // HIGHLIGHT_PATCH
|
||||
#if CARET_WIDTH_PATCH
|
||||
else if (!strcmp(argv[i], "-cw")) /* sets caret witdth */
|
||||
caret_width = atoi(argv[++i]);
|
||||
|
11
drw.c
11
drw.c
@ -9,7 +9,7 @@
|
||||
#include "drw.h"
|
||||
#include "util.h"
|
||||
|
||||
#if !PANGO_PATCH
|
||||
#if !PANGO_PATCH || HIGHLIGHT_PATCH
|
||||
#define UTF_INVALID 0xFFFD
|
||||
#define UTF_SIZ 4
|
||||
|
||||
@ -61,6 +61,15 @@ utf8decode(const char *c, long *u, size_t clen)
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#if HIGHLIGHT_PATCH
|
||||
size_t
|
||||
utf8len(const char *c)
|
||||
{
|
||||
long utf8codepoint = 0;
|
||||
return utf8decode(c, &utf8codepoint, UTF_SIZ);
|
||||
}
|
||||
#endif // HIGHLIGHT_PATCH
|
||||
#endif // PANGO_PATCH
|
||||
|
||||
Drw *
|
||||
|
4
drw.h
4
drw.h
@ -68,6 +68,10 @@ unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int
|
||||
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
|
||||
#endif // PANGO_PATCH
|
||||
|
||||
#if HIGHLIGHT_PATCH
|
||||
size_t utf8len(const char *c);
|
||||
#endif // HIGHLIGHT_PATCH
|
||||
|
||||
/* Colorscheme abstraction */
|
||||
#if ALPHA_PATCH
|
||||
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha);
|
||||
|
@ -1,66 +0,0 @@
|
||||
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)
|
||||
#endif // EMOJI_HIGHLIGHT_PATCH
|
||||
{
|
||||
int i, indent;
|
||||
char *highlight;
|
||||
char c;
|
||||
|
||||
#if EMOJI_HIGHLIGHT_PATCH
|
||||
char *itemtext = output;
|
||||
#elif TSV_PATCH && !SEPARATOR_PATCH
|
||||
char *itemtext = item->stext;
|
||||
#else
|
||||
char *itemtext = item->text;
|
||||
#endif // TSV_PATCH
|
||||
|
||||
if (!(strlen(itemtext) && strlen(text)))
|
||||
return;
|
||||
|
||||
/* Do not highlight items scheduled for output */
|
||||
#if MULTI_SELECTION_PATCH
|
||||
if (issel(item->id))
|
||||
return;
|
||||
#else
|
||||
if (item->out)
|
||||
return;
|
||||
#endif // MULTI_SELECTION_PATCH
|
||||
|
||||
drw_setscheme(drw, scheme[item == sel
|
||||
? SchemeSelHighlight
|
||||
: SchemeNormHighlight]);
|
||||
for (i = 0, highlight = itemtext; *highlight && text[i];) {
|
||||
#if FUZZYMATCH_PATCH
|
||||
if (!fstrncmp(&(*highlight), &text[i], 1))
|
||||
#else
|
||||
if (*highlight == text[i])
|
||||
#endif // FUZZYMATCH_PATCH
|
||||
{
|
||||
/* get indentation */
|
||||
c = *highlight;
|
||||
*highlight = '\0';
|
||||
indent = TEXTW(itemtext) - lrpad;
|
||||
*highlight = c;
|
||||
|
||||
/* highlight character */
|
||||
c = highlight[1];
|
||||
highlight[1] = '\0';
|
||||
drw_text(
|
||||
drw,
|
||||
x + indent + (lrpad / 2),
|
||||
y,
|
||||
MIN(maxw - indent - lrpad, TEXTW(highlight) - lrpad),
|
||||
bh, 0, highlight, 0
|
||||
#if PANGO_PATCH
|
||||
, True
|
||||
#endif // PANGO_PATCH
|
||||
);
|
||||
highlight[1] = c;
|
||||
i++;
|
||||
}
|
||||
highlight++;
|
||||
}
|
||||
}
|
@ -7,6 +7,13 @@ drawhighlights(struct item *item, int x, int y, int maxw)
|
||||
{
|
||||
char restorechar, tokens[sizeof text], *highlight, *token;
|
||||
int indentx, highlightlen;
|
||||
|
||||
#if FUZZYMATCH_PATCH
|
||||
char c;
|
||||
int i, indent;
|
||||
int utf8charlen;
|
||||
#endif // FUZZYMATCH_PATCH
|
||||
|
||||
#if EMOJI_HIGHLIGHT_PATCH
|
||||
char *itemtext = output;
|
||||
#elif TSV_PATCH && !SEPARATOR_PATCH
|
||||
@ -15,6 +22,9 @@ drawhighlights(struct item *item, int x, int y, int maxw)
|
||||
char *itemtext = item->text;
|
||||
#endif // EMOJI_HIGHLIGHT_PATCH | TSV_PATCH
|
||||
|
||||
if (!(strlen(itemtext) && strlen(text)))
|
||||
return;
|
||||
|
||||
/* Do not highlight items scheduled for output */
|
||||
#if MULTI_SELECTION_PATCH
|
||||
if (issel(item->id))
|
||||
@ -25,6 +35,45 @@ drawhighlights(struct item *item, int x, int y, int maxw)
|
||||
#endif // MULTI_SELECTION_PATCH
|
||||
|
||||
drw_setscheme(drw, scheme[item == sel ? SchemeSelHighlight : SchemeNormHighlight]);
|
||||
|
||||
#if FUZZYMATCH_PATCH
|
||||
if (fuzzy) {
|
||||
for (i = 0, highlight = itemtext; *highlight && text[i];) {
|
||||
utf8charlen = utf8len(highlight);
|
||||
#if FUZZYMATCH_PATCH
|
||||
if (!fstrncmp(&(*highlight), &text[i], utf8charlen))
|
||||
#else
|
||||
if (*highlight == text[i])
|
||||
#endif // FUZZYMATCH_PATCH
|
||||
{
|
||||
/* get indentation */
|
||||
c = *highlight;
|
||||
*highlight = '\0';
|
||||
indent = TEXTW(itemtext) - lrpad;
|
||||
*highlight = c;
|
||||
|
||||
/* highlight character */
|
||||
c = highlight[utf8charlen];
|
||||
highlight[utf8charlen] = '\0';
|
||||
drw_text(
|
||||
drw,
|
||||
x + indent + (lrpad / 2),
|
||||
y,
|
||||
MIN(maxw - indent - lrpad, TEXTW(highlight) - lrpad),
|
||||
bh, 0, highlight, 0
|
||||
#if PANGO_PATCH
|
||||
, True
|
||||
#endif // PANGO_PATCH
|
||||
);
|
||||
highlight[utf8charlen] = c;
|
||||
i += utf8charlen;
|
||||
}
|
||||
highlight++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif // FUZZYMATCH_PATCH
|
||||
|
||||
strcpy(tokens, text);
|
||||
for (token = strtok(tokens, " "); token; token = strtok(NULL, " ")) {
|
||||
highlight = fstrstr(itemtext, token);
|
||||
|
@ -1,9 +1,7 @@
|
||||
#if CENTER_PATCH
|
||||
#include "center.c"
|
||||
#endif
|
||||
#if FUZZYHIGHLIGHT_PATCH
|
||||
#include "fuzzyhighlight.c"
|
||||
#elif HIGHLIGHT_PATCH
|
||||
#if HIGHLIGHT_PATCH
|
||||
#include "highlight.c"
|
||||
#endif
|
||||
#if FUZZYMATCH_PATCH
|
||||
|
@ -43,7 +43,7 @@ readxresources(void)
|
||||
if (XrmGetResource(xdb, "dmenu.bordercolor", "*", &type, &xval))
|
||||
colors[SchemeBorder][ColBg] = strdup(xval.addr);
|
||||
#endif // BORDER_PATCH
|
||||
#if HIGHLIGHT_PATCH || FUZZYHIGHLIGHT_PATCH
|
||||
#if HIGHLIGHT_PATCH
|
||||
if (XrmGetResource(xdb, "dmenu.selhlbackground", "*", &type, &xval))
|
||||
colors[SchemeSelHighlight][ColBg] = strdup(xval.addr);
|
||||
if (XrmGetResource(xdb, "dmenu.selhlforeground", "*", &type, &xval))
|
||||
@ -52,7 +52,7 @@ readxresources(void)
|
||||
colors[SchemeNormHighlight][ColBg] = strdup(xval.addr);
|
||||
if (XrmGetResource(xdb, "dmenu.hlforeground", "*", &type, &xval))
|
||||
colors[SchemeNormHighlight][ColFg] = strdup(xval.addr);
|
||||
#endif // HIGHLIGHT_PATCH | FUZZYHIGHLIGHT_PATCH
|
||||
#endif // HIGHLIGHT_PATCH
|
||||
#if HIGHPRIORITY_PATCH
|
||||
if (XrmGetResource(xdb, "dmenu.hpbackground", "*", &type, &xval))
|
||||
colors[SchemeHp][ColBg] = strdup(xval.addr);
|
||||
|
@ -57,12 +57,6 @@
|
||||
*/
|
||||
#define EMOJI_HIGHLIGHT_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/
|
||||
*/
|
||||
#define FUZZYHIGHLIGHT_PATCH 0
|
||||
|
||||
/* This patch adds support for fuzzy-matching to dmenu, allowing users to type non-consecutive
|
||||
* portions of the string to be matched.
|
||||
* https://tools.suckless.org/dmenu/patches/fuzzymatch/
|
||||
@ -89,8 +83,13 @@
|
||||
#define GRIDNAV_PATCH 0
|
||||
|
||||
/* This patch highlights the individual characters of matched text for each dmenu list entry.
|
||||
* The fuzzy highlight patch takes precedence over this patch.
|
||||
* If combined with the fuzzymatch patch then fuzzy highlight will be used for highlighting
|
||||
* depending on whether fuzzy matching is enabled.
|
||||
*
|
||||
* Known issue: highlighting does not work properly when pango markup is used
|
||||
*
|
||||
* https://tools.suckless.org/dmenu/patches/highlight/
|
||||
* https://tools.suckless.org/dmenu/patches/fuzzyhighlight/
|
||||
*/
|
||||
#define HIGHLIGHT_PATCH 0
|
||||
|
||||
@ -216,6 +215,8 @@
|
||||
* A long term fix for the libXft library is pending approval of this pull request:
|
||||
* https://gitlab.freedesktop.org/xorg/lib/libxft/-/merge_requests/1
|
||||
*
|
||||
* Known issue: not compatible with the scroll patch
|
||||
*
|
||||
* Also see:
|
||||
* https://developer.gnome.org/pygtk/stable/pango-markup-language.html
|
||||
* https://github.com/StillANixRookie/dmenu-pango
|
||||
@ -302,6 +303,9 @@
|
||||
|
||||
/* This patch adds support for text scrolling and no longer appends '...' for long input as
|
||||
* it can handle long text.
|
||||
*
|
||||
* Known issue: not compatible with the pango patch
|
||||
*
|
||||
* https://tools.suckless.org/dmenu/patches/scroll/
|
||||
*/
|
||||
#define SCROLL_PATCH 0
|
||||
|
Loading…
Reference in New Issue
Block a user