nix-community.nixvim/plugins/utils/yanky.nix

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

254 lines
8.9 KiB
Nix
Raw Normal View History

2023-12-19 15:01:46 +01:00
{
lib,
helpers,
config,
pkgs,
...
}:
with lib;
let
cfg = config.plugins.yanky;
in
{
options.plugins.yanky = helpers.neovim-plugin.extraOptionsOptions // {
2023-12-19 15:01:46 +01:00
enable = mkEnableOption "yanky.nvim";
2024-05-05 19:39:35 +02:00
package = helpers.mkPluginPackageOption "yanky.nvim" pkgs.vimPlugins.yanky-nvim;
2024-05-05 19:39:35 +02:00
2023-12-19 15:01:46 +01:00
ring = {
historyLength = helpers.defaultNullOpts.mkUnsignedInt 100 ''
Define the number of yanked items that will be saved and used for ring.
'';
2024-05-05 19:39:35 +02:00
2023-12-19 15:01:46 +01:00
storage =
helpers.defaultNullOpts.mkEnumFirstDefault
[
"shada"
"sqlite"
"memory"
]
''
Define the storage mode for ring values.
2024-05-05 19:39:35 +02:00
2023-12-19 15:01:46 +01:00
Using `shada`, this will save pesistantly using Neovim ShaDa feature.
This means that history will be persisted between each session of Neovim.
2024-05-05 19:39:35 +02:00
2023-12-19 15:01:46 +01:00
You can also use this feature to sync the yank history across multiple running instances
of Neovim by updating shada file.
If you execute `:wshada` in the first instance and then `:rshada` in the second instance,
the second instance will be synced with the yank history in the first instance.
2024-05-05 19:39:35 +02:00
2023-12-19 15:01:46 +01:00
Using `memory`, each Neovim instance will have his own history and il will be lost between
sessions.
2024-05-05 19:39:35 +02:00
2023-12-19 15:01:46 +01:00
Sqlite is more reliable than ShaDa but requires more dependencies.
You can change the storage path using `ring.storagePath` option.
2024-05-05 19:39:35 +02:00
'';
2023-12-19 15:01:46 +01:00
storagePath = helpers.defaultNullOpts.mkNullable (
with types; either str helpers.nixvimTypes.rawLua
) ''{__raw = "vim.fn.stdpath('data') .. '/databases/yanky.db'";}'' "Only for sqlite storage.";
2024-05-05 19:39:35 +02:00
2023-12-19 15:01:46 +01:00
syncWithNumberedRegisters = helpers.defaultNullOpts.mkBool true ''
History can also be synchronized with numbered registers.
Every time the yank history changes the numbered registers 1 - 9 will be updated to sync
with the first 9 entries in the yank history.
See [here](http://vimcasts.org/blog/2013/11/registers-the-good-the-bad-and-the-ugly-parts/) for an explanation of why we would want do do this.
2024-05-05 19:39:35 +02:00
'';
2023-12-19 15:01:46 +01:00
cancelEvent =
helpers.defaultNullOpts.mkEnumFirstDefault
2024-05-05 19:39:35 +02:00
[
"update"
"move"
]
''
2023-12-19 15:01:46 +01:00
Define the event used to cancel ring activation.
`update` will cancel ring on next buffer update, `move` will cancel ring when moving
cursor or content changed.
2024-05-05 19:39:35 +02:00
'';
2023-12-19 15:01:46 +01:00
ignoreRegisters = helpers.defaultNullOpts.mkNullable (with types; listOf str) ''["_"]'' ''
Define registers to be ignored.
By default the black hole register is ignored.
2024-05-05 19:39:35 +02:00
'';
2023-12-19 15:01:46 +01:00
updateRegisterOnCycle = helpers.defaultNullOpts.mkBool false ''
If true, when you cycle through the ring, the contents of the register used to update will
be updated with the last content cycled.
2024-05-05 19:39:35 +02:00
'';
};
2023-12-19 15:01:46 +01:00
picker = {
select = {
action = helpers.mkNullOrOption (with types; either helpers.nixvimTypes.rawLua str) ''
This define the action that should be done when selecting an item in the
`vim.ui.select` prompt.
If you let this option to `null`, this will use the default action: put selected item
after cursor.
2024-05-05 19:39:35 +02:00
2023-12-19 15:01:46 +01:00
This is either:
- a `rawLua` value (`action.__raw = "function() foo end";`).
- a string. In this case, Nixvim will automatically interpret it as a builtin yanky
2024-05-05 19:39:35 +02:00
action.
2023-12-19 15:01:46 +01:00
Example: `action = "put('p')";` will translate to
`action = require('yanky.picker').actions.put('p')` in lua.
'';
2024-05-05 19:39:35 +02:00
};
2023-12-19 15:01:46 +01:00
telescope = {
enable = mkEnableOption "the `yank_history` telescope picker.";
useDefaultMappings = helpers.defaultNullOpts.mkBool true ''
This define if default Telescope mappings should be used.
'';
mappings = helpers.mkNullOrOption (with types; attrsOf (attrsOf str)) ''
This define or overrides the mappings available in Telescope.
If you set `useDefaultMappings` to `true`, mappings will be merged with default
2024-03-07 19:44:13 +01:00
mappings.
2023-12-19 15:01:46 +01:00
2024-05-05 19:39:35 +02:00
Example:
```nix
{
i = {
2023-12-19 15:01:46 +01:00
"<c-g>" = "put('p')";
"<c-k>" = "put('P')";
"<c-x>" = "delete()";
"<c-r>" = "set_register(require('yanky.utils').get_default_register())";
2024-05-05 19:39:35 +02:00
};
2023-12-19 15:01:46 +01:00
n = {
p = "put('p')";
P = "put('P')";
d = "delete()";
r = "set_register(require('yanky.utils').get_default_register())";
2024-05-05 19:39:35 +02:00
};
}
```
2023-12-19 15:01:46 +01:00
'';
};
2024-05-05 19:39:35 +02:00
};
2023-12-19 15:01:46 +01:00
systemClipboard = {
syncWithRing = helpers.defaultNullOpts.mkBool true ''
Yanky can automatically adds to ring history yanks that occurs outside of Neovim.
This works regardless to your `&clipboard` setting.
This means, if `&clipboard` is set to `unnamed` and/or `unnamedplus`, if you yank
2024-03-07 19:44:13 +01:00
something outside of Neovim, you can put it immediately using `p` and it will be added to
2023-12-19 15:01:46 +01:00
your yank ring.
If `&clipboard` is empty, if you yank something outside of Neovim, this will be the first
value you'll have when cycling through the ring.
2024-03-07 19:44:13 +01:00
Basically, you can do `p` and then `<c-p>` to paste yanked text.
2023-12-19 15:01:46 +01:00
'';
};
highlight = {
onPut = helpers.defaultNullOpts.mkBool true ''
Define if highlight put text feature is enabled.
'';
onYank = helpers.defaultNullOpts.mkBool true ''
Define if highlight yanked text feature is enabled.
'';
timer = helpers.defaultNullOpts.mkUnsignedInt 500 ''
Define the duration of highlight.
'';
};
preserveCursorPosition = {
enabled = helpers.defaultNullOpts.mkBool true ''
Whether cursor position should be preserved on yank.
This works only if mappings has been defined.
'';
};
textobj = {
enabled = helpers.defaultNullOpts.mkBool true ''
Yanky comes with a text object corresponding to last put text.
To use it, you have to enable it and set a keymap.
'';
};
2024-05-05 19:39:35 +02:00
};
2023-12-19 15:01:46 +01:00
config =
let
thereAreSomeTelescopeMappings =
(cfg.picker.telescope.mappings != null) && (cfg.picker.telescope.mappings != { });
in
mkIf cfg.enable {
assertions = [
{
assertion = thereAreSomeTelescopeMappings -> cfg.picker.telescope.enable;
message = ''
Nixvim: You have defined some mappings in `plugins.yanky.picker.telescope.mappings` but
you have not set `plugins.yanky.picker.telescope.enable`.
'';
}
];
plugins.telescope.enable = true;
plugins.telescope.enabledExtensions = optional cfg.picker.telescope.enable "yank_history";
extraPlugins = [
cfg.package
] ++ (optional (cfg.ring.storage == "sqlite") pkgs.vimPlugins.sqlite-lua);
2024-05-05 19:39:35 +02:00
2023-12-19 15:01:46 +01:00
extraConfigLua =
let
setupOptions =
with cfg;
{
ring = {
history_length = ring.historyLength;
inherit (ring) storage;
storage_path = ring.storagePath;
sync_with_numbered_registers = ring.syncWithNumberedRegisters;
cancel_event = ring.cancelEvent;
ignore_registers = ring.ignoreRegisters;
update_register_on_cycle = ring.updateRegisterOnCycle;
};
picker = {
select = {
2024-05-05 19:39:35 +02:00
action =
2023-12-19 15:01:46 +01:00
if isString picker.select.action then
helpers.mkRaw "require('yanky.picker').actions.${picker.select.action}"
2024-05-05 19:39:35 +02:00
else
2023-12-19 15:01:46 +01:00
picker.select.action;
2024-05-05 19:39:35 +02:00
};
2023-12-19 15:01:46 +01:00
telescope = {
use_default_mappings = picker.telescope.useDefaultMappings;
mappings = helpers.ifNonNull' picker.telescope.mappings (
mapAttrs (
mode: mappings: mapAttrs (key: action: helpers.mkRaw "__yanky_telescope_mapping.${action}") mappings
) picker.telescope.mappings
);
2024-05-05 19:39:35 +02:00
};
};
system_clipboard = {
sync_with_ring = systemClipboard.syncWithRing;
2024-05-05 19:39:35 +02:00
};
highlight = {
on_put = highlight.onPut;
on_yank = highlight.onYank;
inherit (highlight) timer;
2024-05-05 19:39:35 +02:00
};
preserve_cursor_position = {
inherit (preserveCursorPosition) enabled;
2024-05-05 19:39:35 +02:00
};
textobj = {
inherit (textobj) enabled;
2023-12-19 15:01:46 +01:00
};
}
2023-12-19 15:01:46 +01:00
// cfg.extraOptions;
in
(optionalString thereAreSomeTelescopeMappings "local __yanky_telescope_mapping = require('yanky.telescope.mapping')")
+ ''
require('yanky').setup(${helpers.toLuaObject setupOptions})
'';
};
}