From b637f921d591118b4b60bdc2370b45a6daf0824b Mon Sep 17 00:00:00 2001 From: Ching Pei Yang <59727193+horriblename@users.noreply.github.com> Date: Sun, 6 Oct 2024 11:23:01 +0200 Subject: [PATCH] maps: allow same key on multiple mode (#360) * mappings: add new keymap option * mappings: impl keymap option * doc: update release notes * map: fix misinformation * map: remove redundant variable * fixup! mappings: impl keymap option --- docs/release-notes/rl-0.7.md | 17 +++--- modules/neovim/mappings/config.nix | 89 +++++++++++++++++++++-------- modules/neovim/mappings/options.nix | 72 ++++++++++++----------- modules/wrapper/rc/config.nix | 39 ++----------- 4 files changed, 120 insertions(+), 97 deletions(-) diff --git a/docs/release-notes/rl-0.7.md b/docs/release-notes/rl-0.7.md index 060efba..2ec691b 100644 --- a/docs/release-notes/rl-0.7.md +++ b/docs/release-notes/rl-0.7.md @@ -28,10 +28,10 @@ configuration formats. ### `vim.maps` rewrite {#sec-vim-maps-rewrite} -Instead of specifying map modes using submodules (eg.: `vim.maps.normal`), a new -`mode` option has mode has been introduced. It can be either a string, or a list -of strings, where a string represents the short-name of the map mode(s), that -the mapping should be set for. See `:help map-modes` for more information. +Instead of specifying map modes using submodules (eg.: `vim.maps.normal`), a new `vim.keymaps` +submodule with support for a `mode` option has been introduced. It can be either a string, or a +list of strings, where a string represents the short-name of the map mode(s), that the mapping +should be set for. See `:help map-modes` for more information. For example: @@ -42,10 +42,13 @@ vim.maps.normal."m" = { ... }; has to be replaced by ```nix -vim.maps."m" = { - mode = "n"; +vim.keymaps = [ + { + key = "m"; + mode = "n"; + } ... -}; +]; ``` ### `vim.lsp.nvimCodeActionMenu` removed in favor of `vim.ui.fastaction` {#sec-nvim-code-action-menu-deprecation} diff --git a/modules/neovim/mappings/config.nix b/modules/neovim/mappings/config.nix index 365e124..4d7f241 100644 --- a/modules/neovim/mappings/config.nix +++ b/modules/neovim/mappings/config.nix @@ -3,32 +3,75 @@ lib, ... }: let - inherit (lib.modules) mkIf; + inherit (lib.modules) mkIf mkMerge; + inherit (lib.trivial) pipe; + inherit (lib.attrsets) mapAttrsToList; + inherit (lib.lists) flatten; + + legacyMapModes = { + normal = ["n"]; + insert = ["i"]; + select = ["s"]; + visual = ["v"]; + terminal = ["t"]; + normalVisualOp = ["n" "v" "o"]; + visualOnly = ["n" "x"]; + operator = ["o"]; + insertCommand = ["i" "c"]; + lang = ["l"]; + command = ["c"]; + }; cfg = config.vim; in { config = { - vim.maps = mkIf cfg.disableArrows { - "" = { - mode = ["n" "i"]; - action = ""; - noremap = false; - }; - "" = { - mode = ["n" "i"]; - action = ""; - noremap = false; - }; - "" = { - mode = ["n" "i"]; - action = ""; - noremap = false; - }; - "" = { - mode = ["n" "i"]; - action = ""; - noremap = false; - }; - }; + vim.keymaps = mkMerge [ + ( + mkIf cfg.disableArrows [ + { + key = ""; + mode = ["n" "i"]; + action = ""; + noremap = false; + } + { + key = ""; + mode = ["n" "i"]; + action = ""; + noremap = false; + } + { + key = ""; + mode = ["n" "i"]; + action = ""; + noremap = false; + } + { + key = ""; + mode = ["n" "i"]; + action = ""; + noremap = false; + } + ] + ) + ( + pipe cfg.maps + [ + (mapAttrsToList ( + oldMode: keybinds: + mapAttrsToList ( + key: bind: + bind + // { + inherit key; + mode = legacyMapModes.${oldMode}; + } + ) + keybinds + )) + flatten + ] + ) + ]; }; } diff --git a/modules/neovim/mappings/options.nix b/modules/neovim/mappings/options.nix index f422991..f05de21 100644 --- a/modules/neovim/mappings/options.nix +++ b/modules/neovim/mappings/options.nix @@ -1,6 +1,6 @@ {lib, ...}: let inherit (lib.options) mkOption; - inherit (lib.types) either str listOf attrsOf nullOr submodule bool; + inherit (lib.types) either str listOf attrsOf nullOr submodule; inherit (lib.nvim.config) mkBool; mapConfigOptions = { @@ -31,6 +31,10 @@ options = mapConfigOptions // { + key = mkOption { + type = str; + description = "The key that triggers this keybind."; + }; mode = mkOption { type = either str (listOf str); description = '' @@ -38,52 +42,56 @@ See `:help map-modes` for a list of modes. ''; + example = ''`["n" "v" "c"]` for normal, visual and command mode''; }; }; }; - # legacy stuff - mapOption = submodule { - options = mapConfigOptions; - }; - - mapOptions = mode: + legacyMapOption = mode: mkOption { description = "Mappings for ${mode} mode"; - type = attrsOf mapOption; + type = attrsOf (submodule { + options = mapConfigOptions; + }); default = {}; }; in { options.vim = { - maps = mkOption { - type = submodule { - freeformType = attrsOf mapType; - options = { - normal = mapOptions "normal"; - insert = mapOptions "insert"; - select = mapOptions "select"; - visual = mapOptions "visual and select"; - terminal = mapOptions "terminal"; - normalVisualOp = mapOptions "normal, visual, select and operator-pending (same as plain 'map')"; - - visualOnly = mapOptions "visual only"; - operator = mapOptions "operator-pending"; - insertCommand = mapOptions "insert and command-line"; - lang = mapOptions "insert, command-line and lang-arg"; - command = mapOptions "command-line"; - }; - }; - default = {}; + keymaps = mkOption { + type = listOf mapType; description = "Custom keybindings."; example = '' - maps = { - "m" = { + vim.keymaps = [ + { + key = "m"; mode = "n"; silent = true; - action = "make"; - }; # Same as nnoremap m make - }; + action = ":make"; + } + { + key = "l"; + mode = ["n" "x"]; + silent = true; + action = "cnext"; + } + ]; ''; + default = {}; + }; + + maps = { + normal = legacyMapOption "normal"; + insert = legacyMapOption "insert"; + select = legacyMapOption "select"; + visual = legacyMapOption "visual and select"; + terminal = legacyMapOption "terminal"; + normalVisualOp = legacyMapOption "normal, visual, select and operator-pending (same as plain 'map')"; + + visualOnly = legacyMapOption "visual only"; + operator = legacyMapOption "operator-pending"; + insertCommand = legacyMapOption "insert and command-line"; + lang = legacyMapOption "insert, command-line and lang-arg"; + command = legacyMapOption "command-line"; }; }; } diff --git a/modules/wrapper/rc/config.nix b/modules/wrapper/rc/config.nix index 6c1936e..6f9ed1c 100644 --- a/modules/wrapper/rc/config.nix +++ b/modules/wrapper/rc/config.nix @@ -3,8 +3,8 @@ lib, ... }: let - inherit (builtins) map mapAttrs filter removeAttrs attrNames; - inherit (lib.attrsets) mapAttrsToList filterAttrs attrsToList; + inherit (builtins) map mapAttrs filter; + inherit (lib.attrsets) mapAttrsToList filterAttrs; inherit (lib.strings) concatLines concatMapStringsSep; inherit (lib.trivial) showWarnings; inherit (lib.generators) mkLuaInline; @@ -41,40 +41,9 @@ in { inherit (keymap) desc silent nowait script expr unique noremap; }; - toLuaKeymap = { - name, - value, - }: "vim.keymap.set(${toLuaObject value.mode}, ${toLuaObject name}, ${toLuaObject (getAction value)}, ${toLuaObject (getOpts value)})"; + toLuaKeymap = bind: "vim.keymap.set(${toLuaObject bind.mode}, ${toLuaObject bind.key}, ${toLuaObject (getAction bind)}, ${toLuaObject (getOpts bind)})"; - namedModes = { - "normal" = ["n"]; - "insert" = ["i"]; - "select" = ["s"]; - "visual" = ["v"]; - "terminal" = ["t"]; - "normalVisualOp" = ["n" "v" "o"]; - "visualOnly" = ["n" "x"]; - "operator" = ["o"]; - "insertCommand" = ["i" "c"]; - "lang" = ["l"]; - "command" = ["c"]; - }; - - maps = - removeAttrs cfg.maps (attrNames namedModes) - // mapAttrs (_: legacyMap: legacyMap // {mode = namedModes.normal;}) cfg.maps.normal - // mapAttrs (_: legacyMap: legacyMap // {mode = namedModes.insert;}) cfg.maps.insert - // mapAttrs (_: legacyMap: legacyMap // {mode = namedModes.select;}) cfg.maps.select - // mapAttrs (_: legacyMap: legacyMap // {mode = namedModes.visual;}) cfg.maps.visual - // mapAttrs (_: legacyMap: legacyMap // {mode = namedModes.terminal;}) cfg.maps.terminal - // mapAttrs (_: legacyMap: legacyMap // {mode = namedModes.normalVisualOp;}) cfg.maps.normalVisualOp - // mapAttrs (_: legacyMap: legacyMap // {mode = namedModes.visualOnly;}) cfg.maps.visualOnly - // mapAttrs (_: legacyMap: legacyMap // {mode = namedModes.operator;}) cfg.maps.operator - // mapAttrs (_: legacyMap: legacyMap // {mode = namedModes.insertCommand;}) cfg.maps.insertCommand - // mapAttrs (_: legacyMap: legacyMap // {mode = namedModes.lang;}) cfg.maps.lang - // mapAttrs (_: legacyMap: legacyMap // {mode = namedModes.command;}) cfg.maps.command; - - keymaps = concatLines (map toLuaKeymap (attrsToList (filterAttrs (_: value: value != null) maps))); + keymaps = concatLines (map toLuaKeymap cfg.keymaps); in { vim = { luaConfigRC = {