modules/keymaps: fix bug in keymaps generation (#300)

This commit is contained in:
Gaétan Lepage 2023-04-04 18:34:05 +02:00 committed by GitHub
parent 90d14f97d4
commit bd81037c5f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 119 additions and 106 deletions

View file

@ -49,42 +49,6 @@ with lib; rec {
emptyTable = {"__empty" = null;}; emptyTable = {"__empty" = null;};
# Generates maps for a lua config
genMaps = mode: maps: let
normalized =
builtins.mapAttrs
(key: action:
if builtins.isString action
then {
silent = false;
expr = false;
unique = false;
noremap = true;
remap = false;
script = false;
nowait = false;
action = action;
}
else {
inherit (action) silent expr unique noremap script nowait remap;
action =
if action.lua
then mkRaw action.action
else action.action;
})
maps;
in
builtins.attrValues (builtins.mapAttrs
(key: action: {
action = action.action;
config = lib.filterAttrs (_: v: v) {
inherit (action) silent expr unique noremap script nowait remap;
};
key = key;
mode = mode;
})
normalized);
# Given an attrs of key mappings (for a single mode), applies the defaults to each one of them. # Given an attrs of key mappings (for a single mode), applies the defaults to each one of them.
# #
# Example: # Example:

View file

@ -6,70 +6,119 @@
with lib; let with lib; let
helpers = import ../lib/helpers.nix {inherit lib;}; helpers = import ../lib/helpers.nix {inherit lib;};
# These are the configuration options that change the behavior of each mapping.
mapConfigOptions = {
silent =
helpers.defaultNullOpts.mkBool false
"Whether this mapping should be silent. Equivalent to adding <silent> to a map.";
nowait =
helpers.defaultNullOpts.mkBool false
"Whether to wait for extra input on ambiguous mappings. Equivalent to adding <nowait> to a map.";
script =
helpers.defaultNullOpts.mkBool false
"Equivalent to adding <script> to a map.";
expr =
helpers.defaultNullOpts.mkBool false
"Means that the action is actually an expression. Equivalent to adding <expr> to a map.";
unique =
helpers.defaultNullOpts.mkBool false
"Whether to fail if the map is already defined. Equivalent to adding <unique> to a map.";
noremap =
helpers.defaultNullOpts.mkBool true
"Whether to use the 'noremap' variant of the command, ignoring any custom mappings on the defined action. It is highly advised to keep this on, which is the default.";
remap =
helpers.defaultNullOpts.mkBool false
"Make the mapping recursive. Inverses \"noremap\"";
desc =
helpers.mkNullOrOption types.str
"A textual description of this keybind, to be shown in which-key, if you have it.";
};
# Generates maps for a lua config
genMaps = mode: maps: let
/*
Take a user-defined action (string or attrs) and return the following attribute set:
{
action = (string) the actual action to map to this key
config = (attrs) the configuration options for this mapping (noremap, silent...)
}
- If the action is a string:
{
action = action;
config = {};
}
- If the action is an attrs:
{
action = action;
config = {
inherit (action) <values of the config options that have been explicitly set by the user>
};
}
*/
normalizeAction = action:
if isString action
# Case 1: action is a string
then {
inherit action;
config = helpers.emptyTable;
}
else
# Case 2: action is an attrs
let
# Extract the values of the config options that have been explicitly set by the user
config =
filterAttrs (n: v: v != null)
(getAttrs (attrNames mapConfigOptions) action);
in {
config =
if config == {}
then helpers.emptyTable
else config;
action =
if action.lua
then helpers.mkRaw action.action
else action.action;
};
in
builtins.attrValues (builtins.mapAttrs
(key: action: let
normalizedAction = normalizeAction action;
in {
inherit (normalizedAction) action config;
key = key;
mode = mode;
})
maps);
mapOption = types.oneOf [ mapOption = types.oneOf [
types.str types.str
(types.submodule { (types.submodule {
options = { options =
silent = mkOption { mapConfigOptions
type = types.bool; // {
description = "Whether this mapping should be silent. Equivalent to adding <silent> to a map."; action = mkOption {
default = false; type = types.str;
}; description = "The action to execute.";
};
nowait = mkOption { lua = mkOption {
type = types.bool; type = types.bool;
description = "Whether to wait for extra input on ambiguous mappings. Equivalent to adding <nowait> to a map."; description = ''
default = false; If true, `action` is considered to be lua code.
Thus, it will not be wrapped in `""`.
'';
default = false;
};
}; };
script = mkOption {
type = types.bool;
description = "Equivalent to adding <script> to a map.";
default = false;
};
expr = mkOption {
type = types.bool;
description = "Means that the action is actually an expression. Equivalent to adding <expr> to a map.";
default = false;
};
unique = mkOption {
type = types.bool;
description = "Whether to fail if the map is already defined. Equivalent to adding <unique> to a map.";
default = false;
};
noremap = mkOption {
type = types.bool;
description = "Whether to use the 'noremap' variant of the command, ignoring any custom mappings on the defined action. It is highly advised to keep this on, which is the default.";
default = true;
};
remap = mkOption {
type = types.bool;
description = "Make the mapping recursive. Inverses \"noremap\"";
default = false;
};
action = mkOption {
type = types.str;
description = "The action to execute.";
};
lua = mkOption {
type = types.bool;
description = ''
If true, `action` is considered to be lua code.
Thus, it will not be wrapped in `""`.
'';
default = false;
};
description = helpers.mkNullOrOption types.str ''
A textual description of this keybind, to be shown in which-key, if you have it.
'';
};
}) })
]; ];
@ -119,17 +168,17 @@ in {
config = let config = let
mappings = mappings =
(helpers.genMaps "" config.maps.normalVisualOp) (genMaps "" config.maps.normalVisualOp)
++ (helpers.genMaps "n" config.maps.normal) ++ (genMaps "n" config.maps.normal)
++ (helpers.genMaps "i" config.maps.insert) ++ (genMaps "i" config.maps.insert)
++ (helpers.genMaps "v" config.maps.visual) ++ (genMaps "v" config.maps.visual)
++ (helpers.genMaps "x" config.maps.visualOnly) ++ (genMaps "x" config.maps.visualOnly)
++ (helpers.genMaps "s" config.maps.select) ++ (genMaps "s" config.maps.select)
++ (helpers.genMaps "t" config.maps.terminal) ++ (genMaps "t" config.maps.terminal)
++ (helpers.genMaps "o" config.maps.operator) ++ (genMaps "o" config.maps.operator)
++ (helpers.genMaps "l" config.maps.lang) ++ (genMaps "l" config.maps.lang)
++ (helpers.genMaps "!" config.maps.insertCommand) ++ (genMaps "!" config.maps.insertCommand)
++ (helpers.genMaps "c" config.maps.command); ++ (genMaps "c" config.maps.command);
in { in {
extraConfigLua = optionalString (mappings != []) '' extraConfigLua = optionalString (mappings != []) ''
-- Set up keybinds {{{ -- Set up keybinds {{{