nix-community.nixvim/plugins/by-name/leap/default.nix
2024-12-22 10:04:00 +00:00

191 lines
6.3 KiB
Nix

{
lib,
helpers,
config,
pkgs,
...
}:
with lib;
let
cfg = config.plugins.leap;
in
{
options.plugins.leap = lib.nixvim.plugins.neovim.extraOptionsOptions // {
enable = mkEnableOption "leap.nvim";
package = lib.mkPackageOption pkgs "leap.nvim" {
default = [
"vimPlugins"
"leap-nvim"
];
};
addDefaultMappings = 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 "<enter>" ''
Key captured by the plugin at runtime to jump to the next match in traversal mode
(`|leap-traversal|`)
'';
prevTarget = helpers.defaultNullOpts.mkStr "<tab>" ''
Key captured by the plugin at runtime to jump to the previous match in traversal mode
(`|leap-traversal|`)
'';
nextGroup = helpers.defaultNullOpts.mkStr "<space>" ''
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 "<tab>" ''
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 "<enter>" ''
Key captured by the plugin at runtime to accept the selection in `|leap-multiselect|`
mode.
'';
multiRevert = helpers.defaultNullOpts.mkStr "<backspace>" ''
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 ];
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
)
'');
};
}