lib/keymaps: remove lua submodule option

Co-authored-by: Austin Horstman <khaneliman12@gmail.com>
This commit is contained in:
Matt Sturgeon 2026-06-05 08:03:28 +01:00
parent 90ccd43c71
commit f2029d9a26
4 changed files with 96 additions and 104 deletions

View file

@ -65,7 +65,11 @@ rec {
# 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: removeAttrs v [ "lua" ];
removeDeprecatedMapAttrs = lib.flip removeAttrs [
"lua"
"assertions"
"warnings"
];
mkModeOption =
default:
@ -101,57 +105,52 @@ rec {
extraOptions ? { },
extraModules ? [ ],
}:
types.submodule (
{ config, options, ... }:
{
imports = extraModules;
options =
(lib.optionalAttrs (isAttrs key || key) {
key = lib.mkOption (
{
type = types.str;
description = "The key to map.";
example = "<C-m>";
}
// (optionalAttrs (isAttrs key) key)
// (optionalAttrs (defaults ? key) { default = defaults.key; })
);
})
// (optionalAttrs (isAttrs action || action) {
action = lib.mkOption (
{
type = types.maybeRaw types.str;
description = "The action to execute.";
apply = v: if options.lua.isDefined or false && config.lua then lib.nixvim.mkRaw v else v;
}
// (optionalAttrs (isAttrs action) action)
// (optionalAttrs (defaults ? action) { default = defaults.action; })
);
})
// optionalAttrs (isAttrs lua || lua) {
lua = lib.mkOption (
{
type = types.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
);
types.submodule {
imports =
extraModules
++ lib.optional (isAttrs lua || lua) (
{ options, ... }:
{
imports = [
../modules/misc/assertions.nix
# NOTE: we embed the full ${options.lua}, as mkRemovedOptionModule does not.
(lib.mkRemovedOptionModule [ "lua" ] ''
Full option: `${options.lua}`
Use a "raw lua" `action` instead;
e.g. `action.__raw = "<lua code>"` or `action = lib.nixvim.mkRaw "<lua code>"`.
'')
];
}
// {
mode = mkModeOption defaults.mode or "";
options = mapConfigOptions;
}
// extraOptions;
}
);
);
options =
(lib.optionalAttrs (isAttrs key || key) {
key = lib.mkOption (
{
type = types.str;
description = "The key to map.";
example = "<C-m>";
}
// (optionalAttrs (isAttrs key) key)
// (optionalAttrs (defaults ? key) { default = defaults.key; })
);
})
// (optionalAttrs (isAttrs action || action) {
action = lib.mkOption (
{
type = types.maybeRaw types.str;
description = "The action to execute.";
}
// (optionalAttrs (isAttrs action) action)
// (optionalAttrs (defaults ? action) { default = defaults.action; })
);
})
// {
mode = mkModeOption defaults.mode or "";
options = mapConfigOptions;
}
// extraOptions;
};
# Correctly merge two attrs (partially) representing a mapping.
mergeKeymap =

View file

@ -10,6 +10,30 @@ let
removeDeprecatedMapAttrs
deprecatedMapOptionSubmodule
;
# All keymap submodules that have historically supported the `lua` sub-option
legacyKeymapConfigurations =
lib.pipe
[
options.keymaps.valueMeta.list
(lib.concatMap (ev: ev.list) (lib.attrValues options.keymapsOnEvents.valueMeta.attrs))
# 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.valueMeta.list
# NOTE: tmux-navigator added `mapOptionSubmodule` support _after_ branching off 24.05
options.plugins.tmux-navigator.keymaps.valueMeta.list
# NOTE: barbar added `mapOptionSubmodule` support shortly _before_ branching off 24.05
(lib.mapAttrsToList (name: opt: opt.valueMeta) (
removeAttrs options.plugins.barbar.keymaps [ "silent" ]
))
]
[
lib.concatLists
(lib.catAttrs "configuration")
];
in
{
options = {
@ -49,46 +73,9 @@ in
};
config = {
# Deprecate `lua` keymap option
# TODO upgrade to an assertion (removal notice) in 24.11
# TODO remove entirely in 25.05?
warnings =
let
keymapsUsingLua =
lib.pipe
# All keymap options that have historically supported the `lua` sub-option
[
options.keymaps.valueMeta.list
(lib.concatMap (ev: ev.list) (lib.attrValues options.keymapsOnEvents.valueMeta.attrs))
# 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.valueMeta.list
# NOTE: tmux-navigator added `mapOptionSubmodule` support _after_ branching off 24.05
options.plugins.tmux-navigator.keymaps.valueMeta.list
# NOTE: barbar added `mapOptionSubmodule` support shortly _before_ branching off 24.05
(lib.mapAttrsToList (name: opt: opt.valueMeta) (
removeAttrs options.plugins.barbar.keymaps [ "silent" ]
))
]
[
lib.concatLists
(lib.filter (meta: meta.configuration.options.lua.isDefined or false))
(map (meta: meta.configuration.options))
];
in
lib.optional (keymapsUsingLua != [ ]) ''
The `lua` keymap option is deprecated and will be removed in 26.05.
You should use a "raw" `action` instead;
e.g. `action.__raw = "<lua code>"` or `action = lib.nixvim.mkRaw "<lua code>"`.
${lib.concatMapStringsSep "\n" (
m: "- `${m.lua}' is defined in " + lib.options.showFiles m.lua.files
) keymapsUsingLua}
'';
# Collect per-keymap warnings and assertions
assertions = lib.concatMap (c: c.config.assertions or [ ]) legacyKeymapConfigurations;
warnings = lib.concatMap (c: c.config.warnings or [ ]) legacyKeymapConfigurations;
extraConfigLua = lib.mkIf (config.keymaps != [ ]) ''
-- Set up keybinds {{{

View file

@ -46,10 +46,12 @@ let
};
# As of 2025-11-21, `either` supports `valueMeta`, while `nullOr` does not.
# The `lua` deprecation warning in `modules/keymaps.nix` requires `valueMeta`,
# See https://github.com/NixOS/nixpkgs/pull/525519
#
# The `lua` removal assertions in `modules/keymaps.nix` require `valueMeta`,
# so re-implement `nullOr` using `types.either` as a workaround.
#
# TODO: Remove with the warning, or once `nullOr` supports v2 check and merge.
# TODO: Remove when assertions are dropped or `nullOr` supports v2 checkAndMerge.
v2NullOr =
type:
let

View file

@ -93,7 +93,7 @@
};
};
luaWarning = {
luaError = {
imports = [
(lib.modules.setDefaultModuleLocation "test-module" {
keymaps = [
@ -132,16 +132,20 @@
})
];
test.warnings = expect: [
(expect "count" 1)
(expect "any" "The `lua` keymap option is deprecated and will be removed")
(expect "any" "You should use a \"raw\" `action` instead;")
(expect "any" "e.g. `action.__raw = \"<lua code>\"` or `action = lib.nixvim.mkRaw \"<lua code>\"`.")
(expect "any" "- `keymaps.\"[definition 1-entry 1]\".lua' is defined in `test-module'")
(expect "any" "- `keymapsOnEvents.InsertEnter.\"[definition 1-entry 1]\".lua' is defined in `test-module'")
(expect "any" "- `plugins.lsp.keymaps.extra.\"[definition 1-entry 1]\".lua' is defined in `test-module'")
(expect "any" "- `plugins.tmux-navigator.keymaps.\"[definition 1-entry 1]\".lua' is defined in `test-module'")
(expect "any" "- `plugins.barbar.keymaps.first.lua' is defined in `test-module'")
test.assertions = expect: [
# Failed assertions:
# - The option definition `lua' in `<unknown-file>' no longer has any effect; please remove it.
# Use a "raw lua" `action` instead;
# e.g. `action.__raw = "<lua code>"` or `action = lib.nixvim.mkRaw "<lua code>"`.
(expect "count" 5)
(expect "all" "The option definition `lua' in `test-module' no longer has any effect; please remove it.")
(expect "any" "Full option: `keymaps.\"[definition 1-entry 1]\".lua`")
(expect "any" "Full option: `keymapsOnEvents.InsertEnter.\"[definition 1-entry 1]\".lua`")
(expect "any" "Full option: `plugins.lsp.keymaps.extra.\"[definition 1-entry 1]\".lua`")
(expect "any" "Full option: `plugins.tmux-navigator.keymaps.\"[definition 1-entry 1]\".lua`")
(expect "any" "Full option: `plugins.barbar.keymaps.first.lua`")
(expect "all" "Use a \"raw lua\" `action` instead;")
(expect "all" "e.g. `action.__raw = \"<lua code>\"` or `action = lib.nixvim.mkRaw \"<lua code>\"`.")
];
test.runNvim = false;