{ config, lib, ... }: let cfg = config.vim.keymap; in { options.vim.keymap = with lib; { _validate = mkOption { # mode lhs rhs type = with types; 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.unique (lib.flatten (lib.flip map sourceModes (m: if m == "" then [ m "n" "x" "s" "o" ] else if m == "!" then [ m "i" "c" ] else if m == "v" then [ m "x" "s" ] else if m == "l" then [ m "i" "c" "l" ] else m ))); in lib.foldl lib.recursiveUpdate { } (lib.flip map unwrappedModes (m: { "${m}"."${lhs}" = rhs; })) ) cfg.set); }; }