diff --git a/plugins/by-name/leap/default.nix b/plugins/by-name/leap/default.nix index 7a43535c..a6e54002 100644 --- a/plugins/by-name/leap/default.nix +++ b/plugins/by-name/leap/default.nix @@ -1,191 +1,42 @@ { lib, - helpers, - config, - pkgs, ... }: -with lib; let - cfg = config.plugins.leap; + inherit (lib) types; in -{ - options.plugins.leap = lib.nixvim.plugins.neovim.extraOptionsOptions // { - enable = mkEnableOption "leap.nvim"; +lib.nixvim.plugins.mkNeovimPlugin { + name = "leap"; + package = "leap-nvim"; - package = lib.mkPackageOption pkgs "leap.nvim" { - default = [ - "vimPlugins" - "leap-nvim" - ]; - }; + maintainers = [ lib.maintainers.khaneliman ]; - addDefaultMappings = mkOption { + extraOptions = { + addDefaultMappings = lib.mkOption { type = types.bool; default = true; description = "Whether to enable the default mappings."; }; - - maxPhaseOneTargets = helpers.mkNullOrOption types.int '' - By default, the plugin shows labels and/or highlights matches right after the first input - character. - This option disables ahead-of-time displaying of target beacons beyond a certain number of - phase one targets (to mitigate visual noise in extreme cases). - Setting it to 0 disables two-phase processing altogether. - ''; - - highlightUnlabeledPhaseOneTargets = helpers.defaultNullOpts.mkBool false '' - Whether to highlight unlabeled (i.e., directly reachable) matches after the first input - character. - ''; - - maxHighlightedTraversalTargets = helpers.defaultNullOpts.mkInt 10 '' - Number of targets to be highlighted after the cursor in `|leap-traversal|` mode (when there - are no labels at all). - ''; - - caseSensitive = helpers.defaultNullOpts.mkBool false '' - Whether to consider case in search patterns. - ''; - - equivalenceClasses = helpers.defaultNullOpts.mkListOf' { - type = with types; either str (listOf str); - description = '' - A character will match any other in its equivalence class. The sets can - either be defined as strings or tables. - - Note: Make sure to have a set containing `\n` if you want to be able to - target characters at the end of the line. - - Note: Non-mutual aliases are not possible in Leap, for the same reason - that supporting |smartcase| is not possible: we would need to show two - different labels, corresponding to two different futures, at the same - time. - ''; - pluginDefault = [ " \t\r\n" ]; - example = [ - "\r\n" - ")]}>" - "([{<" - [ - "\"" - "'" - "`" - ] - ]; - }; - - substituteChars = helpers.defaultNullOpts.mkAttrsOf' { - type = types.str; - description = '' - The keys in this attrs will be substituted in labels and highlighted matches by the given - characters. - This way special (e.g. whitespace) characters can be made visible in matches, or even be - used as labels. - ''; - pluginDefault = { }; - example = { - "\r" = "¬"; - }; - }; - - safeLabels = - helpers.defaultNullOpts.mkNullable (with lib.types; maybeRaw (listOf str)) - (stringToCharacters "sfnut/SFNLHMUGT?Z") - '' - When the number of matches does not exceed the number of these "safe" labels plus one, the - plugin jumps to the first match automatically after entering the pattern. - Obviously, for this purpose you should choose keys that are unlikely to be used right - after a jump! - - Setting the list to `[]` effectively disables the autojump feature. - - Note: Operator-pending mode ignores this, since we need to be able to select the actual - target before executing the operation. - ''; - - labels = - helpers.defaultNullOpts.mkListOf types.str - (stringToCharacters "sfnjklhodwembuyvrgtcx/zSFNJKLHODWEMBUYVRGTCX?Z") - '' - Target labels to be used when there are more matches than labels in - `|leap.opts.safe_labels|` plus one. - - Setting the list to `[]` forces autojump to always be on (except for Operator-pending - mode, where it makes no sense). - In this case, do not forget to set `special_keys.next_group` to something "safe" too. - ''; - - specialKeys = { - nextTarget = helpers.defaultNullOpts.mkStr "" '' - Key captured by the plugin at runtime to jump to the next match in traversal mode - (`|leap-traversal|`) - ''; - - prevTarget = helpers.defaultNullOpts.mkStr "" '' - Key captured by the plugin at runtime to jump to the previous match in traversal mode - (`|leap-traversal|`) - ''; - - nextGroup = helpers.defaultNullOpts.mkStr "" '' - Key captured by the plugin at runtime to switch to the next group of matches, when there - are more matches than available labels. - ''; - - prevGroup = helpers.defaultNullOpts.mkStr "" '' - Key captured by the plugin at runtime to switch to the previous group of matches, when - there are more matches than available labels. - ''; - - multiAccept = helpers.defaultNullOpts.mkStr "" '' - Key captured by the plugin at runtime to accept the selection in `|leap-multiselect|` - mode. - ''; - - multiRevert = helpers.defaultNullOpts.mkStr "" '' - Key captured by the plugin at runtime to deselect the last selected target in - `|leap-multiselect|` mode. - ''; - }; }; - config = - let - options = - with cfg; - { - max_phase_one_targets = maxPhaseOneTargets; - highlight_unlabeled_phase_one_targets = highlightUnlabeledPhaseOneTargets; - max_highlighted_traversal_targets = maxHighlightedTraversalTargets; - case_sensitive = caseSensitive; - equivalence_classes = equivalenceClasses; - substitute_chars = substituteChars; - safe_labels = safeLabels; - inherit labels; - special_keys = with specialKeys; { - next_target = nextTarget; - prev_target = prevTarget; - next_group = nextGroup; - prev_group = prevGroup; - multi_accept = multiAccept; - multi_revert = multiRevert; - }; - } - // cfg.extraOptions; - in - mkIf cfg.enable { - extraPlugins = [ cfg.package ]; + callSetup = false; + extraConfig = cfg: { + plugins.leap.luaConfig.content = + lib.optionalString cfg.addDefaultMappings '' + require('leap').add_default_mappings() + '' + + lib.optionalString (cfg.settings != { }) '' + require('leap').opts = vim.tbl_deep_extend( + "keep", + ${lib.nixvim.toLuaObject cfg.settings}, + require('leap').opts + ) + ''; + }; - extraConfigLua = - (optionalString cfg.addDefaultMappings '' - require('leap').add_default_mappings() - '') - + (optionalString (options != { }) '' - require('leap').opts = vim.tbl_deep_extend( - "keep", - ${lib.nixvim.toLuaObject options}, - require('leap').opts - ) - ''); - }; + # TODO: Deprecated 2025-10-04 + inherit (import ./deprecations.nix) + optionsRenamedToSettings + deprecateExtraOptions + ; } diff --git a/plugins/by-name/leap/deprecations.nix b/plugins/by-name/leap/deprecations.nix new file mode 100644 index 00000000..afd89642 --- /dev/null +++ b/plugins/by-name/leap/deprecations.nix @@ -0,0 +1,38 @@ +{ + # TODO: added 2025-10-04 + deprecateExtraOptions = true; + optionsRenamedToSettings = [ + "maxPhaseOneTargets" + "highlightUnlabeledPhaseOneTargets" + "maxHighlightedTraversalTargets" + "caseSensitive" + "equivalenceClasses" + "substituteChars" + "safeLabels" + "labels" + [ + "specialKeys" + "nextTarget" + ] + [ + "specialKeys" + "prevTarget" + ] + [ + "specialKeys" + "nextGroup" + ] + [ + "specialKeys" + "prevGroup" + ] + [ + "specialKeys" + "multiAccept" + ] + [ + "specialKeys" + "multiRevert" + ] + ]; +} diff --git a/tests/test-sources/plugins/by-name/leap/default.nix b/tests/test-sources/plugins/by-name/leap/default.nix index 3e52fc22..31589162 100644 --- a/tests/test-sources/plugins/by-name/leap/default.nix +++ b/tests/test-sources/plugins/by-name/leap/default.nix @@ -1,3 +1,7 @@ +{ + lib, + ... +}: { empty = { plugins.leap.enable = true; @@ -7,98 +11,33 @@ autojump-disabled = { plugins.leap = { enable = true; - - safeLabels.__empty = null; + settings.safe_labels.__empty = null; }; }; example = { plugins.leap = { enable = true; - addDefaultMappings = true; - maxPhaseOneTargets = 10; - highlightUnlabeledPhaseOneTargets = false; - maxHighlightedTraversalTargets = 10; - caseSensitive = false; - equivalenceClasses = [ " \t\r\n" ]; - substituteChars = { - "\r" = "¬"; - }; - safeLabels = [ - "s" - "f" - "n" - "u" - "t" - "/" - "S" - "F" - "N" - "L" - "H" - "M" - "U" - "G" - "T" - "?" - "Z" - ]; - labels = [ - "s" - "f" - "n" - "j" - "k" - "l" - "h" - "o" - "d" - "w" - "e" - "m" - "b" - "u" - "y" - "v" - "r" - "g" - "t" - "c" - "x" - "/" - "z" - "S" - "F" - "N" - "J" - "K" - "L" - "H" - "O" - "D" - "W" - "E" - "M" - "B" - "U" - "Y" - "V" - "R" - "G" - "T" - "C" - "X" - "?" - "Z" - ]; - specialKeys = { - nextTarget = ""; - prevTarget = ""; - nextGroup = ""; - prevGroup = ""; - multiAccept = ""; - multiRevert = ""; + settings = { + max_phase_one_targets = 10; + highlight_unlabeled_phase_one_targets = false; + max_highlighted_traversal_targets = 10; + case_sensitive = false; + equivalence_classes = [ " \t\r\n" ]; + substitute_chars = { + "\r" = "¬"; + }; + safe_labels = lib.stringToCharacters "sfnut/SFNLHMUGT?Z"; + labels = lib.stringToCharacters "sfnjklhodwembuyvrgtcx/zSFNJKLHODWEMBUYVRGTCX?Z"; + special_keys = { + next_target = ""; + prev_target = ""; + next_group = ""; + prev_group = ""; + multi_accept = ""; + multi_revert = ""; + }; }; }; };