lib: move keymap and mode types to a lib

This commit is contained in:
Dmitriy Pleshevskiy 2024-04-28 00:39:50 +03:00
parent 85f2524196
commit 60f2d1e8ff
Signed by: pleshevskiy
GPG key ID: 17041163DA10A9A2
5 changed files with 166 additions and 145 deletions

View file

@ -3,16 +3,18 @@
, nix2lua ? import <nix2lua> , nix2lua ? import <nix2lua>
}: }:
let let
inherit (pkgs.lib) evalModules filter concatMapStringsSep showWarnings; inherit (pkgs.lib) evalModules filter concatMapStringsSep showWarnings;
extendedLib = import ./lib { inherit (pkgs) lib; };
allModules = import ./module-list.nix { inherit pkgs; }; allModules = import ./module-list.nix { inherit pkgs; };
rawModule = evalModules { rawModule = evalModules {
modules = [ config ] ++ allModules; modules = [ config ] ++ allModules;
specialArgs = { specialArgs = {
inherit pkgs; inherit pkgs;
lib = extendedLib;
nix2lua = nix2lua.lib; nix2lua = nix2lua.lib;
}; };
}; };

8
lib/default.nix Normal file
View file

@ -0,0 +1,8 @@
{ lib }:
let
types = import ./types.nix { inherit lib; };
in
lib // {
types = lib.types // types;
}

134
lib/types.nix Normal file
View file

@ -0,0 +1,134 @@
{ lib }:
let
modeEnum = lib.types.enum [ "" "n" "!" "i" "c" "v" "x" "s" "o" "t" "l" ];
mode = with lib.types; either modeEnum (uniq (listOf modeEnum));
# TODO: maybe add more options and add descriptions from
# :help vim.keymap.set
# :help nvim_set_keymap
keymap = lib.types.submodule ({ config, ... }: {
options = with lib; {
lhs = mkOption {
type = types.str;
description = ''
Left-hand side |{lhs}| of the mapping.
'';
};
rhs = mkOption {
type = with types; oneOf [ str attrs ];
description = ''
Right-hand side |{rhs}| of the mapping, can be a Lua function.
'';
};
mode = mkOption {
type = mode;
default = "";
description = ''
Mode | Norm | Ins | Cmd | Vis | Sel | Opr | Term | Lang |
Command +------+-----+-----+-----+-----+-----+------+------+
"" | yes | - | - | yes | yes | yes | - | - |
"n" | yes | - | - | - | - | - | - | - |
"!" | - | yes | yes | - | - | - | - | - |
"i" | - | yes | - | - | - | - | - | - |
"c" | - | - | yes | - | - | - | - | - |
"v" | - | - | - | yes | yes | - | - | - |
"x" | - | - | - | yes | - | - | - | - |
"s" | - | - | - | - | yes | - | - | - |
"o" | - | - | - | - | - | yes | - | - |
"t" | - | - | - | - | - | - | yes | - |
"l" | - | yes | yes | - | - | - | - | yes |
`:help map-overview`
'';
};
buffer = mkOption {
type = with types; nullOr str;
default = null;
description = ''
The mapping will be effective in the current buffer only.
`:help :map-buffer`
'';
};
nowait = mkOption {
type = types.bool;
default = false;
description = ''
When defining a buffer-local mapping for "," there may be a global mapping
that starts with ",". Then you need to type another character for Vim to know
whether to use the "," mapping or the longer one. To avoid this add the
<nowait> argument. Then the mapping will be used when it matches, Vim does
not wait for more characters to be typed.
`:help :map-nowait`
'';
};
silent = mkOption {
type = types.bool;
default = false;
description = ''
To define a mapping which will not be echoed on the command line.
`:help :map-silent`
'';
};
script = mkOption {
type = types.bool;
default = false;
description = ''
If the first argument to one of these commands is "<script>" and it is used to
define a new mapping or abbreviation, the mapping will only remap characters
in the {rhs} using mappings that were defined local to a script, starting with
"<SID>". This can be used to avoid that mappings from outside a script
interfere (e.g., when CTRL-V is remapped in mswin.vim), but do use other
mappings defined in the script.
`:help :map-script`
'';
};
expr = mkOption {
type = types.bool;
default = false;
description = ''
If the first argument to one of these commands is "<expr>" and it is used to
define a new mapping or abbreviation, the argument is an expression. The
expression is evaluated to obtain the {rhs} that is used.
`:help :map-expression`
'';
};
unique = mkOption {
type = types.bool;
default = false;
description = ''
It is used to define a new mapping or abbreviation, the command will fail if
the mapping or abbreviation already exists.
When defining a local mapping, there will also be a check if a global map
already exists which is equal.
`:help :map-unique`
'';
};
remap = mkOption {
type = types.bool;
default = false;
description = ''
Make the mapping recursive.
'';
};
desc = mkOption {
type = with types; nullOr str;
default = null;
description = ''
Human-readable description.
'';
};
};
});
in
{
inherit mode keymap;
}

View file

@ -6,28 +6,36 @@ let
disableKeymaps = mode: lhss: lib.flip map lhss (lhs: { inherit mode lhs; rhs = "<nop>"; }); disableKeymaps = mode: lhss: lib.flip map lhss (lhs: { inherit mode lhs; rhs = "<nop>"; });
in in
{ {
options.input = with lib; with types; { options.input = with lib; {
leader = mkOption { leader = mkOption {
type = str; type = types.str;
default = ''\''; default = ''\'';
apply = x: assert (builtins.stringLength x == 1 || abort "<Leader> `${x}` is longer than one character is not allowed"); x; apply = x: assert (builtins.stringLength x == 1 || abort "<Leader> `${x}` is longer than one character is not allowed"); x;
}; };
localLeader = mkOption { localLeader = mkOption {
type = str; type = types.str;
default = ''\''; default = ''\'';
apply = x: assert (builtins.stringLength x == 1 || abort "<LocalLeader> `${x}` is longer than one character is not allowed"); x; apply = x: assert (builtins.stringLength x == 1 || abort "<LocalLeader> `${x}` is longer than one character is not allowed"); x;
}; };
exMode.enable = (mkEnableOption "Ex mode") // { default = true; }; exMode.enable = (mkEnableOption "Ex mode") // { default = true; };
arrowKeys = { arrowKeys = {
disableInMode = mkOption { disable = mkOption {
type = oneOf [ str (uniq (listOf str)) ]; type = types.bool;
default = true;
};
mode = mkOption {
type = types.mode;
default = [ "n" "v" ]; default = [ "n" "v" ];
}; };
}; };
pageButtons = { pageButtons = {
disableInMode = mkOption { disable = mkOption {
type = oneOf [ str (uniq (listOf str)) ]; type = types.bool;
default = true;
};
mode = mkOption {
type = types.mode;
default = [ "n" "v" "i" ]; default = [ "n" "v" "i" ];
}; };
}; };
@ -40,10 +48,10 @@ in
# Disable the annoying and useless ex-mode # Disable the annoying and useless ex-mode
lib.optionals (!cfg.exMode.enable) (disableKeymaps "n" [ "Q" "gQ" ]) lib.optionals (!cfg.exMode.enable) (disableKeymaps "n" [ "Q" "gQ" ])
# Disable arrow keys # Disable arrow keys
++ lib.optionals (cfg.arrowKeys.disableInMode != [ ]) ++ lib.optionals cfg.arrowKeys.disable
(disableKeymaps cfg.arrowKeys.disableInMode [ "<Up>" "<Down>" "<Left>" "<Right>" ]) (disableKeymaps cfg.arrowKeys.mode [ "<Up>" "<Down>" "<Left>" "<Right>" ])
# Disable PageUp / PageDown # Disable PageUp / PageDown
++ lib.optionals (cfg.pageButtons.disableInMode != [ ]) ++ lib.optionals cfg.pageButtons.disable
(disableKeymaps cfg.pageButtons.disableInMode [ "<PageUp>" "<PageDown>" ]); (disableKeymaps cfg.pageButtons.mode [ "<PageUp>" "<PageDown>" ]);
}; };
} }

View file

@ -1,140 +1,9 @@
{ lib, ... }: { lib, ... }:
let
modeType = lib.types.enum [ "" "n" "!" "i" "c" "v" "x" "s" "o" "t" "l" ];
# TODO: maybe add more options and add descriptions from
# :help vim.keymap.set
# :help nvim_set_keymap
setKeymapType = with lib; with types; submodule {
options = {
lhs = mkOption {
type = str;
description = ''
Left-hand side |{lhs}| of the mapping.
'';
};
rhs = mkOption {
type = oneOf [ str attrs ];
description = ''
Right-hand side |{rhs}| of the mapping, can be a Lua function.
'';
};
mode = mkOption {
type = oneOf [
modeType
(uniq (listOf modeType))
];
default = "";
description = ''
Mode | Norm | Ins | Cmd | Vis | Sel | Opr | Term | Lang |
Command +------+-----+-----+-----+-----+-----+------+------+
"" | yes | - | - | yes | yes | yes | - | - |
"n" | yes | - | - | - | - | - | - | - |
"!" | - | yes | yes | - | - | - | - | - |
"i" | - | yes | - | - | - | - | - | - |
"c" | - | - | yes | - | - | - | - | - |
"v" | - | - | - | yes | yes | - | - | - |
"x" | - | - | - | yes | - | - | - | - |
"s" | - | - | - | - | yes | - | - | - |
"o" | - | - | - | - | - | yes | - | - |
"t" | - | - | - | - | - | - | yes | - |
"l" | - | yes | yes | - | - | - | - | yes |
`:help map-overview`
'';
};
buffer = mkOption {
type = nullOr str;
default = null;
description = ''
The mapping will be effective in the current buffer only.
`:help :map-buffer`
'';
};
nowait = mkOption {
type = bool;
default = false;
description = ''
When defining a buffer-local mapping for "," there may be a global mapping
that starts with ",". Then you need to type another character for Vim to know
whether to use the "," mapping or the longer one. To avoid this add the
<nowait> argument. Then the mapping will be used when it matches, Vim does
not wait for more characters to be typed.
`:help :map-nowait`
'';
};
silent = mkOption {
type = bool;
default = false;
description = ''
To define a mapping which will not be echoed on the command line.
`:help :map-silent`
'';
};
script = mkOption {
type = bool;
default = false;
description = ''
If the first argument to one of these commands is "<script>" and it is used to
define a new mapping or abbreviation, the mapping will only remap characters
in the {rhs} using mappings that were defined local to a script, starting with
"<SID>". This can be used to avoid that mappings from outside a script
interfere (e.g., when CTRL-V is remapped in mswin.vim), but do use other
mappings defined in the script.
`:help :map-script`
'';
};
expr = mkOption {
type = bool;
default = false;
description = ''
If the first argument to one of these commands is "<expr>" and it is used to
define a new mapping or abbreviation, the argument is an expression. The
expression is evaluated to obtain the {rhs} that is used.
`:help :map-expression`
'';
};
unique = mkOption {
type = bool;
default = false;
description = ''
It is used to define a new mapping or abbreviation, the command will fail if
the mapping or abbreviation already exists.
When defining a local mapping, there will also be a check if a global map
already exists which is equal.
`:help :map-unique`
'';
};
remap = mkOption {
type = bool;
default = false;
description = ''
Make the mapping recursive.
'';
};
desc = mkOption {
type = nullOr str;
default = null;
description = ''
Human-readable description.
'';
};
};
};
in
{ {
options.vim.keymap = with lib; with types; { options.vim.keymap = with lib; {
set = mkOption { set = mkOption {
type = listOf setKeymapType; type = with types; listOf keymap;
default = [ ]; default = [ ];
}; };
}; };