feat: can load lazy plugins on keymaps

main
LeMarsu 2024-06-04 03:23:28 +02:00
parent 70484e221f
commit f52525abd1
5 changed files with 152 additions and 76 deletions

View File

@ -8,19 +8,19 @@ A [neovim] plugin and configuration management plugin, highly inspired by [lazy]
- [Features](#features) - [Features](#features)
- [SemVer](#semver) - [SemVer](#semver)
- [Installation](#installation) - [Installation](#installation)
- [Flake installation](#flake-installation) - [Flake installation](#flake-installation)
- [Usage](#usage) - [Usage](#usage)
- [Documentation](#documentation) - [Documentation](#documentation)
- [nix](#nix) - [nix](#nix)
- [`mkNeovimPkg`](#mkneovimpkg) - [`mkNeovimPkg`](#mkneovimpkg)
- [neovim (lua)](#neovim-lua) - [neovim (lua)](#neovim-lua)
- [Using default `init.lua`](#using-default-initlua) - [Using default `init.lua`](#using-default-initlua)
- [Using your own `init.lua`](#using-your-own-initlua) - [Using your own `init.lua`](#using-your-own-initlua)
- [`:Sloth` command](#sloth-command) - [`:Sloth` command](#sloth-command)
- [`list` subcommand](#list-subcommand) - [`list` subcommand](#list-subcommand)
- [`load` subcommand](#load-subcommand) - [`load` subcommand](#load-subcommand)
- [`version` subcommand](#version-subcommand) - [`version` subcommand](#version-subcommand)
- [API](#api) - [API](#api)
<!-- TOC --> <!-- TOC -->
@ -45,7 +45,7 @@ A [neovim] plugin and configuration management plugin, highly inspired by [lazy]
- [X] on command - [X] on command
- [X] on filetype - [X] on filetype
- [X] on event - [X] on event
- [ ] on keybinding - [X] on keybinding
- [X] load plugins in order (via plugin `dependencies` property) - [X] load plugins in order (via plugin `dependencies` property)
- [X] Have a `:Sloth` command to load or query your plugins - [X] Have a `:Sloth` command to load or query your plugins
- [ ] Generate spell files on build (maybe) - [ ] Generate spell files on build (maybe)
@ -167,6 +167,7 @@ The Plugin configuration object accepts the following properties:
| `cmd` | `[]` | Command to put as place_holder to load the lazy plugin⁴ | | `cmd` | `[]` | Command to put as place_holder to load the lazy plugin⁴ |
| `ft` | `[]` | Filetype to watch to load the lazy plugin⁴ | | `ft` | `[]` | Filetype to watch to load the lazy plugin⁴ |
| `events` | `[]` | Events to watch to load the lazy plugin⁴⁵ | | `events` | `[]` | Events to watch to load the lazy plugin⁴⁵ |
| `keymaps` | `[]` | Keymaps that when press will load the lazy plugin⁴⁶ |
> ² The plugin can be either a nix package or an object with only `name` and > ² The plugin can be either a nix package or an object with only `name` and
> `src` as properties. The latter will be used to create a nix package of your > `src` as properties. The latter will be used to create a nix package of your
@ -183,6 +184,8 @@ The Plugin configuration object accepts the following properties:
> represent a simple event name and pattern with the following string format : > represent a simple event name and pattern with the following string format :
> "BufRead *.md". > "BufRead *.md".
> ⁶ Keymaps can be a string, an Keymap object or a list of either.
The Event configuration object accepts the following properties: The Event configuration object accepts the following properties:
| name | default | description | | name | default | description |
@ -190,6 +193,13 @@ The Event configuration object accepts the following properties:
| `name` | N/A | The name of the event as string or list of string **REQUIRED** | | `name` | N/A | The name of the event as string or list of string **REQUIRED** |
| `pattern` | `null` | Pattern (as string or list of string) associated to the event | | `pattern` | `null` | Pattern (as string or list of string) associated to the event |
The Keymap configuration object accepts the following properties:
| name | default | description |
|-----------|---------|----------------------------------------------------|
| `mode` | `"n"` | The mode of the keymap as string or list of string |
| `mapping` | N/A | The actual mapping **REQUIRED** |
### neovim (lua) ### neovim (lua)
#### Using default `init.lua` #### Using default `init.lua`

View File

@ -28,6 +28,7 @@
cmd = []; cmd = [];
ft = []; ft = [];
events = []; events = [];
keymaps = [];
}; };
remotePluginToNeovimPlugin = p: remotePluginToNeovimPlugin = p:
@ -36,19 +37,32 @@
pname = name; pname = name;
}; };
defaultKeymap = {mode = "n";};
normalizeKeymap = keymap: let
value = (
if isString keymap
then {mapping = keymap;}
else keymap
);
in
mapAttrs (_: wrapArray) (defaultKeymap // value);
normalizeKeymaps = keymaps:
if isList keymaps
then map normalizeKeymap keymaps
else [(normalizeKeymap keymaps)];
normalizeEvent = event: let normalizeEvent = event: let
value = value =
if ! isString event if ! isString event
then event then event
else else if ! hasMatch ".* .*" event
if ! hasMatch ".* .*" event then {name = event;}
then {name = event;} else let
else let part = elemAt (splitString " " event);
part = elemAt (splitString " " event); in {
in { name = part 0;
name = part 0; pattern = part 1;
pattern = part 1; };
};
in in
mapAttrs (_: wrapArray) value; mapAttrs (_: wrapArray) value;
normalizeEvents = events: normalizeEvents = events:
@ -74,9 +88,11 @@
// rec { // rec {
hasCommands = p.cmd != []; hasCommands = p.cmd != [];
hasFileTypes = p.ft != []; hasFileTypes = p.ft != [];
keymaps = normalizeKeymaps p.keymaps;
hasKeymaps = p.keymaps != [];
events = normalizeEvents p.events; events = normalizeEvents p.events;
hasEvents = p.events != []; hasEvents = p.events != [];
lazy = p.lazy || hasCommands || hasFileTypes || hasEvents; lazy = p.lazy || hasCommands || hasFileTypes || hasEvents || hasKeymaps;
optional = lazy || p.init != null; optional = lazy || p.init != null;
}; };
@ -135,7 +151,6 @@
else content; else content;
pluginLuaDef = memo: plugin: let pluginLuaDef = memo: plugin: let
# plugin = builtins.removeAttrs plugin ["dependencies" "plugin"];
mkTypeFn = type: let mkTypeFn = type: let
content = textOrContent plugin.${type}; content = textOrContent plugin.${type};
in in
@ -168,6 +183,9 @@
}) })
// (optionalAttrs plugin.hasEvents { // (optionalAttrs plugin.hasEvents {
inherit (plugin) events; inherit (plugin) events;
})
// (optionalAttrs plugin.hasKeymaps {
inherit (plugin) keymaps;
}); });
}; };
pluginsLuaDef = plugins: pluginsLuaDef = plugins:

View File

@ -1,4 +1,10 @@
{yants, ...}: rec { {yants, ...}: let
stringList = with yants; list string;
stringOrStringList = with yants; either string stringList;
stringOrStringListOr = type:
with yants;
option (eitherN [string type (list (either string type))]);
in rec {
# The runtime object # The runtime object
runtimeType = with yants; runtimeType = with yants;
struct "runtime" { struct "runtime" {
@ -24,14 +30,22 @@
eventType = with yants; eventType = with yants;
struct "event" { struct "event" {
name = either string stringList; # The name of the event
pattern = either string stringList; name = stringOrStringList;
# The pattern of the event
pattern = stringOrStringList;
};
keymapType = with yants;
struct "keymap" {
# The mode of the keymap
mode = option stringOrStringList;
# The mapping of the keymap
mapping = stringOrStringList;
}; };
# The plugin type of dependencies # The plugin type of dependencies
pluginType = with yants; let pluginType = with yants;
stringList = list string;
in
struct "plugin" { struct "plugin" {
# Whether this plugin should be enabled. This option allows specific # Whether this plugin should be enabled. This option allows specific
# plugins to be disabled. # plugins to be disabled.
@ -55,7 +69,7 @@
lazy = option bool; lazy = option bool;
# List of events on which the plugin should be loaded # List of events on which the plugin should be loaded
events = option (eitherN [string eventType (list (either string eventType))]); events = option (stringOrStringListOr eventType);
# List of commands on which the plugin should be loaded # List of commands on which the plugin should be loaded
cmd = option stringList; cmd = option stringList;
@ -64,7 +78,7 @@
ft = option stringList; ft = option stringList;
# List of keystrokes on which the plugin should be loaded # List of keystrokes on which the plugin should be loaded
# keys = option stringList; keymaps = option (stringOrStringListOr keymapType);
# Priority of the module. Influence the order of loading plugins. # Priority of the module. Influence the order of loading plugins.
# Highest values get loaded before. # Highest values get loaded before.

View File

@ -18,40 +18,7 @@ function M.new(values)
self.sm = state_machine.build(State, { self.sm = state_machine.build(State, {
enter = { enter = {
[State.Shimed] = function() [State.Shimed] = function()
if self.cmd then return self:_shim()
for _, cmd in ipairs(self.cmd) do
vim.api.nvim_create_user_command(cmd, self:lazy_load_cmd(cmd), {
desc = "Sloth-flake placeholder for plugin " .. self.name,
nargs = '*',
bang = true,
})
end
end
if self.has_events then
local group_id = vim.api.nvim_create_augroup(self.augroup_name, {
clear = true,
})
if self.ft then
vim.api.nvim_create_autocmd('FileType', {
group = group_id,
pattern = self.ft,
callback = self:lazy_load_event('FileType')
})
end
if self.events then
for _, event in ipairs(self.events) do
-- print("register event", event.name, "for pattern", event.pattern)
vim.api.nvim_create_autocmd(event.name, {
group = group_id,
pattern = event.pattern,
callback = self:lazy_load_event(event.name)
})
end
end
end
end, end,
[State.Inited] = function() [State.Inited] = function()
for _, dep in ipairs(self.dependencies) do for _, dep in ipairs(self.dependencies) do
@ -81,15 +48,7 @@ function M.new(values)
}, },
exit = { exit = {
[State.Shimed] = function() [State.Shimed] = function()
if self.cmd then self:_unshim()
for _, cmd in ipairs(self.cmd) do
vim.api.nvim_del_user_command(cmd)
end
end
if self.has_events then
vim.api.nvim_del_augroup_by_name(self.augroup_name)
end
end, end,
}, },
events = { events = {
@ -152,6 +111,10 @@ function M:get_events()
return self.values.events return self.values.events
end end
function M:get_keymaps()
return self.values.keymaps
end
function M:get_is_lazy() function M:get_is_lazy()
return self.values.lazy or false return self.values.lazy or false
end end
@ -180,6 +143,70 @@ function M:shim()
return self.sm:shim() return self.sm:shim()
end end
function M:_shim()
if self.cmd then
for _, cmd in ipairs(self.cmd) do
vim.api.nvim_create_user_command(cmd, self:lazy_load_cmd(cmd), {
desc = "Sloth-flake placeholder for plugin " .. self.name,
nargs = '*',
bang = true,
})
end
end
if self.has_events then
local group_id = vim.api.nvim_create_augroup(self.augroup_name, {
clear = true,
})
if self.ft then
vim.api.nvim_create_autocmd('FileType', {
group = group_id,
pattern = self.ft,
callback = self:lazy_load_event('FileType')
})
end
if self.events then
for _, event in ipairs(self.events) do
vim.api.nvim_create_autocmd(event.name, {
group = group_id,
pattern = event.pattern,
callback = self:lazy_load_event(event.name)
})
end
end
end
if self.keymaps then
for _, keymap in ipairs(self.keymaps) do
for _, mapping in ipairs(keymap.mapping) do
vim.keymap.set(keymap.mode, mapping, self:lazy_load_mapping(mapping))
end
end
end
end
function M:_unshim()
if self.cmd then
for _, cmd in ipairs(self.cmd) do
vim.api.nvim_del_user_command(cmd)
end
end
if self.has_events then
vim.api.nvim_del_augroup_by_name(self.augroup_name)
end
if self.keymaps then
for _, keymap in ipairs(self.keymaps) do
for _, mapping in ipairs(keymap.mapping) do
vim.keymap.del(keymap.mode, mapping)
end
end
end
end
function M:init() function M:init()
return self.sm:init() return self.sm:init()
end end
@ -218,6 +245,13 @@ function M:lazy_load_event(name)
end end
end end
function M:lazy_load_mapping(mapping)
return function(param)
self:load()
vim.cmd.normal(mapping)
end
end
local deps = {} local deps = {}
for k, v in pairs(raw_deps) do for k, v in pairs(raw_deps) do
deps[k] = M.new(v) deps[k] = M.new(v)

View File

@ -50,8 +50,8 @@ function SM:run_enter_state(state)
end end
function SM:run_exit_state(state) function SM:run_exit_state(state)
local enter_fn = self.defs.exit and self.defs.exit[state] or empty_fn local exit_fn = self.defs.exit and self.defs.exit[state] or empty_fn
enter_fn(self.state) exit_fn(self.state)
end end
local function wrap_state_array(val) local function wrap_state_array(val)