From 6a1ed51d47e4ffa847607016a0a03228122cef1e Mon Sep 17 00:00:00 2001 From: bakkeby Date: Sun, 4 Sep 2022 22:33:24 +0200 Subject: [PATCH] Adding fzfexpect patch --- README.md | 5 ++++ dmenu.c | 71 +++++++++++++++++++++++++++++++++++++++++------ patch/fzfexpect.c | 39 ++++++++++++++++++++++++++ patch/fzfexpect.h | 1 + patch/include.c | 3 ++ patch/include.h | 3 ++ patches.def.h | 6 ++++ 7 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 patch/fzfexpect.c create mode 100644 patch/fzfexpect.h diff --git a/README.md b/README.md index 010258f..b215296 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ Browsing patches? There is a [map of patches](https://coggle.it/diagram/YjT2DD6j ### Changelog: +2022-09-04 - Added the fzfexpect patch + 2022-06-21 - Adding barpadding patch and relative input width patch 2022-03-02 - Bump to 5.1 @@ -102,6 +104,9 @@ Browsing patches? There is a [map of patches](https://coggle.it/diagram/YjT2DD6j - adds support for fuzzy-matching to dmenu, allowing users to type non-consecutive portions of the string to be matched + - [fzfexpect](https://github.com/DAFF0D11/dafmenu/blob/master/patches/dmenu-fzfexpect-5.1.diff) + - adds fzf expect functionality in dmenu + - [grid](https://tools.suckless.org/dmenu/patches/grid/) - allows dmenu's entries to be rendered in a grid by adding a new `-g` flag to specify the number of grid columns diff --git a/dmenu.c b/dmenu.c index 7990a3b..4e8803a 100644 --- a/dmenu.c +++ b/dmenu.c @@ -975,6 +975,30 @@ keypress(XKeyEvent *ev) if (ev->state & ControlMask) { switch(ksym) { + #if FZFEXPECT_PATCH + case XK_a: expect("ctrl-a", ev); ksym = XK_Home; break; + case XK_b: expect("ctrl-b", ev); ksym = XK_Left; break; + case XK_c: expect("ctrl-c", ev); ksym = XK_Escape; break; + case XK_d: expect("ctrl-d", ev); ksym = XK_Delete; break; + case XK_e: expect("ctrl-e", ev); ksym = XK_End; break; + case XK_f: expect("ctrl-f", ev); ksym = XK_Right; break; + case XK_g: expect("ctrl-g", ev); ksym = XK_Escape; break; + case XK_h: expect("ctrl-h", ev); ksym = XK_BackSpace; break; + case XK_i: expect("ctrl-i", ev); ksym = XK_Tab; break; + case XK_j: expect("ctrl-j", ev); ksym = XK_Down; break; + case XK_J:/* fallthrough */ + case XK_l: expect("ctrl-l", ev); break; + case XK_m: expect("ctrl-m", ev); /* fallthrough */ + case XK_M: ksym = XK_Return; ev->state &= ~ControlMask; break; + case XK_n: expect("ctrl-n", ev); ksym = XK_Down; break; + case XK_p: expect("ctrl-p", ev); ksym = XK_Up; break; + case XK_o: expect("ctrl-o", ev); break; + case XK_q: expect("ctrl-q", ev); break; + case XK_r: expect("ctrl-r", ev); break; + case XK_s: expect("ctrl-s", ev); break; + case XK_t: expect("ctrl-t", ev); break; + case XK_k: expect("ctrl-k", ev); ksym = XK_Up; break; + #else case XK_a: ksym = XK_Home; break; case XK_b: ksym = XK_Left; break; case XK_c: ksym = XK_Escape; break; @@ -995,24 +1019,45 @@ keypress(XKeyEvent *ev) text[cursor] = '\0'; match(); break; + #endif // FZFEXPECT_PATCH + #if FZFEXPECT_PATCH + case XK_u: expect("ctrl-u", ev); /* delete left */ + #else case XK_u: /* delete left */ + #endif // FZFEXPECT_PATCH insert(NULL, 0 - cursor); break; + #if FZFEXPECT_PATCH + case XK_w: expect("ctrl-w", ev); /* delete word */ + #else case XK_w: /* delete word */ + #endif // FZFEXPECT_PATCH while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) insert(NULL, nextrune(-1) - cursor); while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) insert(NULL, nextrune(-1) - cursor); break; - case XK_y: /* paste selection */ - case XK_Y: - #if CTRL_V_TO_PASTE_PATCH + #if FZFEXPECT_PATCH || CTRL_V_TO_PASTE_PATCH case XK_v: + #if FZFEXPECT_PATCH + expect("ctrl-v", ev); + #endif // FZFEXPECT_PATCH case XK_V: - #endif // CTRL_V_TO_PASTE_PATCH XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, utf8, utf8, win, CurrentTime); return; + #endif // FZFEXPECT_PATCH | CTRL_V_TO_PASTE_PATCH + #if FZFEXPECT_PATCH + case XK_y: expect("ctrl-y", ev); /* paste selection */ + #else + case XK_y: /* paste selection */ + #endif // FZFEXPECT_PATCH + case XK_Y: + XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, + utf8, utf8, win, CurrentTime); + return; + case XK_x: expect("ctrl-x", ev); break; + case XK_z: expect("ctrl-z", ev); break; case XK_Left: case XK_KP_Left: movewordedge(-1); @@ -1805,17 +1850,20 @@ usage(void) #endif // GRID_PATCH "[-l lines] [-p prompt] [-fn font] [-m monitor]" "\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 || JSON_PATCH + #if ALPHA_PATCH || BORDER_PATCH || HIGHPRIORITY_PATCH || INITIALTEXT_PATCH || LINE_HEIGHT_PATCH || NAVHISTORY_PATCH || XYW_PATCH || DYNAMIC_OPTIONS_PATCH || JSON_PATCH || FZFEXPECT_PATCH "\n " #endif #if JSON_PATCH - " [ -j json-file]" + " [-j json-file]" #endif // JSON_PATCH #if DYNAMIC_OPTIONS_PATCH - " [ -dy command]" + " [-dy command]" #endif // DYNAMIC_OPTIONS_PATCH + #if FZFEXPECT_PATCH + " [-ex expectkey]" + #endif // FZFEXPECT_PATCH #if ALPHA_PATCH - " [ -o opacity]" + " [-o opacity]" #endif // ALPHA_PATCH #if BORDER_PATCH " [-bw width]" @@ -1826,6 +1874,7 @@ usage(void) #if INITIALTEXT_PATCH " [-it text]" #endif // INITIALTEXT_PATCH + "\n " #if LINE_HEIGHT_PATCH " [-h height]" #endif // LINE_HEIGHT_PATCH @@ -1839,7 +1888,7 @@ usage(void) " [-X xoffset] [-Y yoffset] [-W width]" // (arguments made upper case due to conflicts) #endif // XYW_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 "\n", stderr); exit(1); @@ -1928,6 +1977,10 @@ main(int argc, char *argv[]) } else if (!strcmp(argv[i], "-P")) { /* is the input a password */ passwd = 1; #endif // PASSWORD_PATCH + #if FZFEXPECT_PATCH + } else if (!strcmp(argv[i], "-ex")) { /* expect key */ + expected = argv[++i]; + #endif // FZFEXPECT_PATCH #if REJECTNOMATCH_PATCH } else if (!strcmp(argv[i], "-R")) { /* reject input which results in no match */ reject_no_match = 1; diff --git a/patch/fzfexpect.c b/patch/fzfexpect.c new file mode 100644 index 0000000..1563362 --- /dev/null +++ b/patch/fzfexpect.c @@ -0,0 +1,39 @@ +static char *expected; +#if MULTI_SELECTION_PATCH +void +expect(char *expect, XKeyEvent *ev) +{ + if (sel && expected && strstr(expected, expect)) { + if (expected && sel && !(ev->state & ShiftMask)) + puts(expect); + for (int i = 0; i < selidsize; i++) + if (selid[i] != -1 && (!sel || sel->id != selid[i])) + puts(items[selid[i]].text); + if (sel && !(ev->state & ShiftMask)) { + puts(sel->text); + } else + puts(text); + cleanup(); + exit(1); + } else if (!sel && expected && strstr(expected, expect)) { + puts(expect); + cleanup(); + exit(1); + } +} +#else +void +expect(char *expect, XKeyEvent *ignored) +{ + if (sel && expected && strstr(expected, expect)) { + puts(expect); + puts(sel->text); + cleanup(); + exit(1); + } else if (!sel && expected && strstr(expected, expect)){ + puts(expect); + cleanup(); + exit(1); + } +} +#endif // MULTI_SELECTION_PATCH \ No newline at end of file diff --git a/patch/fzfexpect.h b/patch/fzfexpect.h new file mode 100644 index 0000000..95c1dad --- /dev/null +++ b/patch/fzfexpect.h @@ -0,0 +1 @@ +static void expect(char *expect, XKeyEvent *ev); diff --git a/patch/include.c b/patch/include.c index 84f353b..87faaea 100644 --- a/patch/include.c +++ b/patch/include.c @@ -12,6 +12,9 @@ #if FUZZYMATCH_PATCH #include "fuzzymatch.c" #endif +#if FZFEXPECT_PATCH +#include "fzfexpect.c" +#endif #if HIGHPRIORITY_PATCH #include "highpriority.c" #endif diff --git a/patch/include.h b/patch/include.h index 1aebc52..777acac 100644 --- a/patch/include.h +++ b/patch/include.h @@ -1,6 +1,9 @@ #if DYNAMIC_OPTIONS_PATCH #include "dynamicoptions.h" #endif +#if FZFEXPECT_PATCH +#include "fzfexpect.h" +#endif #if JSON_PATCH #include "json.h" #endif diff --git a/patches.def.h b/patches.def.h index d1aec74..aced908 100644 --- a/patches.def.h +++ b/patches.def.h @@ -71,6 +71,12 @@ */ #define FUZZYMATCH_PATCH 0 +/* Adds fzf-like functionality for dmenu. + * Refer to https://github.com/DAFF0D11/dafmenu/ for documentation and example use cases. + * https://github.com/DAFF0D11/dafmenu/blob/master/patches/dmenu-fzfexpect-5.1.diff + */ +#define FZFEXPECT_PATCH 0 + /* Allows dmenu's entries to be rendered in a grid by adding a new -g flag to specify * the number of grid columns. The -g and -l options can be used together to create a * G columns * L lines grid.