plugins/flash: switch to mkNeovimPlugin

This commit is contained in:
Matt Sturgeon 2024-06-17 16:08:58 +01:00 committed by MattSturgeon
parent 7cc1685eaf
commit aaab869d4f
2 changed files with 801 additions and 736 deletions

View file

@ -6,116 +6,315 @@
... ...
}: }:
with lib; with lib;
helpers.neovim-plugin.mkNeovimPlugin config {
name = "flash";
originalName = "flash.nvim";
defaultPackage = pkgs.vimPlugins.flash-nvim;
maintainers = with maintainers; [
traxys
MattSturgeon
];
# TODO: Added 2024-06-17; remove 2024-09-17
deprecateExtraOptions = true;
optionsRenamedToSettings =
let let
cfg = config.plugins.flash; # Combine base option paths with nested mode option paths
merged = flatten [
opts
(mapAttrsToList (mode: extras: map (opt: "${mode}.${opt}") (opts ++ extras)) modes)
];
# Option paths that should be renamed
opts = [
"labels"
"search.multiWindow"
"search.forward"
"search.wrap"
"search.mode"
"search.incremental"
"search.exclude"
"search.trigger"
"search.maxLength"
"jump.jumplist"
"jump.pos"
"jump.history"
"jump.register"
"jump.nohlsearch"
"jump.autojump"
"jump.inclusive"
"jump.offset"
"label.uppercase"
"label.exclude"
"label.current"
"label.after"
"label.before"
"label.style"
"label.reuse"
"label.distance"
"label.minPatternLength"
"label.rainbow.enabled"
"label.rainbow.shade"
"label.format"
"highlight.backdrop"
"highlight.matches"
"highlight.priority"
"highlight.group.match"
"highlight.group.current"
"highlight.group.backdrop"
"highlight.group.label"
"action"
"pattern"
"continue"
"config"
"prompt.enabled"
"prompt.prefix"
"prompt.winConfig.relative"
"prompt.winConfig.width"
"prompt.winConfig.height"
"prompt.winConfig.row"
"prompt.winConfig.col"
"prompt.winConfig.zindex"
"remoteOp.restore"
"remoteOp.motion"
];
# "Modes" that should also be renamed
# `opts` will get added to the attr value
modes = {
search = [ "enabled" ];
char = [
"enabled"
"autohide"
"jumpLabels"
"multiLine"
"keys"
"charActions"
];
treesitter = [ ];
treesitterSearch = [ ];
remote = [ ];
};
in
map (splitString ".") merged;
imports = [
# TODO: check automatic search config still works
(mkRemovedOptionModule [
"plugins"
"flash"
"search"
"automatic"
] "You can configure `plugins.flash.settings.modes.search.search.*` directly.")
];
settingsOptions =
let
# Default values used for the top-level settings options,
# also used as secondary defaults for mode options.
configDefaults = {
labels = "asdfghjklqwertyuiopzxcvbnm";
search = {
multi_window = true;
forward = true;
wrap = true;
mode = "exact";
incremental = false;
exclude = [
"notify"
"cmp_menu"
"noice"
"flash_prompt"
(helpers.mkRaw ''
function(win)
-- exclude non-focusable windows
return not vim.api.nvim_win_get_config(win).focusable
end
'')
];
trigger = "";
max_length = false;
};
jump = {
jumplist = true;
pos = "start";
history = false;
register = false;
nohlsearch = false;
autojump = false;
inclusive = null;
offset = null;
};
label = {
uppercase = true;
exclude = "";
current = true;
after = true;
before = false;
style = "overlay";
reuse = "lowercase";
distance = true;
min_pattern_length = 0;
rainbow = {
enabled = false;
shade = 5;
};
format = ''
function(opts)
return { { opts.match.label, opts.hl_group } }
end
'';
};
highlight = {
backdrop = true;
matches = true;
priority = 5000;
groups = {
match = "FlashMatch";
current = "FlashCurrent";
backdrop = "FlashBackdrop";
label = "FlashLabel";
};
};
action = null;
pattern = "";
continue = false;
config = null;
prompt = {
enabled = true;
prefix = [
[
""
"FlashPromptIcon"
]
];
win_config = {
relative = "editor";
width = 1;
height = 1;
row = -1;
col = 0;
zindex = 1000;
};
};
remote_op = {
restore = false;
motion = false;
};
};
# Shared config options, used by the top-level settings, as well as modes.
# Each usage has different default values.
configOpts =
defaultOverrides:
let
defaults = recursiveUpdate configDefaults defaultOverrides;
in in
{ {
options.plugins.flash = labels = helpers.defaultNullOpts.mkStr defaults.labels ''
let
configOpts = {
labels = helpers.defaultNullOpts.mkStr "asdfghjklqwertyuiopzxcvbnm" ''
Labels appear next to the matches, allowing you to quickly jump to any location. Labels are Labels appear next to the matches, allowing you to quickly jump to any location. Labels are
guaranteed not to exist as a continuation of the search pattern. guaranteed not to exist as a continuation of the search pattern.
''; '';
search = { search = {
automatic = mkOption { multi_window = helpers.defaultNullOpts.mkBool defaults.search.multi_window ''
type = types.bool; Search/jump in all windows
default = false;
description = ''
Automatically set the values according to context. Same as passing `search = {}` in lua
''; '';
};
multiWindow = helpers.defaultNullOpts.mkBool true "search/jump in all windows"; forward = helpers.defaultNullOpts.mkBool defaults.search.forward ''
Search direction
'';
forward = helpers.defaultNullOpts.mkBool true "search direction"; wrap = helpers.defaultNullOpts.mkBool defaults.search.wrap ''
Continue searching after reaching the start/end of the file.
wrap = helpers.defaultNullOpts.mkBool true '' When `false`, find only matches in the given direction
when `false`, find only matches in the given direction
''; '';
mode = mode =
helpers.defaultNullOpts.mkNullable helpers.defaultNullOpts.mkEnum
( [
with types;
either (enum [
"exact" "exact"
"search" "search"
"fuzzy" "fuzzy"
]) helpers.nixvimTypes.rawLua ]
) defaults.search.mode
''"exact"''
'' ''
- exact: exact match Each mode will take `ignorecase` and `smartcase` into account.
- search: regular search - `exact`: exact match
- fuzzy: fuzzy search - `search`: regular search
- fun(str): custom search function that returns a pattern - `fuzzy`: fuzzy search
- `__raw` fun(str): custom search function that returns a pattern
For example, to only match at the beginning of a word: For example, to only match at the beginning of a word:
```lua
function(str) function(str)
return "\\<" .. str return "\\<" .. str
end end
```
''; '';
incremental = helpers.defaultNullOpts.mkBool false "behave like `incsearch`"; incremental = helpers.defaultNullOpts.mkBool defaults.search.incremental ''
Behave like `incsearch`.
exclude =
helpers.defaultNullOpts.mkListOf types.str
[
"notify"
"cmp_menu"
"noice"
"flash_prompt"
{
__raw = ''
function(win)
return not vim.api.nvim_win_get_config(win).focusable
end
'';
}
]
''
Excluded filetypes and custom window filters
''; '';
trigger = helpers.defaultNullOpts.mkStr "" '' exclude = helpers.defaultNullOpts.mkListOf types.str defaults.search.exclude ''
Excluded filetypes and custom window filters.
'';
trigger = helpers.defaultNullOpts.mkStr defaults.search.trigger ''
Optional trigger character that needs to be typed before a jump label can be used. Optional trigger character that needs to be typed before a jump label can be used.
It's NOT recommended to set this, unless you know what you're doing It's NOT recommended to set this, unless you know what you're doing.
''; '';
maxLength = max_length =
helpers.defaultNullOpts.mkNullable (with types; either (enum [ false ]) types.int) false helpers.defaultNullOpts.mkNullable (with types; either (enum [ false ]) int)
defaults.search.max_length
'' ''
max pattern length. If the pattern length is equal to this labels will no longer be Max pattern length. If the pattern length is equal to this labels will no longer be skipped.
skipped. When it exceeds this length it will either end in a jump or terminate the search When it exceeds this length it will either end in a jump or terminate the search.
''; '';
}; };
jump = { jump = {
jumplist = helpers.defaultNullOpts.mkBool true "save location in the jumplist"; jumplist = helpers.defaultNullOpts.mkBool defaults.jump.jumplist ''
Save location in the jumplist.
'';
pos = helpers.defaultNullOpts.mkEnumFirstDefault [ pos =
helpers.defaultNullOpts.mkEnum
[
"start" "start"
"end" "end"
"range" "range"
] "jump position"; ]
defaults.jump.pos
history = helpers.defaultNullOpts.mkBool false "add pattern to search history"; ''
Jump position
register = helpers.defaultNullOpts.mkBool false "add pattern to search register";
nohlsearch = helpers.defaultNullOpts.mkBool false "clear highlight after jump";
autojump = helpers.defaultNullOpts.mkBool false ''
automatically jump when there is only one match
''; '';
inclusive = helpers.mkNullOrOption types.bool '' history = helpers.defaultNullOpts.mkBool defaults.jump.history ''
Add pattern to search history.
'';
register = helpers.defaultNullOpts.mkBool defaults.jump.register ''
Add pattern to search register.
'';
nohlsearch = helpers.defaultNullOpts.mkBool defaults.jump.nohlsearch ''
Clear highlight after jump
'';
autojump = helpers.defaultNullOpts.mkBool defaults.jump.autojump ''
Automatically jump when there is only one match
'';
inclusive = helpers.defaultNullOpts.mkBool defaults.jump.inclusive ''
You can force inclusive/exclusive jumps by setting the `inclusive` option. By default it You can force inclusive/exclusive jumps by setting the `inclusive` option. By default it
will be automatically set based on the mode. will be automatically set based on the mode.
''; '';
offset = helpers.mkNullOrOption types.int '' offset = helpers.defaultNullOpts.mkInt defaults.jump.offset ''
jump position offset. Not used for range jumps. jump position offset. Not used for range jumps.
0: default 0: default
1: when pos == "end" and pos < current position 1: when pos == "end" and pos < current position
@ -123,23 +322,31 @@ in
}; };
label = { label = {
uppercase = helpers.defaultNullOpts.mkBool true "allow uppercase labels"; uppercase = helpers.defaultNullOpts.mkBool defaults.label.uppercase ''
Allow uppercase labels.
'';
exclude = helpers.defaultNullOpts.mkStr "" '' exclude = helpers.defaultNullOpts.mkStr defaults.label.exclude ''
add any labels with the correct case here, that you want to exclude add any labels with the correct case here, that you want to exclude
''; '';
current = helpers.defaultNullOpts.mkBool true '' current = helpers.defaultNullOpts.mkBool true ''
add a label for the first match in the current window. Add a label for the first match in the current window.
you can always jump to the first match with `<CR>` You can always jump to the first match with `<CR>`
''; '';
after = helpers.defaultNullOpts.mkNullable (with types; either bool (listOf int)) true '' after =
show the label after the match helpers.defaultNullOpts.mkNullableWithRaw (with types; either bool (listOf int))
defaults.label.after
''
Show the label after the match
''; '';
before = helpers.defaultNullOpts.mkNullable (with types; either bool (listOf int)) false '' before =
show the label before the match helpers.defaultNullOpts.mkNullableWithRaw (with types; either bool (listOf int))
defaults.label.before
''
Show the label before the match
''; '';
style = style =
@ -150,51 +357,46 @@ in
"right_align" "right_align"
"inline" "inline"
] ]
"overlay" defaults.label.style
'' ''
position of the label extmark position of the label extmark
''; '';
reuse = reuse =
helpers.defaultNullOpts.mkEnumFirstDefault helpers.defaultNullOpts.mkEnum
[ [
"lowercase" "lowercase"
"all" "all"
"none" "none"
] ]
defaults.label.reuse
'' ''
flash tries to re-use labels that were already assigned to a position, flash tries to re-use labels that were already assigned to a position,
when typing more characters. By default only lower-case labels are re-used. when typing more characters. By default only lower-case labels are re-used.
''; '';
distance = helpers.defaultNullOpts.mkBool true '' distance = helpers.defaultNullOpts.mkBool defaults.label.distance ''
for the current window, label targets closer to the cursor first for the current window, label targets closer to the cursor first
''; '';
minPatternLength = helpers.defaultNullOpts.mkInt 0 '' min_pattern_length = helpers.defaultNullOpts.mkInt defaults.label.min_pattern_length ''
minimum pattern length to show labels minimum pattrn length to show labels
Ignored for custom labelers. Ignored for custom labelers.
''; '';
rainbow = { rainbow = {
enabled = helpers.defaultNullOpts.mkBool false '' enabled = helpers.defaultNullOpts.mkBool defaults.label.rainbow.enabled ''
Enable this to use rainbow colors to highlight labels Enable this to use rainbow colors to highlight labels
Can be useful for visualizing Treesitter ranges. Can be useful for visualizing Treesitter ranges.
''; '';
shade = helpers.defaultNullOpts.mkNullable (types.ints.between 1 9) 5 ""; shade = helpers.defaultNullOpts.mkNullable (types.ints.between 1 9) defaults.label.rainbow.shade "";
}; };
format = format = helpers.defaultNullOpts.mkLuaFn defaults.label.format ''
helpers.defaultNullOpts.mkLuaFn
''
format = function(opts)
return { { opts.match.label, opts.hl_group } }
end
''
''
With `format`, you can change how the label is rendered. With `format`, you can change how the label is rendered.
Should return a list of `[text, highlight]` tuples. Should return a list of `[text, highlight]` tuples.
@class Flash.Format @class Flash.Format
@field state Flash.State @field state Flash.State
@field match Flash.Match @field match Flash.Match
@ -205,13 +407,20 @@ in
}; };
highlight = { highlight = {
backdrop = helpers.defaultNullOpts.mkBool true "show a backdrop with hl FlashBackdrop"; backdrop = helpers.defaultNullOpts.mkBool defaults.highlight.backdrop ''
Show a backdrop with hl FlashBackdrop.
'';
matches = helpers.defaultNullOpts.mkBool true "Highlight the search matches"; matches = helpers.defaultNullOpts.mkBool defaults.highlight.matches ''
Highlight the search matches.
'';
priority = helpers.defaultNullOpts.mkPositiveInt 5000 "extmark priority"; priority = helpers.defaultNullOpts.mkPositiveInt defaults.highlight.priority ''
Extmark priority.
'';
groups = builtins.mapAttrs (_: default: helpers.defaultNullOpts.mkStr default "") { groups = mapAttrs (name: helpers.defaultNullOpts.mkStr defaults.highlight.groups.${name}) {
# opt = description
match = "FlashMatch"; match = "FlashMatch";
current = "FlashCurrent"; current = "FlashCurrent";
backdrop = "FlashBackdrop"; backdrop = "FlashBackdrop";
@ -219,51 +428,47 @@ in
}; };
}; };
action = helpers.defaultNullOpts.mkLuaFn "nil" '' action = helpers.defaultNullOpts.mkLuaFn defaults.action ''
action to perform when picking a label. action to perform when picking a label.
defaults to the jumping logic depending on the mode. defaults to the jumping logic depending on the mode.
@type fun(match:Flash.Match, state:Flash.State) @type fun(match:Flash.Match, state:Flash.State)
''; '';
pattern = helpers.defaultNullOpts.mkStr "" "initial pattern to use when opening flash"; pattern = helpers.defaultNullOpts.mkStr defaults.pattern ''
Initial pattern to use when opening flash.
continue = helpers.defaultNullOpts.mkBool false ''
When `true`, flash will try to continue the last search
''; '';
config = helpers.defaultNullOpts.mkLuaFn "nil" '' continue = helpers.defaultNullOpts.mkBool defaults.continue ''
Set config to a function to dynamically change the config When `true`, flash will try to continue the last search.
'';
config = helpers.defaultNullOpts.mkLuaFn defaults.config ''
Set config to a function to dynamically change the config.
@type fun(opts:Flash.Config) @type fun(opts:Flash.Config)
''; '';
prompt = { prompt = {
enabled = helpers.defaultNullOpts.mkBool true '' enabled = helpers.defaultNullOpts.mkBool defaults.prompt.enabled ''
options for the floating window that shows the prompt, for regular jumps Options for the floating window that shows the prompt, for regular jumps.
''; '';
# Not sure what is the type... # Not sure what the type is...
prefix = helpers.defaultNullOpts.mkListOf types.anything [ # Think it's listOf (maybeRaw (listOf (maybeRaw str)))?
[ prefix = helpers.defaultNullOpts.mkListOf types.anything defaults.prompt.prefix "";
""
"FlashPromptIcon" win_config = helpers.defaultNullOpts.mkAttrsOf types.anything defaults.prompt.win_config ''
] See `:h nvim_open_win` for more details.
] ""; '';
winConfig = helpers.defaultNullOpts.mkAttrsOf types.anything {
relative = "editor";
width = 1;
height = 1;
row = -1;
col = 0;
zindex = 1000;
} "See nvim_open_win for more details";
}; };
remoteOp = { remote_op = {
restore = helpers.defaultNullOpts.mkBool false '' restore = helpers.defaultNullOpts.mkBool defaults.remote_op.restore ''
restore window views and cursor position after doing a remote operation Restore window views and cursor position after doing a remote operation.
''; '';
motion = helpers.defaultNullOpts.mkBool false '' motion = helpers.defaultNullOpts.mkBool defaults.remote_op.motion ''
For `jump.pos = "range"`, this setting is ignored. For `jump.pos = "range"`, this setting is ignored.
- `true`: always enter a new motion when doing a remote operation - `true`: always enter a new motion when doing a remote operation
- `false`: use the window's cursor position and jump target - `false`: use the window's cursor position and jump target
@ -271,38 +476,41 @@ in
''; '';
}; };
}; };
in
helpers.neovim-plugin.extraOptionsOptions
// {
enable = mkEnableOption "flash.nvim";
package = helpers.mkPluginPackageOption "flash.nvim" pkgs.vimPlugins.flash-nvim; # The `mode`s have all the same options as top-level settings,
# but with different defaults and some additional options.
modes =
let
mkModeConfig = mkModeConfig =
{ {
extra ? { }, defaults ? { },
default, options ? { },
description ? "", ...
}: }@args:
helpers.defaultNullOpts.mkNullable (types.submodule { # FIXME: use mkNullableWithRaw when #1618 is fixed
options = configOpts // extra; helpers.defaultNullOpts.mkNullable' (
}) default description; (removeAttrs args [
in "options"
{ "defaults"
search = mkModeConfig { ])
description = '' // {
options used when flash is activated through a regular search with `/` or `?` type =
''; with types;
extra = { submodule {
enabled = helpers.defaultNullOpts.mkBool true '' freeformType = attrsOf anything;
when `true`, flash will be activated during regular search by default. options = recursiveUpdate (configOpts defaults) options;
You can always toggle when searching with `require("flash").toggle()`
'';
}; };
default = { }
enabled = true; );
in
(configOpts { })
// {
modes = {
search = mkModeConfig rec {
description = ''
Options used when flash is activated through a regular search,
e.g. with `/` or `?`.
'';
defaults = {
enabled = false;
highlight = { highlight = {
backdrop = false; backdrop = false;
}; };
@ -311,75 +519,31 @@ in
register = true; register = true;
nohlsearch = true; nohlsearch = true;
}; };
/* search = {
forward will be automatically set to the search direction forward.__raw = "vim.fn.getcmdtype() == '/'";
mode is always set to 'search' mode = "search";
incremental is set to 'true' when 'incsearch' is enabled incremental.__raw = "vim.go.incsearch";
*/
search.automatic = true;
}; };
}; };
char = mkModeConfig { options = {
description = "options used when flash is activated through a regular search with `/` or `?`"; enabled = helpers.defaultNullOpts.mkBool defaults.enabled ''
extra = { When `true`, flash will be activated during regular search by default.
enabled = helpers.defaultNullOpts.mkBool true ""; You can always toggle when searching with `require("flash").toggle()`
autohide = helpers.defaultNullOpts.mkBool false ''
hide after jump when not using jump labels
'';
jumpLabels = helpers.defaultNullOpts.mkBool false "show jump labels";
multiLine = helpers.defaultNullOpts.mkBool true ''
set to `false` to use the current line only
'';
keys =
helpers.defaultNullOpts.mkAttrsOf types.str
# FIXME can't show helper func in docs
(helpers.listToUnkeyedAttrs [
"f"
"F"
"t"
"T"
";"
","
])
''
by default all keymaps are enabled, but you can disable some of them,
by removing them from the list.
If you rather use another key, you can map them
to something else, e.g., `{ ";" = "L"; "," = "H"; }`
'';
charActions =
helpers.defaultNullOpts.mkLuaFn
''
function(motion)
return {
[";"] = "next", -- set to right to always go right
[","] = "prev", -- set to left to always go left
-- clever-f style
[motion:lower()] = "next",
[motion:upper()] = "prev",
-- jump2d style: same case goes next, opposite case goes prev
-- [motion] = "next",
-- [motion:match("%l") and motion:upper() or motion:lower()] = "prev",
}
end
''
''
The direction for `prev` and `next` is determined by the motion.
`left` and `right` are always left and right.
''; '';
}; };
default = { };
char = mkModeConfig rec {
description = ''
Options used when flash is activated through
`f`, `F`, `t`, `T`, `;` and `,` motions.
'';
defaults = {
enabled = true; enabled = true;
# dynamic configuration for ftFT motions
config = '' config = ''
-- dynamic configuration for ftFT motions
function(opts) function(opts)
-- autohide flash when in operator-pending mode -- autohide flash when in operator-pending mode
opts.autohide = vim.fn.mode(true):find("no") and vim.v.operator == "y" opts.autohide = opts.autohide or (vim.fn.mode(true):find("no") and vim.v.operator == "y")
-- disable jump labels when not enabled, when using a count, -- disable jump labels when not enabled, when using a count,
-- or when recording/executing registers -- or when recording/executing registers
@ -393,25 +557,17 @@ in
end end
''; '';
autohide = false; autohide = false;
jumpLabels = false; jump_labels = false;
multiLine = false; multi_line = true;
label = { label = {
exclude = "hjkliardc"; exclude = "hjkliardc";
}; };
# FIXME can't show the function call in the docs... keys = helpers.listToUnkeyedAttrs (lib.stringToCharacters "fFtT;,");
keys = helpers.listToUnkeyedAttrs [ char_actions = ''
"f"
"F"
"t"
"T"
";"
","
];
charActions = ''
function(motion) function(motion)
return { return {
[";"] = "next", -- set to right to always go right [";"] = "next", -- set to `right` to always go right
[","] = "prev", -- set to left to always go left [","] = "prev", -- set to `left` to always go left
-- clever-f style -- clever-f style
[motion:lower()] = "next", [motion:lower()] = "next",
[motion:upper()] = "prev", [motion:upper()] = "prev",
@ -421,29 +577,54 @@ in
} }
end end
''; '';
search = { search.wrap = false;
wrap = false; highlight.backdrop = true;
jump.register = false;
}; };
highlight = { options = {
backdrop = true; enabled = helpers.defaultNullOpts.mkBool defaults.enabled "";
autohide = helpers.defaultNullOpts.mkBool defaults.autohide ''
Hide after jump when not using jump labels.
'';
jump_labels = helpers.defaultNullOpts.mkBool defaults.jump_labels ''
Show jump labels.
'';
multi_line = helpers.defaultNullOpts.mkBool defaults.multi_line ''
Set to `false` to use the current line only.
'';
keys = helpers.defaultNullOpts.mkAttrsOf' {
type = types.str;
pluginDefault = defaults.keys;
description = ''
By default all keymaps are enabled, but you can disable some of them,
by removing them from the list.
If you rather use another key, you can map them to something else.
'';
example = {
";" = "L";
"," = "H";
}; };
jump = {
register = false;
}; };
char_actions = helpers.defaultNullOpts.mkLuaFn defaults.char_actions ''
The direction for `prev` and `next` is determined by the motion.
`left` and `right` are always left and right.
'';
}; };
}; };
treesitter = mkModeConfig { treesitter = mkModeConfig {
description = '' description = ''
options used for treesitter selections `require("flash").treesitter()` Options used for treesitter selections in `require("flash").treesitter()`.
''; '';
default = { defaults = {
labels = "abcdefghijklmnopqrstuvwxyz"; labels = "abcdefghijklmnopqrstuvwxyz";
jump = { jump.pos = "range";
pos = "range"; search.incremental = false;
};
search = {
incremental = false;
};
label = { label = {
before = true; before = true;
after = true; after = true;
@ -455,19 +636,18 @@ in
}; };
}; };
}; };
treesitterSearch = mkModeConfig { treesitter_search = mkModeConfig {
default = { description = ''
jump = { Options used when flash is activated through `require("flash").treesitter_search()`.
pos = "range"; '';
}; defaults = {
jump.pos = "range";
search = { search = {
multiWindow = true; multi_window = true;
wrap = true; wrap = true;
incremental = false; incremental = false;
}; };
remoteOp = { remote_op.restore = true;
restore = true;
};
label = { label = {
before = true; before = true;
after = true; after = true;
@ -476,119 +656,14 @@ in
}; };
}; };
remote = mkModeConfig { remote = mkModeConfig {
default = { description = "Options used for remote flash.";
remoteOp = { defaults = {
remote_op = {
restore = true; restore = true;
motion = true; motion = true;
}; };
}; };
description = "options used for remote flash"; };
}; };
}; };
} }
// configOpts;
config =
let
mkGlobalConfig = c: {
inherit (c) labels;
search =
if c.search.automatic then
helpers.emptyTable
else
{
multi_window = c.search.multiWindow;
inherit (c.search)
forward
wrap
mode
incremental
exclude
trigger
;
max_length = c.search.maxLength;
};
jump = {
inherit (c.jump)
jumplist
pos
history
register
nohlsearch
autojump
inclusive
offset
;
};
label = {
inherit (c.label)
uppercase
exclude
current
after
before
style
reuse
distance
;
min_pattern_length = c.label.minPatternLength;
rainbow = {
inherit (c.label.rainbow) enabled shade;
};
inherit (c.label) format;
};
highlight = {
inherit (c.highlight)
backdrop
matches
priority
groups
;
};
inherit (c)
action
pattern
continue
config
;
prompt = {
inherit (c.prompt) enabled prefix;
win_config = c.prompt.winConfig;
};
remote_op = {
inherit (c.remoteOp) restore motion;
};
};
options =
(mkGlobalConfig cfg)
// {
modes =
let
mkModeConfig = c: extra: helpers.ifNonNull' c ((mkGlobalConfig c) // (extra c));
in
{
search = mkModeConfig cfg.modes.search (c: {
inherit (c) enabled;
});
char = mkModeConfig cfg.modes.char (c: {
inherit (c) enabled autohide;
jump_labels = c.jumpLabels;
multi_line = c.multiLine;
inherit (c) keys charActions;
});
treesitter = mkModeConfig cfg.modes.treesitter (c: { });
treesitter_search = mkModeConfig cfg.modes.treesitterSearch (c: { });
remote = mkModeConfig cfg.modes.remote (c: { });
};
}
// cfg.extraOptions;
in
mkIf cfg.enable {
extraPlugins = [ cfg.package ];
extraConfigLua = ''
require('flash').setup(${helpers.toLuaObject options})
'';
};
}

View file

@ -8,9 +8,10 @@
plugins.flash = { plugins.flash = {
enable = true; enable = true;
settings = {
labels = "asdfghjklqwertyuiopzxcvbnm"; labels = "asdfghjklqwertyuiopzxcvbnm";
search = { search = {
multiWindow = true; multi_window = true;
forward = true; forward = true;
wrap = true; wrap = true;
mode = "exact"; mode = "exact";
@ -20,17 +21,15 @@
"cmp_menu" "cmp_menu"
"noice" "noice"
"flash_prompt" "flash_prompt"
{ (helpers.mkRaw ''
__raw = ''
function(win) function(win)
-- exclude non-focusable windows -- exclude non-focusable windows
return not vim.api.nvim_win_get_config(win).focusable return not vim.api.nvim_win_get_config(win).focusable
end end
''; '')
}
]; ];
trigger = ""; trigger = "";
maxLength = false; max_length = false;
}; };
jump = { jump = {
jumplist = true; jumplist = true;
@ -51,7 +50,7 @@
style = "overlay"; style = "overlay";
reuse = "lowercase"; reuse = "lowercase";
distance = true; distance = true;
minPatternLength = 0; min_pattern_length = 0;
rainbow = { rainbow = {
enabled = false; enabled = false;
shade = 5; shade = 5;
@ -85,7 +84,7 @@
"FlashPromptIcon" "FlashPromptIcon"
] ]
]; ];
winConfig = { win_config = {
relative = "editor"; relative = "editor";
width = 1; width = 1;
height = 1; height = 1;
@ -94,13 +93,13 @@
zindex = 1000; zindex = 1000;
}; };
}; };
remoteOp = { remote_op = {
restore = false; restore = false;
motion = false; motion = false;
}; };
modes = { modes = {
search = { search = {
enabled = true; enabled = false;
highlight = { highlight = {
backdrop = false; backdrop = false;
}; };
@ -109,14 +108,18 @@
register = true; register = true;
nohlsearch = true; nohlsearch = true;
}; };
search.automatic = true; search = {
forward.__raw = "vim.fn.getcmdtype() == '/'";
mode = "search";
incremental.__raw = "vim.go.incsearch";
};
}; };
char = { char = {
enabled = true; enabled = true;
config = '' config = ''
function(opts) function(opts)
-- autohide flash when in operator-pending mode -- autohide flash when in operator-pending mode
opts.autohide = vim.fn.mode(true):find("no") and vim.v.operator == "y" opts.autohide = opts.autohide or (vim.fn.mode(true):find("no") and vim.v.operator == "y")
-- disable jump labels when not enabled, when using a count, -- disable jump labels when not enabled, when using a count,
-- or when recording/executing registers -- or when recording/executing registers
@ -130,20 +133,20 @@
end end
''; '';
autohide = false; autohide = false;
jumpLabels = false; jump_labels = false;
multiLine = true; multi_line = true;
label = { label = {
exclude = "hjkliardc"; exclude = "hjkliardc";
}; };
keys = helpers.listToUnkeyedAttrs [ keys = {
"f" __unkeyed-0 = "f";
"F" __unkeyed-1 = "F";
"t" __unkeyed-2 = "t";
"T" __unkeyed-3 = "T";
";" __unkeyed-4 = ";";
"," __unkeyed-5 = ",";
]; };
charActions = '' char_actions = ''
function(motion) function(motion)
return { return {
[";"] = "next", -- set to `right` to always go right [";"] = "next", -- set to `right` to always go right
@ -157,24 +160,14 @@
} }
end end
''; '';
search = { search.wrap = false;
wrap = false; highlight.backdrop = true;
}; jump.register = false;
highlight = {
backdrop = true;
};
jump = {
register = false;
};
}; };
treesitter = { treesitter = {
labels = "abcdefghijklmnopqrstuvwxyz"; labels = "abcdefghijklmnopqrstuvwxyz";
jump = { jump.pos = "range";
pos = "range"; search.incremental = false;
};
search = {
incremental = false;
};
label = { label = {
before = true; before = true;
after = true; after = true;
@ -185,18 +178,14 @@
matches = false; matches = false;
}; };
}; };
treesitterSearch = { treesitter_search = {
jump = { jump.pos = "range";
pos = "range";
};
search = { search = {
multiWindow = true; multi_window = true;
wrap = true; wrap = true;
incremental = false; incremental = false;
}; };
remoteOp = { remote_op.restore = true;
restore = true;
};
label = { label = {
before = true; before = true;
after = true; after = true;
@ -204,7 +193,7 @@
}; };
}; };
remote = { remote = {
remoteOp = { remote_op = {
restore = true; restore = true;
motion = true; motion = true;
}; };
@ -212,4 +201,5 @@
}; };
}; };
}; };
};
} }