modules/keymap: improve lua deprecation

- Replace nullable lua option with a no-default option.
- Made it so the deprecated option is only declared when `lua = true` is passed.
- Replace `normalizeMappings` with a `removeDeprecatedMapAttrs` helper.
- Added warnings for all options that historically had `lua` support.
This commit is contained in:
Matt Sturgeon 2024-08-17 22:40:14 +01:00
parent c52ba67856
commit 7fb1f9dd9d
No known key found for this signature in database
GPG key ID: 4F91844CED1A8299
6 changed files with 115 additions and 104 deletions

View file

@ -58,6 +58,12 @@ rec {
mapOptionSubmodule = mkMapOptionSubmodule { }; mapOptionSubmodule = mkMapOptionSubmodule { };
# NOTE: options that have the deprecated `lua` sub-option must use `removeDeprecatedMapAttrs`
# to ensure `lua` isn't evaluated when (e.g.) generating lua code.
# Failure to do so will result in "option used but not defined" errors!
deprecatedMapOptionSubmodule = mkMapOptionSubmodule { lua = true; };
removeDeprecatedMapAttrs = v: builtins.removeAttrs v [ "lua" ];
mkModeOption = mkModeOption =
default: default:
mkOption { mkOption {
@ -81,13 +87,12 @@ rec {
# or an attrset to enable the option and add/override mkOption args. # or an attrset to enable the option and add/override mkOption args.
key ? true, key ? true,
action ? true, action ? true,
lua ? false, # WARNING: for historic use only - do not use in new options!
}: }:
# TODO remove assert once `lua` option is gone with types;
# This is here to ensure no uses of `mkMapOptionSubmodule` set a `lua` default submodule (
assert !(defaults ? lua); { config, options, ... }:
( {
with types;
submodule {
options = options =
(optionalAttrs (isAttrs key || key) { (optionalAttrs (isAttrs key || key) {
key = mkOption ( key = mkOption (
@ -105,27 +110,31 @@ rec {
{ {
type = helpers.nixvimTypes.maybeRaw str; type = helpers.nixvimTypes.maybeRaw str;
description = "The action to execute."; description = "The action to execute.";
apply = v: if options.lua.isDefined or false && config.lua then helpers.mkRaw v else v;
} }
// (optionalAttrs (isAttrs action) action) // (optionalAttrs (isAttrs action) action)
// (optionalAttrs (defaults ? action) { default = defaults.action; }) // (optionalAttrs (defaults ? action) { default = defaults.action; })
); );
}) })
// optionalAttrs (isAttrs lua || lua) {
lua = mkOption (
{
type = bool;
description = ''
If true, `action` is considered to be lua code.
Thus, it will not be wrapped in `""`.
This option is deprecated and will be removed in 24.11.
You should use a "raw" action instead, e.g. `action.__raw = ""`.
'';
visible = false;
}
// optionalAttrs (isAttrs lua) lua
);
}
// { // {
mode = mkModeOption defaults.mode or ""; mode = mkModeOption defaults.mode or "";
options = mapConfigOptions; options = mapConfigOptions;
lua = mkOption {
type = nullOr bool;
description = ''
If true, `action` is considered to be lua code.
Thus, it will not be wrapped in `""`.
This option is deprecated and will be removed in 24.11.
You should use a "raw" action instead, e.g. `action.__raw = ""`.
'';
default = null;
visible = false;
};
}; };
} }
); );

View file

@ -9,7 +9,7 @@ with lib;
{ {
options = { options = {
keymaps = mkOption { keymaps = mkOption {
type = types.listOf helpers.keymaps.mapOptionSubmodule; type = types.listOf helpers.keymaps.deprecatedMapOptionSubmodule;
default = [ ]; default = [ ];
description = "Nixvim keymaps."; description = "Nixvim keymaps.";
example = [ example = [
@ -22,7 +22,7 @@ with lib;
}; };
keymapsOnEvents = mkOption { keymapsOnEvents = mkOption {
type = types.attrsOf (types.listOf helpers.keymaps.mapOptionSubmodule); type = types.attrsOf (types.listOf helpers.keymaps.deprecatedMapOptionSubmodule);
default = { }; default = { };
example = { example = {
"InsertEnter" = [ "InsertEnter" = [
@ -43,82 +43,71 @@ with lib;
}; };
}; };
config = config = {
let # Deprecate `lua` keymap option
# TODO remove `normalizeMapping` once `lua` option is gone # TODO upgrade to an assertion (removal notice) in 24.11
normalizeMapping = keyMapping: { # TODO remove entirely in 25.05?
inherit (keyMapping) mode key options; warnings =
let
# All keymap options that have historically supported the `lua` sub-option
keymapOptions =
[
options.keymaps
options.keymapsOnEvents
options.plugins.wtf.keymaps.ai
options.plugins.wtf.keymaps.search
# NOTE: lsp `diagnostic` and `lspBuf` don't use `mapOptionSubmodule` yet
# So we only need `lua` deprecation in lsp's `extra` option
options.plugins.lsp.keymaps.extra
# NOTE: tmux-navigator added `mapOptionSubmodule` support _after_ branching off 24.05
options.plugins.tmux-navigator.keymaps
]
# NOTE: barbar added `mapOptionSubmodule` support shortly _before_ branching off 24.05
++ builtins.attrValues (builtins.removeAttrs options.plugins.barbar.keymaps [ "silent" ]);
in
lib.pipe keymapOptions [
(map (opt: (opt.type.getSubOptions opt.loc).lua))
(filter (opt: opt.isDefined))
(map (opt: ''
${"\n"}
The `${lib.showOption opt.loc}' option is deprecated and will be removed in 24.11.
action = You should use a "raw" `action` instead;
if keyMapping.lua != null && keyMapping.lua then
helpers.mkRaw keyMapping.action
else
keyMapping.action;
};
in
{
# Deprecate `lua` keymap option
# TODO upgrade to an assertion (removal notice) in 24.11
# TODO remove entirely in 25.05?
warnings =
let
luaDefs = pipe options.keymaps.definitionsWithLocations [
(map (def: {
inherit (def) file;
value = filter (v: (v.lua or null) != null) def.value;
}))
(filter (def: def.value != [ ]))
(map (
def:
let
count = length def.value;
plural = count > 1;
in
''
Found ${toString count} use${optionalString plural "s"} in ${def.file}:
${generators.toPretty { } def.value}
''
))
];
in
optional (luaDefs != [ ]) ''
Nixvim (keymaps): the `lua` keymap option is deprecated.
This option will be removed in 24.11. You should use a "raw" `action` instead;
e.g. `action.__raw = "<lua code>"` or `action = helpers.mkRaw "<lua code>"`. e.g. `action.__raw = "<lua code>"` or `action = helpers.mkRaw "<lua code>"`.
${concatStringsSep "\n" luaDefs} ${lib.options.showDefs opt.definitionsWithLocations}
''; ''))
];
extraConfigLua = mkIf (config.keymaps != [ ]) '' extraConfigLua = mkIf (config.keymaps != [ ]) ''
-- Set up keybinds {{{ -- Set up keybinds {{{
do do
local __nixvim_binds = ${helpers.toLuaObject (map normalizeMapping config.keymaps)} local __nixvim_binds = ${helpers.toLuaObject (map helpers.keymaps.removeDeprecatedMapAttrs config.keymaps)}
for i, map in ipairs(__nixvim_binds) do for i, map in ipairs(__nixvim_binds) do
vim.keymap.set(map.mode, map.key, map.action, map.options) vim.keymap.set(map.mode, map.key, map.action, map.options)
end
end end
-- }}} end
''; -- }}}
'';
autoGroups = mapAttrs' ( autoGroups = mapAttrs' (
event: mappings: nameValuePair "nixvim_binds_${event}" { clear = true; } event: mappings: nameValuePair "nixvim_binds_${event}" { clear = true; }
) config.keymapsOnEvents; ) config.keymapsOnEvents;
autoCmd = mapAttrsToList (event: mappings: { autoCmd = mapAttrsToList (event: mappings: {
inherit event; inherit event;
group = "nixvim_binds_${event}"; group = "nixvim_binds_${event}";
callback = helpers.mkRaw '' callback = helpers.mkRaw ''
function() function()
do do
local __nixvim_binds = ${helpers.toLuaObject (map normalizeMapping mappings)} local __nixvim_binds = ${helpers.toLuaObject (map helpers.keymaps.removeDeprecatedMapAttrs mappings)}
for i, map in ipairs(__nixvim_binds) do for i, map in ipairs(__nixvim_binds) do
vim.keymap.set(map.mode, map.key, map.action, map.options) vim.keymap.set(map.mode, map.key, map.action, map.options)
end
end end
end end
''; end
desc = "Load keymaps for ${event}"; '';
}) config.keymapsOnEvents; desc = "Load keymaps for ${event}";
}; }) config.keymapsOnEvents;
};
} }

View file

@ -193,12 +193,17 @@ helpers.neovim-plugin.mkNeovimPlugin config {
extraOptions = { extraOptions = {
keymaps = mapAttrs ( keymaps = mapAttrs (
optionName: funcName: optionName: funcName:
helpers.mkNullOrOption (helpers.keymaps.mkMapOptionSubmodule { helpers.mkNullOrOption' {
defaults = { type = helpers.keymaps.mkMapOptionSubmodule {
mode = "n"; defaults = {
action = "<Cmd>Buffer${funcName}<CR>"; mode = "n";
action = "<Cmd>Buffer${funcName}<CR>";
};
lua = true;
}; };
}) "Keymap for function Buffer${funcName}" apply = v: if v == null then null else helpers.keymaps.removeDeprecatedMapAttrs v;
description = "Keymap for function Buffer${funcName}";
}
) keymapsActions; ) keymapsActions;
}; };

View file

@ -47,7 +47,8 @@ in
}; };
extra = mkOption { extra = mkOption {
type = with types; listOf helpers.keymaps.mapOptionSubmodule; type = with types; listOf helpers.keymaps.deprecatedMapOptionSubmodule;
apply = map helpers.keymaps.removeDeprecatedMapAttrs;
description = '' description = ''
Extra keymaps to register when an LSP is attached. Extra keymaps to register when an LSP is attached.
This can be used to customise LSP behaviour, for example with "telescope" or the "Lspsaga" plugin, as seen in the examples. This can be used to customise LSP behaviour, for example with "telescope" or the "Lspsaga" plugin, as seen in the examples.

View file

@ -35,9 +35,18 @@ in
keymaps = mapAttrs ( keymaps = mapAttrs (
action: defaults: action: defaults:
helpers.mkNullOrOption ( helpers.mkNullOrOption' {
with types; either str (helpers.keymaps.mkMapOptionSubmodule { inherit defaults; }) type =
) "Keymap for the ${action} action." with types;
coercedTo str (key: defaultKeymaps.${action} // { inherit key; }) (
helpers.keymaps.mkMapOptionSubmodule {
inherit defaults;
lua = true;
}
);
apply = v: if v == null then null else helpers.keymaps.removeDeprecatedMapAttrs v;
description = "Keymap for the ${action} action.";
}
) defaultKeymaps; ) defaultKeymaps;
popupType = popupType =
@ -106,11 +115,7 @@ in
mkIf cfg.enable { mkIf cfg.enable {
extraPlugins = [ cfg.package ]; extraPlugins = [ cfg.package ];
keymaps = filter (keymap: keymap != null) ( keymaps = filter (keymap: keymap != null) (attrValues cfg.keymaps);
mapAttrsToList (
action: value: if isString value then defaultKeymaps.${action} // { key = value; } else value
) cfg.keymaps
);
extraConfigLua = '' extraConfigLua = ''
require("wtf").setup(${helpers.toLuaObject setupOptions}) require("wtf").setup(${helpers.toLuaObject setupOptions})

View file

@ -179,8 +179,10 @@ helpers.vim-plugin.mkVimPlugin config {
]; ];
example = "left"; example = "left";
}; };
lua = true;
} }
); );
apply = map helpers.keymaps.removeDeprecatedMapAttrs;
}; };
}; };