Support basic Emacs-style line-editing bindings - wmenu - 🔧 fork of wmenu
 (HTM) git clone git@git.drkhsh.at/wmenu.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 972277a5e0a4d92810c84afe3a6b278b3f8bbd54
 (DIR) parent 8cc6a22737ba801cc4b5846af3e33f348abfc52e
 (HTM) Author: adnano <me@adnano.co>
       Date:   Fri,  2 Dec 2022 10:08:24 -0500
       
       Support basic Emacs-style line-editing bindings
       
       Implements: https://todo.sr.ht/~adnano/wmenu/3
       
       Diffstat:
         M main.c                              |      90 +++++++++++++++++++++++++++++++
       
       1 file changed, 90 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/main.c b/main.c
       @@ -501,6 +501,96 @@ void keypress(struct menu_state *state, enum wl_keyboard_key_state key_state,
                                XKB_MOD_NAME_SHIFT,
                                XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED);
        
       +        if (ctrl) {
       +                // Emacs-style line editing bindings
       +                switch (sym) {
       +                case XKB_KEY_a:
       +                        sym = XKB_KEY_Home;
       +                        break;
       +                case XKB_KEY_b:
       +                        sym = XKB_KEY_Left;
       +                        break;
       +                case XKB_KEY_c:
       +                        sym = XKB_KEY_Escape;
       +                        break;
       +                case XKB_KEY_d:
       +                        sym = XKB_KEY_Delete;
       +                        break;
       +                case XKB_KEY_e:
       +                        sym = XKB_KEY_End;
       +                        break;
       +                case XKB_KEY_f:
       +                        sym = XKB_KEY_Right;
       +                        break;
       +                case XKB_KEY_g:
       +                        sym = XKB_KEY_Escape;
       +                        break;
       +                case XKB_KEY_h:
       +                        sym = XKB_KEY_BackSpace;
       +                        break;
       +                case XKB_KEY_i:
       +                        sym = XKB_KEY_Tab;
       +                        break;
       +                case XKB_KEY_j:
       +                case XKB_KEY_J:
       +                case XKB_KEY_m:
       +                case XKB_KEY_M:
       +                        sym = XKB_KEY_Return;
       +                        ctrl = false;
       +                        break;
       +                case XKB_KEY_n:
       +                        sym = XKB_KEY_Down;
       +                        break;
       +                case XKB_KEY_p:
       +                        sym = XKB_KEY_Up;
       +                        break;
       +
       +                case XKB_KEY_k:
       +                        // Delete right
       +                        state->text[state->cursor] = '\0';
       +                        match(state);
       +                        render_frame(state);
       +                        return;
       +                case XKB_KEY_u:
       +                        // Delete left
       +                        insert(state, NULL, 0 - state->cursor);
       +                        render_frame(state);
       +                        return;
       +                case XKB_KEY_w:
       +                        // Delete word
       +                        while (state->cursor > 0 && state->text[nextrune(state, -1)] == ' ') {
       +                                insert(state, NULL, nextrune(state, -1) - state->cursor);
       +                        }
       +                        while (state->cursor > 0 && state->text[nextrune(state, -1)] != ' ') {
       +                                insert(state, NULL, nextrune(state, -1) - state->cursor);
       +                        }
       +                        render_frame(state);
       +                        return;
       +                case XKB_KEY_Left:
       +                case XKB_KEY_KP_Left:
       +                        // Move to beginning of word
       +                        while (state->cursor > 0 && state->text[nextrune(state, -1)] == ' ') {
       +                                state->cursor = nextrune(state, -1);
       +                        }
       +                        while (state->cursor > 0 && state->text[nextrune(state, -1)] != ' ') {
       +                                state->cursor = nextrune(state, -1);
       +                        }
       +                        render_frame(state);
       +                        return;
       +                case XKB_KEY_Right:
       +                case XKB_KEY_KP_Right:
       +                        // Move to end of word
       +                        while (state->cursor > 0 && state->text[nextrune(state, -1)] == ' ') {
       +                                state->cursor = nextrune(state, -1);
       +                        }
       +                        while (state->cursor > 0 && state->text[nextrune(state, -1)] != ' ') {
       +                                state->cursor = nextrune(state, -1);
       +                        }
       +                        render_frame(state);
       +                        return;
       +                }
       +        }
       +
                char buf[8];
                size_t len = strlen(state->text);
                switch (sym) {