{ lib, helpers, pkgs, config, ... }: with lib; { options.plugins.which-key = { enable = mkEnableOption "which-key.nvim, a plugin that popup with possible key bindings of the command you started typing"; package = helpers.mkPluginPackageOption "which-key-nvim" pkgs.vimPlugins.which-key-nvim; registrations = mkOption { type = with types; attrsOf anything; default = { }; description = "Manually register the description of mappings."; example = { "p" = "Find git files with telescope"; }; }; plugins = { marks = helpers.defaultNullOpts.mkBool true "shows a list of your marks on ' and `"; registers = helpers.defaultNullOpts.mkBool true ''shows your registers on " in NORMAL or in INSERT mode''; spelling = { enabled = helpers.defaultNullOpts.mkBool true "enabling this will show WhichKey when pressing z= to select spelling suggestions"; suggestions = helpers.defaultNullOpts.mkInt 20 "how many suggestions should be shown in the list?"; }; presets = { operators = helpers.defaultNullOpts.mkBool true "adds help for operators like d, y, ..."; motions = helpers.defaultNullOpts.mkBool true "adds help for motions"; textObjects = helpers.defaultNullOpts.mkBool true "help for text objects triggered after entering an operator"; windows = helpers.defaultNullOpts.mkBool true "default bindings on "; nav = helpers.defaultNullOpts.mkBool true "misc bindings to work with windows"; z = helpers.defaultNullOpts.mkBool true "bindings for folds, spelling and others prefixed with z"; g = helpers.defaultNullOpts.mkBool true "bindings for prefixed with g"; }; }; operators = helpers.defaultNullOpts.mkAttrsOf types.str { gc = "Comments"; } '' add operators that will trigger motion and text object completion to enable all native operators, set the preset / operators plugin above ''; keyLabels = helpers.defaultNullOpts.mkAttrsOf types.str { } '' override the label used to display some keys. It doesn't effect WK in any other way. ''; motions = { count = helpers.defaultNullOpts.mkBool true ""; }; icons = { breadcrumb = helpers.defaultNullOpts.mkStr "»" "symbol used in the command line area that shows your active key combo"; separator = helpers.defaultNullOpts.mkStr "➜" "symbol used between a key and it's label"; group = helpers.defaultNullOpts.mkStr "+" "symbol prepended to a group"; }; popupMappings = { scrollDown = helpers.defaultNullOpts.mkStr "" "binding to scroll down inside the popup"; scrollUp = helpers.defaultNullOpts.mkStr "" "binding to scroll up inside the popup"; }; window = let spacingOptions = types.submodule { options = genAttrs [ "top" "right" "bottom" "left" ] ( n: mkOption { type = types.ints.unsigned; description = "Spacing at the ${n}."; } ); }; in { border = helpers.defaultNullOpts.mkBorder "none" "which-key" ""; position = helpers.defaultNullOpts.mkEnumFirstDefault [ "bottom" "top" ] ""; margin = helpers.defaultNullOpts.mkNullable spacingOptions { top = 1; right = 0; bottom = 1; left = 0; } "extra window margin"; padding = helpers.defaultNullOpts.mkNullable spacingOptions { top = 1; right = 2; bottom = 1; left = 2; } "extra window padding"; winblend = helpers.defaultNullOpts.mkNullable (types.ints.between 0 100 ) 0 "0 for fully opaque and 100 for fully transparent"; }; layout = let rangeOption = types.submodule { options = { min = mkOption { type = types.int; description = "Minimum size."; }; max = mkOption { type = types.int; description = "Maximum size."; }; }; }; in { height = helpers.defaultNullOpts.mkNullable rangeOption { min = 4; max = 25; } "min and max height of the columns"; width = helpers.defaultNullOpts.mkNullable rangeOption { min = 20; max = 50; } "min and max width of the columns"; spacing = helpers.defaultNullOpts.mkInt 3 "spacing between columns"; align = helpers.defaultNullOpts.mkEnumFirstDefault [ "left" "center" "right" ] ""; }; ignoreMissing = helpers.defaultNullOpts.mkBool false "enable this to hide mappings for which you didn't specify a label"; hidden = helpers.defaultNullOpts.mkListOf types.str [ "" "" "" "" "^:" "^ " "^call " "^lua " ] "hide mapping boilerplate"; showHelp = helpers.defaultNullOpts.mkBool true "show a help message in the command line for using WhichKey"; showKeys = helpers.defaultNullOpts.mkBool true "show the currently pressed key and its label as a message in the command line"; triggers = helpers.defaultNullOpts.mkNullable ( with types; either (enum [ "auto" ]) (listOf str) ) "auto" "automatically setup triggers, or specify a list manually"; triggersNoWait = helpers.defaultNullOpts.mkListOf types.str [ "`" "'" "g`" "g'" "\"" "" "z=" ] '' list of triggers, where WhichKey should not wait for timeoutlen and show immediately ''; triggersBlackList = helpers.defaultNullOpts.mkAttrsOf (types.listOf types.str) { i = [ "j" "k" ]; v = [ "j" "k" ]; } '' list of mode / prefixes that should never be hooked by WhichKey this is mostly relevant for keymaps that start with a native binding ''; disable = { buftypes = helpers.defaultNullOpts.mkListOf types.str [ ] "Disabled by default for Telescope"; filetypes = helpers.defaultNullOpts.mkListOf types.str [ ] ""; }; }; config = let cfg = config.plugins.which-key; setupOptions = { plugins = { inherit (cfg.plugins) marks registers spelling; presets = { inherit (cfg.plugins.presets) operators motions; text_objects = cfg.plugins.presets.textObjects; inherit (cfg.plugins.presets) windows nav z g ; }; }; inherit (cfg) operators; key_labels = cfg.keyLabels; inherit (cfg) motions icons; popup_mappings = { scroll_down = cfg.popupMappings.scrollDown; scroll_up = cfg.popupMappings.scrollUp; }; window = let mkSpacing = opt: helpers.ifNonNull' opt [ opt.top opt.right opt.bottom opt.top ]; in { inherit (cfg.window) border position; margin = mkSpacing cfg.window.margin; padding = mkSpacing cfg.window.padding; inherit (cfg.window) winblend; }; inherit (cfg) layout; ignore_missing = cfg.ignoreMissing; inherit (cfg) hidden; show_help = cfg.showHelp; show_keys = cfg.showKeys; inherit (cfg) triggers; triggers_nowait = cfg.triggersNoWait; triggers_blacklist = cfg.triggersBlackList; inherit (cfg) disable; }; in mkIf cfg.enable { extraPlugins = [ cfg.package ]; extraConfigLua = '' require("which-key").setup(${helpers.toLuaObject setupOptions}) '' + (optionalString (cfg.registrations != { }) '' require("which-key").register(${helpers.toLuaObject cfg.registrations}) ''); }; }