From 185c95a5268bdf96ab8dcd9a6b69495eaf3ed230 Mon Sep 17 00:00:00 2001 From: speedie Date: Sat, 29 Jul 2023 04:24:02 +0200 Subject: [PATCH] Replace Vim like binds with normal dmenu like binds by default. --- README.md | 21 +++----- docs/binds-vim.conf | 96 ++++++++++++++++++++++++++++++++++++ docs/docs.md | 22 ++++++--- docs/spmenu.conf | 91 +++++++++++++---------------------- libs/arg.c | 2 +- libs/conf/config.c | 8 +-- libs/keybinds.h | 115 +++++++++----------------------------------- libs/options.h | 1 + meson.build | 1 + spmenu.1 | 11 +++-- spmenu.c | 5 +- spmenu_run.1 | 2 +- spmenu_test.1 | 2 +- 13 files changed, 194 insertions(+), 183 deletions(-) create mode 100644 docs/binds-vim.conf diff --git a/README.md b/README.md index 7784900..39c4c3a 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ can be themed to look identical to dmenu. - Image and icon support - Run launcher, supporting both .desktop entries and $PATH - fzf-like Fuzzy matching -- Vi-like modes +- Vi-like modes (see docs/binds-vim.conf) - History buffer - Configuration file, allowing customizable keybinds - Mouse binds @@ -121,24 +121,19 @@ To generate a tarball, run `scripts/spmenu_make dist` **in the current directory**. If you want to generate a pacman package, run `scripts/spmenu_make pkg_arch` instead. +## Vim like keybinds + +For those who are familiar with Vim and like Vi-style keybinds, +you can copy `docs/binds-vim.conf` to `~/.config/spmenu/binds.conf`. +This will re-enable normal mode. In other words, it will restore the +keybinds spmenu 3.1.1 had. + ## Scripts There's a page dedicated to user scripts [over on the wiki](https://spmenu.speedie.site/User+scripts). Feel free to contribute and try scripts on there. -## Simple mode - -Some users may find the Vim modes confusing. If this is you, you -can copy [this file](https://git.speedie.site/speedie/spmenu-config/raw/branch/master/binds/simple-keybinds.conf) -to ~/.config/spmenu/binds.conf. This will restore some of -the more traditional dmenu keybinds. Do note that many -keybinds will be missing if you go for this, and keybinds -in spmenu.conf will be unused. One of the changes it makes -is removing normal mode, so insert mode will always be -used instead. Arrow keys are used for navigation -rather than Vim keys. - ## Screenshots ![typing](screenshots/typing.gif) diff --git a/docs/binds-vim.conf b/docs/binds-vim.conf new file mode 100644 index 0000000..8bf6130 --- /dev/null +++ b/docs/binds-vim.conf @@ -0,0 +1,96 @@ +/* spmenu default configuration file + * + * Copy to ~/.config/spmenu/spmenu.conf to use. + * Note that you can @include other config files if you want + * + * Arguments will always override options in this configuration file. + * + * Example: @include "config.conf" + */ + +bind = { + /* Mouse bindings + * + * See https://spmenu.speedie.site/Configurable+keybindings for a list of valid options. + */ + mouse = ( + /* Click Button Function Argument */ + { click = "ClickInput"; button = "Left Click"; function = "clear"; argument = "0"; }, // Left click on input: Clear the input + { click = "ClickPrompt"; button = "Left Click"; function = "clear"; argument = "0"; }, // Left click on prompt: Clear the input + { click = "ClickMode"; button = "Left Click"; function = "switchmode"; argument = "0"; }, // Left click on the mode indicator: Toggle mode + { click = "ClickNumber"; button = "Left Click"; function = "viewhist"; argument = "0"; }, // Click on the match count: Toggle viewing history buffer + { click = "ClickItem"; button = "Left Click"; function = "selecthover"; argument = "0"; }, // Left click on an item: Select it + { click = "ClickItem"; button = "Right Click"; function = "markhover"; argument = "0"; }, // Right click on an item: Mark it + { click = "None"; button = "Scroll Up"; function = "moveprev"; argument = "0"; }, // Scroll Up: Move to the previous page + { click = "None"; button = "Scroll Down"; function = "movenext"; argument = "0"; }, // Scroll Down: Move to the next page + + { + scrolldistance = 512; // Distance to scroll for a scroll action to count. Wayland only (num) + ignoreglobalmouse = 1; // Ignore hardcoded mouse binds (0/1) + } ); + + /* Keys + * + * It is strongly recommended that you do NOT unbind any switchmode or quit + * function keybinds unless you know exactly what you're doing. + * If you ignore this warning and find that you can't exit spmenu, + * press Ctrl+Alt+Delete. Doing so will exit spmenu, even if no key is bound. + * + * Please note that at least on the US standard keyboard layout, + * `key` will differ if Shift is held down and the key is a number or symbol. + * + * See https://spmenu.speedie.site/Configurable+keybindings for a list of valid options. + */ + keys = ( + /* Mode Modifier Key Function Argument */ + { mode = -1; modifier = "None"; key = "Enter"; function = "selectitem"; argument = "+1"; }, // Enter: Select item + { mode = -1; modifier = "Shift"; key = "Enter"; function = "selectitem"; argument = "0"; }, // Shift+Enter: Select input + { mode = -1; modifier = "Ctrl"; key = "Enter"; function = "markitem"; argument = "0"; }, // Ctrl+Enter: Mark input + { mode = -1; modifier = "None"; key = "Tab"; function = "complete"; argument = "0"; }, // Tab: Tab complete + { mode = -1; modifier = "Ctrl"; key = "v"; function = "paste"; argument = "2"; }, // Ctrl+v: Paste from clipboard + { mode = -1; modifier = "Ctrl+Shift"; key = "v"; function = "paste"; argument = "1"; }, // Ctrl+Shift+v: Paste from selection + { mode = -1; modifier = "None"; key = "Backspace"; function = "backspace"; argument = "0"; }, // Backspace: Backspace + { mode = -1; modifier = "Ctrl"; key = "Backspace"; function = "deleteword"; argument = "0"; }, // Ctrl+Backspace: Delete word + { mode = -1; modifier = "Ctrl"; key = "Left"; function = "moveword"; argument = "-1"; }, // Ctrl+Left: Move caret (cursor) one word to the left + { mode = -1; modifier = "Ctrl"; key = "Right"; function = "moveword"; argument = "+1"; }, // Ctrl+Right: Move caret (cursor) one word to the right + { mode = -1; modifier = "None"; key = "Left"; function = "movecursor"; argument = "-1"; }, // Left: Move caret (cursor) one character to the left + { mode = -1; modifier = "None"; key = "Right"; function = "movecursor"; argument = "+1"; }, // Right: Move caret (cursor) one character to the right + { mode = -1; modifier = "Ctrl"; key = "k"; function = "setlines"; argument = "+1"; }, // Ctrl+k: Increase lines by 1 + { mode = -1; modifier = "Ctrl"; key = "j"; function = "setlines"; argument = "-1"; }, // Ctrl+j: Decrease lines by 1 + { mode = -1; modifier = "Ctrl"; key = "l"; function = "setcolumns"; argument = "+1"; }, // Ctrl+l: Increase columns by 1 + { mode = -1; modifier = "Ctrl"; key = "h"; function = "setcolumns"; argument = "-1"; }, // Ctrl+h: Decrease columns by 1 + { mode = -1; modifier = "Ctrl+Shift"; key = "p"; function = "setprofile"; argument = "0"; }, // Ctrl+Shift+p: Open profile menu + { mode = -1; modifier = "None"; key = "PrintScr"; function = "screenshot"; argument = "0"; }, // Print Screen: Screenshot spmenu + { mode = 1; modifier = "None"; key = "Esc"; function = "switchmode"; argument = "0"; }, // Escape: Switch mode + { mode = 1; modifier = "Ctrl"; key = "r"; function = "toggleregex"; argument = "0"; }, // Ctrl+r: Toggle regex matching + { mode = 0; modifier = "None"; key = "i"; function = "switchmode"; argument = "0"; }, // i: Switch mode + { mode = 0; modifier = "Ctrl"; key = "="; function = "setimgsize"; argument = "+10"; }, // Ctrl+=: Increase image size by 10 + { mode = 0; modifier = "Ctrl"; key = "-"; function = "setimgsize"; argument = "-10"; }, // Ctrl+-: Decrease image size by 10 + { mode = 0; modifier = "Shift"; key = ")"; function = "defaultimg"; argument = "0"; }, // Shift+0: Set image size to the default + { mode = 0; modifier = "None"; key = "o"; function = "setimgpos"; argument = "+1"; }, // o: Toggle image position + { mode = 0; modifier = "None"; key = "p"; function = "paste"; argument = "2"; }, // p: Paste from clipboard + { mode = 0; modifier = "Ctrl"; key = "1"; function = "setimggaps"; argument = "-10"; }, // Ctrl+1: Decrease image gaps by 10 + { mode = 0; modifier = "Ctrl"; key = "2"; function = "setimggaps"; argument = "+10"; }, // Ctrl+2: Increase image gaps by 10 + { mode = 0; modifier = "None"; key = "t"; function = "toggleimg"; argument = "0"; }, // t: Toggle image + { mode = 0; modifier = "None"; key = "q"; function = "flipimg"; argument = "1"; }, // q: Flip image horizontally + { mode = 0; modifier = "None"; key = "w"; function = "flipimg"; argument = "0"; }, // w: Flip image vertically + { mode = 0; modifier = "None"; key = "k"; function = "moveup"; argument = "0"; }, // k: Move up 1 item + { mode = 0; modifier = "None"; key = "j"; function = "movedown"; argument = "0"; }, // j: Move down 1 item + { mode = 0; modifier = "None"; key = "h"; function = "moveleft"; argument = "0"; }, // h: Move left 1 item + { mode = 0; modifier = "None"; key = "l"; function = "moveright"; argument = "0"; }, // l: Move right 1 item + { mode = 0; modifier = "Ctrl"; key = "u"; function = "moveup"; argument = "5"; }, // Ctrl+u: Move up 5 items + { mode = 0; modifier = "Ctrl"; key = "d"; function = "movedown"; argument = "5"; }, // Ctrl+d: Move down 5 items + { mode = 0; modifier = "None"; key = "u"; function = "togglehighlight"; argument = "0"; }, // u: Toggle highlighting + { mode = 0; modifier = "Shift"; key = "h"; function = "viewhist"; argument = "0"; }, // Shift+h: Toggle viewing history buffer + { mode = 0; modifier = "None"; key = "d"; function = "clear"; argument = "0"; }, // d: Clear the input + { mode = 0; modifier = "Shift"; key = "d"; function = "clearins"; argument = "0"; }, // Shift+d: Clear the input and enter insert mode + { mode = 0; modifier = "None"; key = "Esc"; function = "quit"; argument = "0"; }, // Esc: Exit + { mode = 0; modifier = "None"; key = "g"; function = "movestart"; argument = "0"; }, // g: Move to the start + { mode = 0; modifier = "Shift"; key = "g"; function = "moveend"; argument = "0"; }, // Shift+g: Move to the end + { mode = 0; modifier = "Ctrl"; key = "p"; function = "navhistory"; argument = "-1"; }, // Ctrl+p: Navigate to the previous entry in the history buffer + { mode = 0; modifier = "Ctrl"; key = "n"; function = "navhistory"; argument = "+1"; }, // Ctrl+n: Navigate to the next entry in the history buffer + + { ignoreglobalkeys = 1; // Ignore hardcoded keybinds (0/1) + forceinsertmode = 0; // Force insert mode, disabling normal mode (0/1) + } ), +}; diff --git a/docs/docs.md b/docs/docs.md index bd133b8..7eeb874 100644 --- a/docs/docs.md +++ b/docs/docs.md @@ -610,15 +610,21 @@ to move all keybinds to Insert mode, restoring the original dmenu behavior. Normal mode is the mode spmenu starts in unless a mode argument is specified -or another mode is set in the configuration file. In normal mode, all keys -perform some action, but you cannot type any actual text to filter items. -This mode is commonly used for navigation, general keybinds, as well as -quickly selecting an item. +or another mode is set in the configuration file. Note that if `forceinsertmode` +is enabled, Normal mode cannot be used and spmenu will start in Insert mode +instead. -Insert mode is entered through (by default) pressing `i` in normal mode. In -this mode, most keybinds do nothing. When you are in insert mode, you -filter items by typing text into the field. Once you're done -with insert mode, you can press Escape to enter normal mode again. +In normal mode, all keys perform some action, but you cannot type any actual +text to filter items. This mode is commonly used for navigation, general +keybinds, as well as quickly selecting an item. By default though, +this mode is not used. + +Insert mode is entered through (by default) pressing `i` in normal mode. +In this mode, most keybinds do nothing. When you are in insert mode, +you filter items by typing text into the field. + +Once you're done with insert mode and normal mode is enabled, you can press +(by default) Escape to enter normal mode again. All of these keybinds can be overriden in the configuration file. Should you unbind your switchmode key, you can always press `Ctrl+Alt+Delete` to diff --git a/docs/spmenu.conf b/docs/spmenu.conf index 4ad60e9..29058e5 100644 --- a/docs/spmenu.conf +++ b/docs/spmenu.conf @@ -268,15 +268,15 @@ spmenu = { * See https://spmenu.speedie.site/Configurable+keybindings for a list of valid options. */ mouse = ( - /* Click Button Function Argument */ - { click = "ClickInput"; button = "Left Click"; function = "clear"; argument = "0"; }, // Left click on input: Clear the input - { click = "ClickPrompt"; button = "Left Click"; function = "clear"; argument = "0"; }, // Left click on prompt: Clear the input - { click = "ClickMode"; button = "Left Click"; function = "switchmode"; argument = "0"; }, // Left click on the mode indicator: Toggle mode - { click = "ClickNumber"; button = "Left Click"; function = "viewhist"; argument = "0"; }, // Click on the match count: Toggle viewing history buffer - { click = "ClickItem"; button = "Left Click"; function = "selecthover"; argument = "0"; }, // Left click on an item: Select it - { click = "ClickItem"; button = "Right Click"; function = "markhover"; argument = "0"; }, // Right click on an item: Mark it - { click = "None"; button = "Scroll Up"; function = "moveprev"; argument = "0"; }, // Scroll Up: Move to the previous page - { click = "None"; button = "Scroll Down"; function = "movenext"; argument = "0"; }, // Scroll Down: Move to the next page + /* Click Button Function Argument */ + { click = "ClickInput"; button = "Left Click"; function = "clear"; argument = "0"; }, // Left click on input: Clear the input + { click = "ClickPrompt"; button = "Left Click"; function = "clear"; argument = "0"; }, // Left click on prompt: Clear the input + { click = "ClickMode"; button = "Left Click"; function = "switchmode"; argument = "0"; }, // Left click on the mode indicator: Toggle mode + { click = "ClickNumber"; button = "Left Click"; function = "viewhist"; argument = "0"; }, // Click on the match count: Toggle viewing history buffer + { click = "ClickItem"; button = "Left Click"; function = "selecthover"; argument = "0"; }, // Left click on an item: Select it + { click = "ClickItem"; button = "Right Click"; function = "markhover"; argument = "0"; }, // Right click on an item: Mark it + { click = "None"; button = "Scroll Up"; function = "moveprev"; argument = "0"; }, // Scroll Up: Move to the previous page + { click = "None"; button = "Scroll Down"; function = "movenext"; argument = "0"; }, // Scroll Down: Move to the next page { scrolldistance = 512; // Distance to scroll for a scroll action to count. Wayland only (num) @@ -296,53 +296,30 @@ spmenu = { * See https://spmenu.speedie.site/Configurable+keybindings for a list of valid options. */ keys = ( - /* Mode Modifier Key Function Argument */ - { mode = -1; modifier = "None"; key = "Enter"; function = "selectitem"; argument = "+1"; }, // Enter: Select item - { mode = -1; modifier = "Shift"; key = "Enter"; function = "selectitem"; argument = "0"; }, // Shift+Enter: Select input - { mode = -1; modifier = "Ctrl"; key = "Enter"; function = "markitem"; argument = "0"; }, // Ctrl+Enter: Mark input - { mode = -1; modifier = "None"; key = "Tab"; function = "complete"; argument = "0"; }, // Tab: Tab complete - { mode = -1; modifier = "Ctrl"; key = "v"; function = "paste"; argument = "2"; }, // Ctrl+v: Paste from clipboard - { mode = -1; modifier = "Ctrl+Shift"; key = "v"; function = "paste"; argument = "1"; }, // Ctrl+Shift+v: Paste from selection - { mode = -1; modifier = "None"; key = "Backspace"; function = "backspace"; argument = "0"; }, // Backspace: Backspace - { mode = -1; modifier = "Ctrl"; key = "Backspace"; function = "deleteword"; argument = "0"; }, // Ctrl+Backspace: Delete word - { mode = -1; modifier = "Ctrl"; key = "Left"; function = "moveword"; argument = "-1"; }, // Ctrl+Left: Move caret (cursor) one word to the left - { mode = -1; modifier = "Ctrl"; key = "Right"; function = "moveword"; argument = "+1"; }, // Ctrl+Right: Move caret (cursor) one word to the right - { mode = -1; modifier = "None"; key = "Left"; function = "movecursor"; argument = "-1"; }, // Left: Move caret (cursor) one character to the left - { mode = -1; modifier = "None"; key = "Right"; function = "movecursor"; argument = "+1"; }, // Right: Move caret (cursor) one character to the right - { mode = -1; modifier = "Ctrl"; key = "k"; function = "setlines"; argument = "+1"; }, // Ctrl+k: Increase lines by 1 - { mode = -1; modifier = "Ctrl"; key = "j"; function = "setlines"; argument = "-1"; }, // Ctrl+j: Decrease lines by 1 - { mode = -1; modifier = "Ctrl"; key = "l"; function = "setcolumns"; argument = "+1"; }, // Ctrl+l: Increase columns by 1 - { mode = -1; modifier = "Ctrl"; key = "h"; function = "setcolumns"; argument = "-1"; }, // Ctrl+h: Decrease columns by 1 - { mode = -1; modifier = "Ctrl+Shift"; key = "p"; function = "setprofile"; argument = "0"; }, // Ctrl+Shift+p: Open profile menu - { mode = -1; modifier = "None"; key = "PrintScr"; function = "screenshot"; argument = "0"; }, // Print Screen: Screenshot spmenu - { mode = 1; modifier = "None"; key = "Esc"; function = "switchmode"; argument = "0"; }, // Escape: Switch mode - { mode = 1; modifier = "Ctrl"; key = "r"; function = "toggleregex"; argument = "0"; }, // Ctrl+r: Toggle regex matching - { mode = 0; modifier = "None"; key = "i"; function = "switchmode"; argument = "0"; }, // i: Switch mode - { mode = 0; modifier = "Ctrl"; key = "="; function = "setimgsize"; argument = "+10"; }, // Ctrl+=: Increase image size by 10 - { mode = 0; modifier = "Ctrl"; key = "-"; function = "setimgsize"; argument = "-10"; }, // Ctrl+-: Decrease image size by 10 - { mode = 0; modifier = "Shift"; key = ")"; function = "defaultimg"; argument = "0"; }, // Shift+0: Set image size to the default - { mode = 0; modifier = "None"; key = "o"; function = "setimgpos"; argument = "+1"; }, // o: Toggle image position - { mode = 0; modifier = "None"; key = "p"; function = "paste"; argument = "2"; }, // p: Paste from clipboard - { mode = 0; modifier = "Ctrl"; key = "1"; function = "setimggaps"; argument = "-10"; }, // Ctrl+1: Decrease image gaps by 10 - { mode = 0; modifier = "Ctrl"; key = "2"; function = "setimggaps"; argument = "+10"; }, // Ctrl+2: Increase image gaps by 10 - { mode = 0; modifier = "None"; key = "t"; function = "toggleimg"; argument = "0"; }, // t: Toggle image - { mode = 0; modifier = "None"; key = "q"; function = "flipimg"; argument = "1"; }, // q: Flip image horizontally - { mode = 0; modifier = "None"; key = "w"; function = "flipimg"; argument = "0"; }, // w: Flip image vertically - { mode = 0; modifier = "None"; key = "k"; function = "moveup"; argument = "0"; }, // k: Move up 1 item - { mode = 0; modifier = "None"; key = "j"; function = "movedown"; argument = "0"; }, // j: Move down 1 item - { mode = 0; modifier = "None"; key = "h"; function = "moveleft"; argument = "0"; }, // h: Move left 1 item - { mode = 0; modifier = "None"; key = "l"; function = "moveright"; argument = "0"; }, // l: Move right 1 item - { mode = 0; modifier = "Ctrl"; key = "u"; function = "moveup"; argument = "5"; }, // Ctrl+u: Move up 5 items - { mode = 0; modifier = "Ctrl"; key = "d"; function = "movedown"; argument = "5"; }, // Ctrl+d: Move down 5 items - { mode = 0; modifier = "None"; key = "u"; function = "togglehighlight"; argument = "0"; }, // Ctrl+u: Toggle highlighting - { mode = 0; modifier = "Shift"; key = "h"; function = "viewhist"; argument = "0"; }, // Shift+h: Toggle viewing history buffer - { mode = 0; modifier = "None"; key = "d"; function = "clear"; argument = "0"; }, // d: Clear the input - { mode = 0; modifier = "Shift"; key = "d"; function = "clearins"; argument = "0"; }, // Shift+d: Clear the input and enter insert mode - { mode = 0; modifier = "None"; key = "Esc"; function = "quit"; argument = "0"; }, // Esc: Exit - { mode = 0; modifier = "None"; key = "g"; function = "movestart"; argument = "0"; }, // g: Move to the start - { mode = 0; modifier = "Shift"; key = "g"; function = "moveend"; argument = "0"; }, // Shift+g: Move to the end - { mode = 0; modifier = "Ctrl"; key = "p"; function = "navhistory"; argument = "-1"; }, // Ctrl+p: Navigate to the previous entry in the history buffer - { mode = 0; modifier = "Ctrl"; key = "n"; function = "navhistory"; argument = "+1"; }, // Ctrl+n: Navigate to the next entry in the history buffer + /* Mode Modifier Key Function Argument */ + { mode = -1; modifier = "None"; key = "Enter"; function = "selectitem"; argument = "+1"; }, // Enter: Select item + { mode = -1; modifier = "Shift"; key = "Enter"; function = "selectitem"; argument = "0"; }, // Shift+Enter: Select input + { mode = -1; modifier = "Ctrl"; key = "Enter"; function = "markitem"; argument = "0"; }, // Ctrl+Enter: Mark input + { mode = -1; modifier = "None"; key = "Tab"; function = "complete"; argument = "0"; }, // Tab: Tab complete + { mode = -1; modifier = "Ctrl"; key = "v"; function = "paste"; argument = "2"; }, // Ctrl+v: Paste from clipboard + { mode = -1; modifier = "None"; key = "Backspace"; function = "backspace"; argument = "0"; }, // Backspace: Backspace + { mode = -1; modifier = "Ctrl"; key = "Backspace"; function = "deleteword"; argument = "0"; }, // Ctrl+Backspace: Delete word + { mode = -1; modifier = "Ctrl+Shift"; key = "p"; function = "setprofile"; argument = "0"; }, // Ctrl+Shift+p: Open profile menu + { mode = -1; modifier = "Ctrl"; key = "="; function = "setimgsize"; argument = "+10"; }, // Ctrl+=: Increase image size by 10 + { mode = -1; modifier = "Ctrl"; key = "-"; function = "setimgsize"; argument = "-10"; }, // Ctrl+-: Decrease image size by 10 + { mode = -1; modifier = "None"; key = "Up"; function = "moveup"; argument = "0"; }, // k: Move up 1 item + { mode = -1; modifier = "None"; key = "Down"; function = "movedown"; argument = "0"; }, // j: Move down 1 item + { mode = -1; modifier = "None"; key = "Left"; function = "moveleft"; argument = "0"; }, // h: Move left 1 item + { mode = -1; modifier = "None"; key = "Right"; function = "moveright"; argument = "0"; }, // l: Move right 1 item + { mode = -1; modifier = "Ctrl"; key = "u"; function = "moveup"; argument = "5"; }, // Ctrl+u: Move up 5 items + { mode = -1; modifier = "Ctrl"; key = "d"; function = "movedown"; argument = "5"; }, // Ctrl+d: Move down 5 items + { mode = -1; modifier = "Ctrl"; key = "h"; function = "viewhist"; argument = "0"; }, // Ctrl+h: Toggle viewing history buffer + { mode = -1; modifier = "None"; key = "Esc"; function = "quit"; argument = "0"; }, // Esc: Exit + { mode = -1; modifier = "Ctrl"; key = "p"; function = "navhistory"; argument = "-1"; }, // Ctrl+p: Navigate to the previous entry in the history buffer + { mode = -1; modifier = "Ctrl"; key = "n"; function = "navhistory"; argument = "+1"; }, // Ctrl+n: Navigate to the next entry in the history buffer + { mode = -1; modifier = "None"; key = "PrintScr"; function = "screenshot"; argument = "0"; }, // Print Screen: Screenshot spmenu - { ignoreglobalkeys = 1; } ), // Ignore hardcoded keybinds (0/1) + { ignoreglobalkeys = 1; // Ignore hardcoded keybinds (0/1) + forceinsertmode = 1; // Force insert mode to be used, disabling normal mode (0/1) + } ), }; diff --git a/libs/arg.c b/libs/arg.c index 1a8ca0c..5632fbb 100644 --- a/libs/arg.c +++ b/libs/arg.c @@ -605,7 +605,7 @@ void setprofile(Arg *arg) { } void switchmode(Arg *arg) { - if (sp.forceinsertmode) { + if (forceinsertmode) { return; } diff --git a/libs/conf/config.c b/libs/conf/config.c index c3c1ae4..fe24b54 100644 --- a/libs/conf/config.c +++ b/libs/conf/config.c @@ -49,7 +49,7 @@ int bind_init(void) { fprintf(stderr, "spmenu: Invalid keys file.\n"); } - // load options binds.keys + // load options bind.keys config_setting_t *key_bind = config_lookup(&bind, "bind.keys"); if (key_bind != NULL && loadbinds) { int nmode = 0; @@ -131,12 +131,12 @@ int bind_init(void) { } } + config_setting_lookup_int(conf, "forceinsertmode", &forceinsertmode); config_setting_lookup_int(conf, "ignoreglobalkeys", &sp.ignoreglobalkeys); - config_setting_lookup_int(conf, "forceinsertmode", &sp.forceinsertmode); } } - // load options binds.mouse + // load options bind.mouse config_setting_t *mouse_bind = config_lookup(&bind, "bind.mouse"); if (mouse_bind != NULL && loadbinds) { #if USEX @@ -925,7 +925,7 @@ void conf_init(void) { } } - config_setting_lookup_int(conf, "forceinsertmode", &sp.forceinsertmode); + config_setting_lookup_int(conf, "forceinsertmode", &forceinsertmode); config_setting_lookup_int(conf, "ignoreglobalkeys", &sp.ignoreglobalkeys); } } diff --git a/libs/keybinds.h b/libs/keybinds.h index c510425..47a4e4a 100644 --- a/libs/keybinds.h +++ b/libs/keybinds.h @@ -5,121 +5,54 @@ /* X11 hardcoded keybinds */ #if USEX static Key keys[] = { - /* mode modifier key function argument - * - * any mode - */ { -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 } }, { -1, 0, XK_BackSpace, backspace, {0} }, { -1, Ctrl, XK_BackSpace, deleteword, {0} }, - { -1, Ctrl, XK_Left, moveword, {.i = -1 } }, - { -1, Ctrl, XK_Right, moveword, {.i = +1 } }, - { -1, 0, XK_Left, movecursor, {.i = -1 } }, - { -1, 0, XK_Right, movecursor, {.i = +1 } }, - { -1, Ctrl, XK_k, setlines, {.i = +1 } }, - { -1, Ctrl, XK_j, setlines, {.i = -1 } }, - { -1, Ctrl, XK_h, setcolumns, {.i = +1 } }, - { -1, Ctrl, XK_l, setcolumns, {.i = -1 } }, { -1, Ctrl|Shift, XK_p, setprofile, {0} }, { -1, 0, XK_Print, screenshot, {0} }, - - /* normal mode */ - { 0, 0, XK_i, switchmode, {0} }, - { 0, Ctrl, XK_equal, setimgsize, {.i = +10 } }, - { 0, Ctrl, XK_minus, setimgsize, {.i = -10 } }, - { 0, Shift, XK_0, defaultimg, {0} }, - { 0, 0, XK_o, setimgpos, {.i = +1 } }, - { 0, Ctrl, XK_1, setimggaps, {.i = -10 } }, - { 0, Ctrl, XK_2, setimggaps, {.i = +10 } }, - { 0, 0, XK_t, toggleimg, {0} }, - { 0, 0, XK_p, paste, {.i = 2 } }, - { 0, 0, XK_q, flipimg, {.i = 1 } }, - { 0, 0, XK_w, flipimg, {.i = 0 } }, - { 0, 0, XK_k, moveup, {0} }, - { 0, 0, XK_j, movedown, {0} }, - { 0, 0, XK_h, moveleft, {0} }, - { 0, 0, XK_l, moveright, {0} }, - { 0, Ctrl, XK_u, moveup, {.i = 5 } }, - { 0, Ctrl, XK_d, movedown, {.i = 5 } }, - { 0, 0, XK_u, togglehighlight, {0} }, - { 0, Shift, XK_h, viewhist, {0} }, - { 0, 0, XK_d, clear, {0} }, - { 0, Shift, XK_d, clearins, {0} }, - { 0, 0, XK_Escape, quit, {0} }, - { 0, 0, XK_g, movestart, {0} }, - { 0, Shift, XK_g, moveend, {0} }, - { 0, Ctrl, XK_p, navhistory, {.i = -1 } }, - { 0, Ctrl, XK_n, navhistory, {.i = +1 } }, - - /* insert mode */ - { 1, 0, XK_Escape, switchmode, {0} }, - { 1, Ctrl, XK_r, toggleregex, {0} }, + { -1, Ctrl, XK_equal, setimgsize, {.i = +10 } }, + { -1, Ctrl, XK_minus, setimgsize, {.i = -10 } }, + { -1, 0, XK_k, moveup, {0} }, + { -1, 0, XK_j, movedown, {0} }, + { -1, 0, XK_h, moveleft, {0} }, + { -1, 0, XK_l, moveright, {0} }, + { -1, Ctrl, XK_u, moveup, {.i = 5 } }, + { -1, Ctrl, XK_d, movedown, {.i = 5 } }, + { -1, Shift, XK_h, viewhist, {0} }, + { -1, 0, XK_Escape, quit, {0} }, + { -1, Ctrl, XK_p, navhistory, {.i = -1 } }, + { -1, Ctrl, XK_n, navhistory, {.i = +1 } }, }; #endif /* Wayland hardcoded keybinds */ #if USEWAYLAND static WlKey wl_keys[] = { - /* mode modifier key function argument - * - * any mode - */ { -1, WL_None, XKB_KEY_Return, selectitem, {.i = +1 } }, { -1, WL_Shift, XKB_KEY_Return, selectitem, {0} }, { -1, WL_Ctrl, XKB_KEY_Return, markitem, {0} }, { -1, WL_None, XKB_KEY_Tab, complete, {0} }, { -1, WL_Ctrl, XKB_KEY_v, paste, {.i = 2 } }, - { -1, WL_CtrlShift, XKB_KEY_v, paste, {.i = 1 } }, { -1, WL_None, XKB_KEY_BackSpace, backspace, {0} }, { -1, WL_Ctrl, XKB_KEY_BackSpace, deleteword, {0} }, - { -1, WL_Ctrl, XKB_KEY_Left, moveword, {.i = -1 } }, - { -1, WL_Ctrl, XKB_KEY_Right, moveword, {.i = +1 } }, - { -1, WL_None, XKB_KEY_Left, movecursor, {.i = -1 } }, - { -1, WL_None, XKB_KEY_Right, movecursor, {.i = +1 } }, - { -1, WL_Ctrl, XKB_KEY_k, setlines, {.i = +1 } }, - { -1, WL_Ctrl, XKB_KEY_j, setlines, {.i = -1 } }, - { -1, WL_Ctrl, XKB_KEY_h, setcolumns, {.i = +1 } }, - { -1, WL_Ctrl, XKB_KEY_l, setcolumns, {.i = -1 } }, { -1, WL_CtrlShift, XKB_KEY_p, setprofile, {0} }, { -1, WL_None, XKB_KEY_Print, screenshot, {0} }, + { -1, WL_Ctrl, XKB_KEY_equal, setimgsize, {.i = +10 } }, + { -1, WL_Ctrl, XKB_KEY_minus, setimgsize, {.i = -10 } }, + { -1, WL_None, XKB_KEY_k, moveup, {0} }, + { -1, WL_None, XKB_KEY_j, movedown, {0} }, + { -1, WL_None, XKB_KEY_h, moveleft, {0} }, + { -1, WL_None, XKB_KEY_l, moveright, {0} }, + { -1, WL_Ctrl, XKB_KEY_u, moveup, {.i = 5 } }, + { -1, WL_Ctrl, XKB_KEY_d, movedown, {.i = 5 } }, + { -1, WL_Shift, XKB_KEY_h, viewhist, {0} }, + { -1, WL_None, XKB_KEY_Escape, quit, {0} }, + { -1, WL_Ctrl, XKB_KEY_p, navhistory, {.i = -1 } }, + { -1, WL_Ctrl, XKB_KEY_n, navhistory, {.i = +1 } }, - /* normal mode */ - { 0, WL_None, XKB_KEY_i, switchmode, {0} }, - { 0, WL_Ctrl, XKB_KEY_equal, setimgsize, {.i = +10 } }, - { 0, WL_Ctrl, XKB_KEY_minus, setimgsize, {.i = -10 } }, - { 0, WL_Shift, XKB_KEY_0, defaultimg, {0} }, - { 0, WL_None, XKB_KEY_o, setimgpos, {.i = +1 } }, - { 0, WL_Ctrl, XKB_KEY_1, setimggaps, {.i = -10 } }, - { 0, WL_Ctrl, XKB_KEY_2, setimggaps, {.i = +10 } }, - { 0, WL_None, XKB_KEY_t, toggleimg, {0} }, - { 0, WL_None, XKB_KEY_p, paste, {.i = 2 } }, - { 0, WL_None, XKB_KEY_q, flipimg, {.i = 1 } }, - { 0, WL_None, XKB_KEY_w, flipimg, {.i = 0 } }, - { 0, WL_None, XKB_KEY_k, moveup, {0} }, - { 0, WL_None, XKB_KEY_j, movedown, {0} }, - { 0, WL_None, XKB_KEY_h, moveleft, {0} }, - { 0, WL_None, XKB_KEY_l, moveright, {0} }, - { 0, WL_Ctrl, XKB_KEY_u, moveup, {.i = 5 } }, - { 0, WL_Ctrl, XKB_KEY_d, movedown, {.i = 5 } }, - { 0, WL_None, XKB_KEY_u, togglehighlight, {0} }, - { 0, WL_Shift, XKB_KEY_h, viewhist, {0} }, - { 0, WL_None, XKB_KEY_d, clear, {0} }, - { 0, WL_Shift, XKB_KEY_d, clearins, {0} }, - { 0, WL_None, XKB_KEY_Escape, quit, {0} }, - { 0, WL_None, XKB_KEY_Home, movestart, {0} }, - { 0, WL_None, XKB_KEY_End, moveend, {0} }, - { 0, WL_None, XKB_KEY_g, movestart, {0} }, - { 0, WL_Shift, XKB_KEY_g, moveend, {0} }, - { 0, WL_Ctrl, XKB_KEY_p, navhistory, {.i = -1 } }, - { 0, WL_Ctrl, XKB_KEY_n, navhistory, {.i = +1 } }, - - /* insert mode */ - { 1, WL_None, XKB_KEY_Escape, switchmode, {0} }, - { 1, WL_Ctrl, XKB_KEY_r, toggleregex, {0} }, }; #endif diff --git a/libs/options.h b/libs/options.h index 197f7f9..03a9ee4 100644 --- a/libs/options.h +++ b/libs/options.h @@ -67,6 +67,7 @@ static char *screenshotdir = NULL; /* Screenshot file directory. If /* Mode options */ static int mode = 0; /* Mode to start speedwm in (0: Normal mode, 1: Insert mode) */ +static int forceinsertmode = 1; /* Force insert mode, meaning normal mode will be disabled (0/1) */ static char *normtext = "Normal"; /* Text to display for normal mode */ static char *instext = "Insert"; /* Text to display for insert mode */ static char *regextext = "Regex"; /* Text to display for insert mode when regex is enabled */ diff --git a/meson.build b/meson.build index 851330a..89bc0bb 100644 --- a/meson.build +++ b/meson.build @@ -105,6 +105,7 @@ endif if get_option('docs') install_data(sources : 'docs/spmenu.conf', install_dir : 'share/spmenu') + install_data(sources : 'docs/binds-vim.conf', install_dir : 'share/spmenu') install_data(sources : 'docs/spmenu_run.desktop', install_dir : 'share/applications') install_data(sources : 'docs/spmenu_desktop.desktop', install_dir : 'share/applications') install_data(sources : 'docs/spmenu_filemanager.desktop', install_dir : 'share/applications') diff --git a/spmenu.1 b/spmenu.1 index f56a4fc..9d321d2 100644 --- a/spmenu.1 +++ b/spmenu.1 @@ -1,5 +1,5 @@ '\" t -.\" Automatically generated by Pandoc 3.1.2 +.\" Automatically generated by Pandoc 3.1.3 .\" .\" Define V font for inline verbatim, using C font in formats .\" that render this, and otherwise B font. @@ -647,18 +647,23 @@ Insert mode, restoring the original dmenu behavior. .PP Normal mode is the mode spmenu starts in unless a mode argument is specified or another mode is set in the configuration file. +Note that if \f[V]forceinsertmode\f[R] is enabled, Normal mode cannot be +used and spmenu will start in Insert mode instead. +.PP In normal mode, all keys perform some action, but you cannot type any actual text to filter items. This mode is commonly used for navigation, general keybinds, as well as quickly selecting an item. +By default though, this mode is not used. .PP Insert mode is entered through (by default) pressing \f[V]i\f[R] in normal mode. In this mode, most keybinds do nothing. When you are in insert mode, you filter items by typing text into the field. -Once you\[cq]re done with insert mode, you can press Escape to enter -normal mode again. +.PP +Once you\[cq]re done with insert mode and normal mode is enabled, you +can press (by default) Escape to enter normal mode again. .PP All of these keybinds can be overriden in the configuration file. Should you unbind your switchmode key, you can always press diff --git a/spmenu.c b/spmenu.c index b3605a4..e41b9bb 100644 --- a/spmenu.c +++ b/spmenu.c @@ -149,7 +149,6 @@ struct sp { int ignoreglobalkeys; // should be set in the config file, if 1, the Keys keys array is ignored int ignoreconfmouse; // same for mouse int ignoreglobalmouse; // same for mouse - int forceinsertmode; }; struct mo { @@ -583,10 +582,9 @@ void set_mode(void) { } // normal mode disabled - if (sp.forceinsertmode) { + if (forceinsertmode) { sp.mode = 1; sp.allowkeys = 1; - hidemode = 1; } } @@ -603,7 +601,6 @@ void handle(void) { #if USEIMAGE store_image_vars(); #endif - // fast (-f) means we grab keyboard before reading standard input if (fast && !isatty(0)) { grabkeyboard_x11(); diff --git a/spmenu_run.1 b/spmenu_run.1 index 663fe26..3fd1989 100644 --- a/spmenu_run.1 +++ b/spmenu_run.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pandoc 3.1.2 +.\" Automatically generated by Pandoc 3.1.3 .\" .\" Define V font for inline verbatim, using C font in formats .\" that render this, and otherwise B font. diff --git a/spmenu_test.1 b/spmenu_test.1 index 0c69a1e..8a81fe7 100644 --- a/spmenu_test.1 +++ b/spmenu_test.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pandoc 3.1.2 +.\" Automatically generated by Pandoc 3.1.3 .\" .\" Define V font for inline verbatim, using C font in formats .\" that render this, and otherwise B font.