From 9b806fa9c071de052fa6c033fc474f922065eb4a Mon Sep 17 00:00:00 2001 From: speedie Date: Thu, 9 Mar 2023 10:10:29 +0100 Subject: [PATCH] add high priority --- docs/docs.md | 5 +++++ docs/example.Xresources | 4 ++++ libs/argv.c | 15 +++++++++++++++ libs/colors.h | 4 ++++ libs/draw.c | 6 ++++++ libs/schemes.h | 2 ++ libs/sort.c | 22 ++++++++++++++++++++++ libs/sort.h | 2 ++ libs/xresources.h | 8 ++++++++ options.h | 5 +++++ spmenu.1 | 14 +++++++++++++- spmenu.c | 29 ++++++++++++++++++++++++++--- 12 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 libs/sort.c create mode 100644 libs/sort.h diff --git a/docs/docs.md b/docs/docs.md index 62956bb..1774690 100644 --- a/docs/docs.md +++ b/docs/docs.md @@ -55,6 +55,7 @@ See a list below for a list. - spmenu -bw - Width of the border. 0 will disable the border - spmenu -so - Sort matches - spmenu -nso - Don't sort matches +- spmenu -pri priority - Specify a list of items that take priority - spmenu -s - Use case-sensitive matching - spmenu -i - Use case-insensitive matching - spmenu -nm - Start spmenu in normal mode @@ -99,6 +100,10 @@ See a list below for a list. - spmenu -nib color - Set the normal item background color - spmenu -sif color - Set the selected item foreground color - spmenu -sib color - Set the selected item background color +- spmenu -npf color - Set the normal item (high priority) foreground color +- spmenu -npb color - Set the normal item (high priority) background color +- spmenu -spf color - Set the selected item (high priority) foreground color +- spmenu -spb color - Set the selected item (high priority) background color - spmenu -pfg color - Set the prompt foreground color - spmenu -pbg color - Set the prompt background color - spmenu -ifg color - Set input foreground color diff --git a/docs/example.Xresources b/docs/example.Xresources index 2b8d82e..1a3fa78 100644 --- a/docs/example.Xresources +++ b/docs/example.Xresources @@ -4,6 +4,10 @@ spmenu.col_itemnormfg: #bbbbbb spmenu.col_itemnormbg: #222222 spmenu.col_itemselfg: #eeeeee spmenu.col_itemselbg: #35638A +spmenu.col_itemnormprifg: #bbbbbb +spmenu.col_itemnormpribg: #222222 +spmenu.col_itemselprifg: #eeeeee +spmenu.col_itemselpribg: #35638A spmenu.col_menubgcolor: #222222 spmenu.col_promptfg: #eeeeee spmenu.col_promptbg: #35526b diff --git a/libs/argv.c b/libs/argv.c index 99913fc..786761d 100644 --- a/libs/argv.c +++ b/libs/argv.c @@ -141,6 +141,8 @@ readargs(int argc, char *argv[]) menupaddingv = atoi(argv[++i]); } else if (!strcmp(argv[i], "-hp")) { menupaddingh = atoi(argv[++i]); + } else if (!strcmp(argv[i], "-pri")) { + parse_hpitems(argv[++i]); } else if (!strcmp(argv[i], "-ig")) { imagegaps = atoi(argv[++i]); } else if (!strcmp(argv[i], "-la")) { @@ -208,6 +210,14 @@ readargs(int argc, char *argv[]) colors[SchemeItemSel][ColFg] = argv[++i]; } else if (!strcmp(argv[i], "-sib")) { /* selected item background color */ colors[SchemeItemSel][ColBg] = argv[++i]; + } else if (!strcmp(argv[i], "-npf")) { /* normal item priority foreground color */ + colors[SchemeItemNormPri][ColFg] = argv[++i]; + } else if (!strcmp(argv[i], "-npb")) { /* normal item priority background color */ + colors[SchemeItemNormPri][ColBg] = argv[++i]; + } else if (!strcmp(argv[i], "-spf")) { /* selected item priority foreground color */ + colors[SchemeItemSelPri][ColFg] = argv[++i]; + } else if (!strcmp(argv[i], "-spb")) { /* selected item priority background color */ + colors[SchemeItemSelPri][ColBg] = argv[++i]; } else if (!strcmp(argv[i], "-mbg")) { /* menu color */ colors[SchemeMenu][ColBg] = argv[++i]; } else if (!strcmp(argv[i], "-pfg")) { /* prompt fg color */ @@ -307,6 +317,7 @@ usage(void) "spmenu -bw Width of the border. 0 will disable the border\n" "spmenu -so Sort matches\n" "spmenu -nso Don't sort matches\n" + "spmenu -pri Specify a list of items that take priority\n" "spmenu -s Use case-sensitive matching\n" "spmenu -i Use case-insensitive matching\n" "spmenu -nm Start spmenu in normal mode\n" @@ -354,6 +365,10 @@ usage(void) "spmenu -nib Set the normal item background color\n" "spmenu -sif Set the selected item foreground color\n" "spmenu -sib Set the selected item background color\n" + "spmenu -npf Set the normal item (high priority) foreground color\n" + "spmenu -npb Set the normal item (high priority) background color\n" + "spmenu -spf Set the selected item (high priority) foreground color\n" + "spmenu -spb Set the selected item (high priority) background color\n" "spmenu -pfg Set the prompt foreground color\n" "spmenu -pbg Set the prompt background color\n" "spmenu -ifg Set input foreground color\n" diff --git a/libs/colors.h b/libs/colors.h index d514a86..c8b5853 100644 --- a/libs/colors.h +++ b/libs/colors.h @@ -7,6 +7,8 @@ static const unsigned int alphas[][3] = { [SchemeRArrow] = { fgalpha, bgalpha, borderalpha }, [SchemeItemNorm] = { fgalpha, bgalpha, borderalpha }, [SchemeItemSel] = { fgalpha, bgalpha, borderalpha }, + [SchemeItemNormPri] = { fgalpha, bgalpha, borderalpha }, + [SchemeItemSelPri] = { fgalpha, bgalpha, borderalpha }, [SchemeMenu] = { fgalpha, bgalpha, borderalpha }, [SchemeInput] = { fgalpha, bgalpha, borderalpha }, [SchemePrompt] = { fgalpha, bgalpha, borderalpha }, @@ -25,6 +27,8 @@ static const char *colors[SchemeLast][2] = { [SchemeRArrow] = { col_rarrowfg, col_rarrowbg }, [SchemeItemNorm] = { col_itemnormfg, col_itemnormbg }, [SchemeItemSel] = { col_itemselfg, col_itemselbg }, + [SchemeItemNormPri] = { col_itemnormprifg, col_itemnormpribg }, + [SchemeItemSelPri] = { col_itemselprifg, col_itemselpribg }, [SchemeInput] = { col_inputfg, col_inputbg, }, [SchemeMenu] = { NULL, col_menubgcolor }, [SchemePrompt] = { col_promptfg, col_promptbg }, diff --git a/libs/draw.c b/libs/draw.c index 5aeb081..0b96b7a 100644 --- a/libs/draw.c +++ b/libs/draw.c @@ -50,8 +50,14 @@ drawitem(struct item *item, int x, int y, int w) if (item == sel) { memcpy(scm, scheme[SchemeItemSel], sizeof(scm)); + + if (item->hp) + memcpy(scm, scheme[SchemeItemSelPri], sizeof(scm)); } else { memcpy(scm, scheme[SchemeItemNorm], sizeof(scm)); + + if (item->hp) + memcpy(scm, scheme[SchemeItemNormPri], sizeof(scm)); } /* set scheme */ diff --git a/libs/schemes.h b/libs/schemes.h index 7789bc1..e7d915d 100644 --- a/libs/schemes.h +++ b/libs/schemes.h @@ -4,6 +4,8 @@ enum { SchemeLArrow, SchemeRArrow, SchemeItemNorm, SchemeItemSel, + SchemeItemNormPri, + SchemeItemSelPri, SchemeMenu, SchemeInput, SchemePrompt, diff --git a/libs/sort.c b/libs/sort.c new file mode 100644 index 0000000..683c976 --- /dev/null +++ b/libs/sort.c @@ -0,0 +1,22 @@ +int +str_compar(const void *s0_in, const void *s1_in) +{ + const char *s0 = *(const char **)s0_in; + const char *s1 = *(const char **)s1_in; + return fstrncmp == strncasecmp ? strcasecmp(s0, s1) : strcmp(s0, s1); +} + +void +parse_hpitems(char *src) +{ + int n = 0; + char *t; + + for (t = strtok(src, ","); t; t = strtok(NULL, ",")) { + if (hplength + 1 >= n) { + if (!(hpitems = realloc(hpitems, (n += 8) * sizeof *hpitems))) + die("Unable to realloc %zu bytes\n", n * sizeof *hpitems); + } + hpitems[hplength++] = t; + } +} diff --git a/libs/sort.h b/libs/sort.h new file mode 100644 index 0000000..d450e32 --- /dev/null +++ b/libs/sort.h @@ -0,0 +1,2 @@ +static int str_compar(const void *s0_in, const void *s1_in); +static void parse_hpitems(char *src); diff --git a/libs/xresources.h b/libs/xresources.h index 318a5da..bb9b01e 100644 --- a/libs/xresources.h +++ b/libs/xresources.h @@ -13,6 +13,10 @@ ResourcePref resources[] = { { "col_itemnormbg", STRING, &col_itemnormbg }, { "col_itemselfg", STRING, &col_itemselfg }, { "col_itemselbg", STRING, &col_itemselbg }, + { "col_itemnormprifg", STRING, &col_itemnormprifg }, + { "col_itemnormpribg", STRING, &col_itemnormpribg }, + { "col_itemselprifg", STRING, &col_itemselprifg }, + { "col_itemselpribg", STRING, &col_itemselpribg }, { "col_inputbg", STRING, &col_inputbg }, { "col_inputfg", STRING, &col_inputfg }, { "col_menubgcolor", STRING, &col_menubgcolor }, @@ -33,16 +37,20 @@ ResourcePref resources[] = { { "color4", STRING, &col_larrowfg }, { "color4", STRING, &col_rarrowfg }, { "color10", STRING, &col_itemnormfg }, + { "color10", STRING, &col_itemnormprifg }, { "color10", STRING, &col_inputfg }, { "color0", STRING, &col_itemnormbg }, + { "color0", STRING, &col_itemnormpribg }, { "color0", STRING, &col_menubgcolor }, { "color0", STRING, &col_larrowbg }, { "color0", STRING, &col_rarrowbg }, { "color0", STRING, &col_itemselfg }, + { "color0", STRING, &col_itemselprifg }, { "color0", STRING, &col_inputbg }, { "color12", STRING, &col_promptbg }, { "color0", STRING, &col_promptfg }, { "color6", STRING, &col_itemselbg }, + { "color6", STRING, &col_itemselpribg }, { "color6", STRING, &col_bordercolor }, { "color0", STRING, &col_numfgcolor }, { "color5", STRING, &col_numbgcolor }, diff --git a/options.h b/options.h index 5910b75..4a9eab4 100644 --- a/options.h +++ b/options.h @@ -48,6 +48,7 @@ static int casesensitive = 0; /* Case-sensitive by default? (0/1) static int preselected = 0; /* Which line should spmenu preselect? */ static int accuratewidth = 1; /* Enable accurate width. May have a performance hit if you are matching a lot of items at once */ static int fuzzy = 1; /* Whether or not to enable fuzzy matching by default */ +static char **hpitems = NULL; /* High priority items */ /* Line options */ static int lineheight = 5; /* Line height (0: Calculate automatically) */ @@ -79,6 +80,10 @@ static char col_itemnormfg[] = "#bbbbbb"; /* Normal foreground item co static char col_itemnormbg[] = "#222222"; /* Normal background item color */ static char col_itemselfg[] = "#eeeeee"; /* Selected foreground item color */ static char col_itemselbg[] = "#35638A"; /* Selected background item color */ +static char col_itemnormprifg[] = "#bbbbbb"; /* Normal foreground item (high priority) color */ +static char col_itemnormpribg[] = "#222222"; /* Normal background item (high priority) color */ +static char col_itemselprifg[] = "#eeeeee"; /* Selected foreground item (high priority) color */ +static char col_itemselpribg[] = "#35638A"; /* Selected background item (high priority) color */ /* Input colors */ static char col_inputbg[] = "#222222"; /* Input field background color */ diff --git a/spmenu.1 b/spmenu.1 index 2dd84b0..b2e194c 100644 --- a/spmenu.1 +++ b/spmenu.1 @@ -14,7 +14,7 @@ . ftr VB CB . ftr VBI CBI .\} -.TH "spmenu" "1" "" "0.2.1" "dynamic menu" +.TH "spmenu" "1" "" "0.2.2" "dynamic menu" .hy .SH spmenu .SS 1. What is spmenu? @@ -103,6 +103,8 @@ spmenu -so - Sort matches .IP \[bu] 2 spmenu -nso - Don\[cq]t sort matches .IP \[bu] 2 +spmenu -pri priority - Specify a list of items that take priority +.IP \[bu] 2 spmenu -s - Use case-sensitive matching .IP \[bu] 2 spmenu -i - Use case-insensitive matching @@ -189,6 +191,16 @@ spmenu -sif color - Set the selected item foreground color .IP \[bu] 2 spmenu -sib color - Set the selected item background color .IP \[bu] 2 +spmenu -npf color - Set the normal item (high priority) foreground color +.IP \[bu] 2 +spmenu -npb color - Set the normal item (high priority) background color +.IP \[bu] 2 +spmenu -spf color - Set the selected item (high priority) foreground +color +.IP \[bu] 2 +spmenu -spb color - Set the selected item (high priority) background +color +.IP \[bu] 2 spmenu -pfg color - Set the prompt foreground color .IP \[bu] 2 spmenu -pbg color - Set the prompt background color diff --git a/spmenu.c b/spmenu.c index cf017b1..79e5df6 100644 --- a/spmenu.c +++ b/spmenu.c @@ -112,6 +112,7 @@ #include "libs/xrdb.h" #include "libs/key.h" #include "libs/mouse.h" +#include "libs/sort.h" static char text[BUFSIZ] = ""; @@ -120,6 +121,7 @@ struct item { char *image; char *ex; struct item *left, *right; + int hp; double distance; }; @@ -132,6 +134,7 @@ typedef struct { } Key; static char numbers[NUMBERSBUFSIZE] = ""; +static int hplength = 0; static char *embed; static int numlockmask = 0; static int bh, mw, mh; @@ -230,6 +233,7 @@ static char *(*fstrstr)(const char *, const char *) = cistrstr; #include "libs/event.c" #include "libs/key.c" #include "libs/mouse.c" +#include "libs/sort.c" #include "libs/draw.c" #include "libs/schemes.c" #include "libs/arg.c" @@ -489,7 +493,8 @@ match(void) char buf[sizeof text], *s; int i, tokc = 0; size_t len, textsize; - struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; + struct item *item, *lhpprefix, *lprefix, *lsubstr, *hpprefixend, *prefixend, *substrend; + strcpy(buf, text); /* separate input text into tokens to be matched individually */ @@ -498,7 +503,7 @@ match(void) die("cannot realloc %u bytes:", tokn * sizeof *tokv); len = tokc ? strlen(tokv[0]) : 0; - matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; + matches = lhpprefix = lprefix = lsubstr = matchend = hpprefixend = prefixend = substrend = NULL; textsize = strlen(text) + 1; for (item = items; item && item->text; item++) { for (i = 0; i < tokc; i++) @@ -509,15 +514,25 @@ match(void) if (!sortmatches) appenditem(item, &matches, &matchend); else { - /* exact matches go first, then prefixes, then substrings */ + /* exact matches go first, then prefixes with high priority, then prefixes, then substrings */ if (!tokc || !fstrncmp(text, item->text, textsize)) appenditem(item, &matches, &matchend); + else if (item->hp && !fstrncmp(tokv[0], item->text, len)) + appenditem(item, &lhpprefix, &hpprefixend); else if (!fstrncmp(tokv[0], item->text, len)) appenditem(item, &lprefix, &prefixend); else appenditem(item, &lsubstr, &substrend); } } + if (lhpprefix) { + if (matches) { + matchend->right = lhpprefix; + lhpprefix->left = matchend; + } else + matches = lhpprefix; + matchend = hpprefixend; + } if (lprefix) { if (matches) { matchend->right = lprefix; @@ -734,6 +749,9 @@ readstdin(void) return; } + if (hpitems && hplength > 0) + qsort(hpitems, hplength, sizeof *hpitems, str_compar); + /* read each line from stdin and add it to the item list */ for (i = 0; fgets(buf, sizeof buf, stdin); i++) { if (i + 1 >= itemsiz) { @@ -745,6 +763,11 @@ readstdin(void) *p = '\0'; if (!(items[i].text = strdup(buf))) die("cannot strdup %u bytes:", strlen(buf) + 1); + p = hpitems == NULL ? NULL : bsearch( + &items[i].text, hpitems, hplength, sizeof *hpitems, + str_compar + ); + items[i].hp = p != NULL; drw_font_getexts(drw->font, buf, strlen(buf), &tmpmax, NULL, True); if (tmpmax > inputw) { inputw = tmpmax;