diff --git a/lib/keymap-helpers.nix b/lib/keymap-helpers.nix index 0d5dc5f5..0285928f 100644 --- a/lib/keymap-helpers.nix +++ b/lib/keymap-helpers.nix @@ -58,6 +58,12 @@ rec { 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 = default: mkOption { @@ -81,13 +87,12 @@ rec { # or an attrset to enable the option and add/override mkOption args. key ? true, action ? true, + lua ? false, # WARNING: for historic use only - do not use in new options! }: - # TODO remove assert once `lua` option is gone - # This is here to ensure no uses of `mkMapOptionSubmodule` set a `lua` default - assert !(defaults ? lua); - ( - with types; - submodule { + with types; + submodule ( + { config, options, ... }: + { options = (optionalAttrs (isAttrs key || key) { key = mkOption ( @@ -105,27 +110,31 @@ rec { { type = helpers.nixvimTypes.maybeRaw str; 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 (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 ""; 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; - }; }; } ); diff --git a/modules/keymaps.nix b/modules/keymaps.nix index e58b9789..5349d3c4 100644 --- a/modules/keymaps.nix +++ b/modules/keymaps.nix @@ -9,7 +9,7 @@ with lib; { options = { keymaps = mkOption { - type = types.listOf helpers.keymaps.mapOptionSubmodule; + type = types.listOf helpers.keymaps.deprecatedMapOptionSubmodule; default = [ ]; description = "Nixvim keymaps."; example = [ @@ -22,7 +22,7 @@ with lib; }; keymapsOnEvents = mkOption { - type = types.attrsOf (types.listOf helpers.keymaps.mapOptionSubmodule); + type = types.attrsOf (types.listOf helpers.keymaps.deprecatedMapOptionSubmodule); default = { }; example = { "InsertEnter" = [ @@ -43,82 +43,71 @@ with lib; }; }; - config = - let - # TODO remove `normalizeMapping` once `lua` option is gone - normalizeMapping = keyMapping: { - inherit (keyMapping) mode key options; + config = { + # Deprecate `lua` keymap option + # TODO upgrade to an assertion (removal notice) in 24.11 + # TODO remove entirely in 25.05? + 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 = - 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; + You should use a "raw" `action` instead; e.g. `action.__raw = ""` or `action = helpers.mkRaw ""`. - ${concatStringsSep "\n" luaDefs} - ''; + ${lib.options.showDefs opt.definitionsWithLocations} + '')) + ]; - extraConfigLua = mkIf (config.keymaps != [ ]) '' - -- Set up keybinds {{{ - do - local __nixvim_binds = ${helpers.toLuaObject (map normalizeMapping config.keymaps)} - for i, map in ipairs(__nixvim_binds) do - vim.keymap.set(map.mode, map.key, map.action, map.options) - end + extraConfigLua = mkIf (config.keymaps != [ ]) '' + -- Set up keybinds {{{ + do + local __nixvim_binds = ${helpers.toLuaObject (map helpers.keymaps.removeDeprecatedMapAttrs config.keymaps)} + for i, map in ipairs(__nixvim_binds) do + vim.keymap.set(map.mode, map.key, map.action, map.options) end - -- }}} - ''; + end + -- }}} + ''; - autoGroups = mapAttrs' ( - event: mappings: nameValuePair "nixvim_binds_${event}" { clear = true; } - ) config.keymapsOnEvents; + autoGroups = mapAttrs' ( + event: mappings: nameValuePair "nixvim_binds_${event}" { clear = true; } + ) config.keymapsOnEvents; - autoCmd = mapAttrsToList (event: mappings: { - inherit event; - group = "nixvim_binds_${event}"; - callback = helpers.mkRaw '' - function() - do - local __nixvim_binds = ${helpers.toLuaObject (map normalizeMapping mappings)} - for i, map in ipairs(__nixvim_binds) do - vim.keymap.set(map.mode, map.key, map.action, map.options) - end + autoCmd = mapAttrsToList (event: mappings: { + inherit event; + group = "nixvim_binds_${event}"; + callback = helpers.mkRaw '' + function() + do + local __nixvim_binds = ${helpers.toLuaObject (map helpers.keymaps.removeDeprecatedMapAttrs mappings)} + for i, map in ipairs(__nixvim_binds) do + vim.keymap.set(map.mode, map.key, map.action, map.options) end end - ''; - desc = "Load keymaps for ${event}"; - }) config.keymapsOnEvents; - }; + end + ''; + desc = "Load keymaps for ${event}"; + }) config.keymapsOnEvents; + }; } diff --git a/plugins/bufferlines/barbar.nix b/plugins/bufferlines/barbar.nix index 25bfc20a..d77a03cc 100644 --- a/plugins/bufferlines/barbar.nix +++ b/plugins/bufferlines/barbar.nix @@ -193,12 +193,17 @@ helpers.neovim-plugin.mkNeovimPlugin config { extraOptions = { keymaps = mapAttrs ( optionName: funcName: - helpers.mkNullOrOption (helpers.keymaps.mkMapOptionSubmodule { - defaults = { - mode = "n"; - action = "Buffer${funcName}"; + helpers.mkNullOrOption' { + type = helpers.keymaps.mkMapOptionSubmodule { + defaults = { + mode = "n"; + action = "Buffer${funcName}"; + }; + 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; }; diff --git a/plugins/lsp/default.nix b/plugins/lsp/default.nix index 862b9b62..65f9aa83 100644 --- a/plugins/lsp/default.nix +++ b/plugins/lsp/default.nix @@ -47,7 +47,8 @@ in }; extra = mkOption { - type = with types; listOf helpers.keymaps.mapOptionSubmodule; + type = with types; listOf helpers.keymaps.deprecatedMapOptionSubmodule; + apply = map helpers.keymaps.removeDeprecatedMapAttrs; description = '' 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. diff --git a/plugins/lsp/wtf.nix b/plugins/lsp/wtf.nix index 236bb4a9..658847ac 100644 --- a/plugins/lsp/wtf.nix +++ b/plugins/lsp/wtf.nix @@ -35,9 +35,18 @@ in keymaps = mapAttrs ( action: defaults: - helpers.mkNullOrOption ( - with types; either str (helpers.keymaps.mkMapOptionSubmodule { inherit defaults; }) - ) "Keymap for the ${action} action." + helpers.mkNullOrOption' { + type = + 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; popupType = @@ -106,11 +115,7 @@ in mkIf cfg.enable { extraPlugins = [ cfg.package ]; - keymaps = filter (keymap: keymap != null) ( - mapAttrsToList ( - action: value: if isString value then defaultKeymaps.${action} // { key = value; } else value - ) cfg.keymaps - ); + keymaps = filter (keymap: keymap != null) (attrValues cfg.keymaps); extraConfigLua = '' require("wtf").setup(${helpers.toLuaObject setupOptions}) diff --git a/plugins/utils/tmux-navigator.nix b/plugins/utils/tmux-navigator.nix index 15c7ea72..05b0583a 100644 --- a/plugins/utils/tmux-navigator.nix +++ b/plugins/utils/tmux-navigator.nix @@ -179,8 +179,10 @@ helpers.vim-plugin.mkVimPlugin config { ]; example = "left"; }; + lua = true; } ); + apply = map helpers.keymaps.removeDeprecatedMapAttrs; }; };