Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 36 additions & 106 deletions lib/keymap-helpers.nix
Original file line number Diff line number Diff line change
Expand Up @@ -79,63 +79,43 @@ in rec {

# TODO: When `maps` will have to be deprecated (early December 2023), change this.
# mapOptionSubmodule = {...} (no need for options... except for 'optionalAction')
mkMapOptionSubmodule = {
defaultMode ? "",
withKeyOpt ? true,
flatConfig ? false,
}:
with types; let
mapOptionSubmodule = submodule {
options =
(
if withKeyOpt
then {
key = mkOption {
type = str;
description = "The key to map.";
example = "<C-m>";
};
}
else {}
)
// {
mode = mkOption {
type = either modeEnum (listOf modeEnum);
description = ''
One or several modes.
Use the short-names (`"n"`, `"v"`, ...).
See `:h map-modes` to learn more.
'';
default = defaultMode;
example = ["n" "v"];
};

action = mkOption {
type = str;
description = "The action to execute.";
};

lua = mkOption {
type = bool;
description = ''
If true, `action` is considered to be lua code.
Thus, it will not be wrapped in `""`.
'';
default = false;
};
}
// (
if flatConfig
then mapConfigOptions
else {
options = mapConfigOptions;
}
);
mapOptionSubmodule = with types;
submodule {
options = {
key = mkOption {
type = str;
description = "The key to map.";
example = "<C-m>";
};

mode = mkOption {
type = either modeEnum (listOf modeEnum);
description = ''
One or several modes.
Use the short-names (`"n"`, `"v"`, ...).
See `:h map-modes` to learn more.
'';
default = "";
example = ["n" "v"];
};

action = mkOption {
type = str;
description = "The action to execute.";
};

lua = mkOption {
type = bool;
description = ''
If true, `action` is considered to be lua code.
Thus, it will not be wrapped in `""`.
'';
default = false;
};

options = mapConfigOptions;
};
in
if flatConfig
then either str mapOptionSubmodule
else mapOptionSubmodule;
};

# Correctly merge two attrs (partially) representing a mapping.
mergeKeymap = defaults: keymap: let
Expand All @@ -145,56 +125,6 @@ in rec {
# Then, merge the root attrs together and add the previously merged `options` attrs.
(defaults // keymap) // {options = mergedOpts;};

# Given an attrs of key mappings (for a single mode), applies the defaults to each one of them.
#
# Example:
# mkModeMaps { silent = true; } {
# Y = "y$";
# "<C-c>" = { action = ":b#<CR>"; silent = false; };
# };
#
# would give:
# {
# Y = {
# action = "y$";
# silent = true;
# };
# "<C-c>" = {
# action = ":b#<CR>";
# silent = false;
# };
# };
mkModeMaps = defaults:
mapAttrs
(
key: action: let
actionAttrs =
if isString action
then {inherit action;}
else action;
in
defaults // actionAttrs
);

# Applies some default mapping options to a set of mappings
#
# Example:
# maps = mkMaps { silent = true; expr = true; } {
# normal = {
# ...
# };
# visual = {
# ...
# };
# }
mkMaps = defaults:
mapAttrs
(
name: modeMaps:
mkModeMaps defaults modeMaps
);

# TODO deprecate `mkMaps` and `mkModeMaps` and leave only this one
mkKeymaps = defaults:
map
(mergeKeymap defaults);
Expand Down
144 changes: 36 additions & 108 deletions modules/keymaps.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,59 +5,11 @@
...
}:
with lib; {
options = {
maps =
mapAttrs
(
modeName: modeProps: let
desc = modeProps.desc or modeName;
in
mkOption {
description = "Mappings for ${desc} mode";
type = with types;
attrsOf
(
either
str
(
helpers.keymaps.mkMapOptionSubmodule
{
defaultMode = modeProps.short;
withKeyOpt = false;
flatConfig = true;
}
)
);
default = {};
}
)
helpers.keymaps.modes;

keymaps = mkOption {
type =
types.listOf
(helpers.keymaps.mkMapOptionSubmodule {});
default = [];
example = [
{
key = "<C-m>";
action = "<cmd>make<CR>";
options.silent = true;
}
];
};
};

config = {
warnings =
optional
(
any
(modeMaps: modeMaps != {})
(attrValues config.maps)
)
# This warning has been added on 2023-12-02. TODO: remove it in early Feb. 2024.
imports = [
(mkRemovedOptionModule
["maps"]
''
The `maps` option will be deprecated in the near future.
Please, use the new `keymaps` option which works as follows:

keymaps = [
Expand All @@ -79,66 +31,42 @@ with lib; {
};
}
];
'';
'')
];

options = {
keymaps = mkOption {
type =
types.listOf
helpers.keymaps.mapOptionSubmodule;
default = [];
example = [
{
key = "<C-m>";
action = "<cmd>make<CR>";
options.silent = true;
}
];
};
};

config = {
extraConfigLua = let
modeMapsAsList =
flatten
(
mapAttrsToList
(
modeOptionName: modeProps:
mapAttrsToList
(
key: action:
(
if isString action
then {
mode = modeProps.short;
inherit action;
lua = false;
options = {};
}
else
{
inherit
(action)
action
lua
mode
;
}
// {
options =
getAttrs
(attrNames helpers.keymaps.mapConfigOptions)
action;
}
)
// {inherit key;}
)
config.maps.${modeOptionName}
)
helpers.keymaps.modes
);
normalizeMapping = keyMapping: {
inherit
(keyMapping)
mode
key
options
;

mappings = let
normalizeMapping = keyMapping: {
inherit
(keyMapping)
mode
key
options
;
action =
if keyMapping.lua
then helpers.mkRaw keyMapping.action
else keyMapping.action;
};

action =
if keyMapping.lua
then helpers.mkRaw keyMapping.action
else keyMapping.action;
};
in
map normalizeMapping
(config.keymaps ++ modeMapsAsList);
mappings = map normalizeMapping config.keymaps;
in
optionalString (mappings != [])
''
Expand Down
36 changes: 1 addition & 35 deletions tests/test-sources/modules/keymaps.nix
Original file line number Diff line number Diff line change
@@ -1,38 +1,4 @@
{helpers, ...}: {
legacy = {
maps.normal."," = "<cmd>echo \"test\"<cr>";
};

legacy-mkMaps = {
maps = helpers.keymaps.mkMaps {silent = true;} {
normal."," = "<cmd>echo \"test\"<cr>";
visual = {
"<C-a>" = {
action = "function() print('toto') end";
lua = true;
silent = false;
};
"<C-z>" = {
action = "bar";
};
};
};
};

legacy-mkModeMaps = {
maps.normal = helpers.keymaps.mkModeMaps {silent = true;} {
"," = "<cmd>echo \"test\"<cr>";
"<C-a>" = {
action = "function() print('toto') end";
lua = true;
silent = false;
};
"<leader>b" = {
action = "bar";
};
};
};

example = {
keymaps = [
{
Expand All @@ -47,7 +13,7 @@
];
};

mkMaps = {
mkKeymaps = {
keymaps =
helpers.keymaps.mkKeymaps
{
Expand Down