diff --git a/lib/types.nix b/lib/types.nix index fbdc426..66d7ac2 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -25,8 +25,8 @@ let type = mode; default = ""; description = '' - Mode | Norm | Ins | Cmd | Vis | Sel | Opr | Term | Lang | - Command +------+-----+-----+-----+-----+-----+------+------+ + Mode | Norm | Ins | Cmd | Vis | Sel | Opr | Term | Lang | + Command +------+-----+-----+-----+-----+-----+------+------+ "" | yes | - | - | yes | yes | yes | - | - | "n" | yes | - | - | - | - | - | - | - | "!" | - | yes | yes | - | - | - | - | - | diff --git a/modules/vim/keymap.nix b/modules/vim/keymap.nix index 9e258ec..a55162f 100644 --- a/modules/vim/keymap.nix +++ b/modules/vim/keymap.nix @@ -1,10 +1,42 @@ -{ lib, ... }: +{ config, lib, ... }: +let cfg = config.vim.keymap; in { options.vim.keymap = with lib; { + _validate = mkOption { + # buffer mode lhs rhs + type = with types; attrsOf (attrsOf (attrsOf (either str attrs))); + visible = false; + internal = true; + readOnly = true; + }; set = mkOption { type = with types; listOf keymap; default = [ ]; }; }; + + config = { + vim.keymap._validate = lib.mkMerge + (map + ({ mode, lhs, rhs, buffer, ... }: + let + sourceModes = if builtins.isList mode then mode else [ mode ]; + unwrappedModes = lib.flatten (lib.flip map sourceModes (m: + if m == "" then [ "n" "x" "s" "o" ] + else if m == "!" then [ "i" "c" ] + else if m == "v" then [ "x" "s" ] + else if m == "l" then [ "i" "c" "l" ] + else m + )); + + buf = if buffer == null then "" else buffer; + in + lib.foldl lib.recursiveUpdate { } + (lib.flip map unwrappedModes (m: { + "${buf}"."${m}"."${lhs}" = rhs; + })) + ) + cfg.set); + }; }