From 12b69656a7e4df69df73f45e9993503ffc41e248 Mon Sep 17 00:00:00 2001 From: speedie Date: Tue, 16 May 2023 18:54:26 +0200 Subject: [PATCH] add support for marking items (ie. multi selection) --- docs/spmenu.conf | 7 +++++++ keybinds.h | 1 + libs/arg.c | 28 ++++++++++++++++++++++++++++ libs/arg.h | 1 + libs/conf/config.h | 1 + libs/draw.c | 4 ++++ spmenu.c | 14 ++++++++++++++ 7 files changed, 56 insertions(+) diff --git a/docs/spmenu.conf b/docs/spmenu.conf index e5ffae8..59938ac 100644 --- a/docs/spmenu.conf +++ b/docs/spmenu.conf @@ -290,6 +290,13 @@ spmenu = { function = "selectitem"; argument = "0"; }, + // Ctrl+Enter: Mark input + { mode = -1; + modifier = "Ctrl"; + key = "Enter"; + function = "markitem"; + argument = "0"; + }, // Tab: Tab complete { mode = -1; modifier = "None"; diff --git a/keybinds.h b/keybinds.h index 94a0d93..1f8a394 100644 --- a/keybinds.h +++ b/keybinds.h @@ -12,6 +12,7 @@ static Key keys[] = { */ { -1, 0, XK_Return, selectitem, {.i = +1 } }, { -1, Shift, XK_Return, selectitem, {0} }, + { -1, Ctrl, XK_Return, markitem, {0} }, { -1, 0, XK_Tab, complete, {0} }, { -1, Ctrl, XK_v, paste, {.i = 2 } }, { -1, Ctrl|Shift, XK_v, paste, {.i = 1 } }, diff --git a/libs/arg.c b/libs/arg.c index a2e3887..e8fc1a8 100644 --- a/libs/arg.c +++ b/libs/arg.c @@ -240,6 +240,27 @@ void backspace(Arg *arg) { drawmenu(); } +void markitem(Arg *arg) { + if (sel && is_selected(sel->index)) { + for (int i = 0; i < sel_size; i++) { + if (sel_index[i] == sel->index) { + sel_index[i] = -1; + } + } + } else { + for (int i = 0; i < sel_size; i++) { + if (sel_index[i] == -1) { + sel_index[i] = sel->index; + return; + } + } + + sel_size++; + sel_index = realloc(sel_index, (sel_size + 1) * sizeof(int)); + sel_index[sel_size - 1] = sel->index; + } +} + void selectitem(Arg *arg) { char *selection; @@ -257,6 +278,13 @@ void selectitem(Arg *arg) { selection = text; } + for (int i = 0; i < sel_size; i++) { + if (sel_index[i] != -1 && (!sel || sel->index != sel_index[i])) { + puts(items[sel_index[i]].text); + savehistory(items[sel_index[i]].text); + } + } + if (!selection) return; diff --git a/libs/arg.h b/libs/arg.h index b9006f8..e6ab450 100644 --- a/libs/arg.h +++ b/libs/arg.h @@ -26,6 +26,7 @@ static void deleteword(Arg *arg); static void movecursor(Arg *arg); static void navhistory(Arg *arg); static void backspace(Arg *arg); +static void markitem(Arg *arg); static void selectitem(Arg *arg); static void quit(Arg *arg); static void complete(Arg *arg); diff --git a/libs/conf/config.h b/libs/conf/config.h index baf46ad..c511042 100644 --- a/libs/conf/config.h +++ b/libs/conf/config.h @@ -352,6 +352,7 @@ static FuncList fl[] = { { "navhistory", navhistory }, { "backspace", backspace }, { "selectitem", selectitem }, + { "markitem", markitem }, { "quit", quit }, { "complete", complete }, { "setimgsize", setimgsize }, diff --git a/libs/draw.c b/libs/draw.c index 5ebd14c..b13d096 100644 --- a/libs/draw.c +++ b/libs/draw.c @@ -71,6 +71,10 @@ int drawitemtext(struct item *item, int x, int y, int w) { } } + if (is_selected(item->index)) { + memcpy(scm, scheme[SchemeItemSel], sizeof(scm)); + } + // apply extra padding if ((selitem && !priitem) && lines) { leftpadding += selitempadding; diff --git a/spmenu.c b/spmenu.c index 4c5fc54..a12e801 100644 --- a/spmenu.c +++ b/spmenu.c @@ -157,6 +157,8 @@ static size_t cursor; static struct item *items = NULL, *backup_items, *list_items; static struct item *matches, *matchend; static struct item *prev, *curr, *next, *sel; +static int *sel_index = NULL; +static unsigned int sel_size = 0; static int screen; static int itemn = 0; @@ -224,6 +226,7 @@ static Clr **scheme; static Clr textclrs[256]; // declare functions +static int is_selected(size_t index); static void calcoffsets(void); static void recalculatenumbers(void); static void usage(void); @@ -288,6 +291,16 @@ static char *(*fstrstr)(const char *, const char *) = cistrstr; #include "libs/event.h" #include "libs/event.c" +int is_selected(size_t index) { + for (int i = 0; i < sel_size; i++) { + if (sel_index[i] == index) { + return 1; + } + } + + return 0; +} + void appenditem(struct item *item, struct item **list, struct item **last) { if (*last) (*last)->right = item; @@ -382,6 +395,7 @@ void cleanup(void) { drw_free(drw); XSync(dpy, False); XCloseDisplay(dpy); + free(sel_index); } char * cistrstr(const char *h, const char *n) {