2024-05-05 15:59:53 +02:00
|
|
|
{
|
|
|
|
lib,
|
|
|
|
pkgs,
|
|
|
|
vPlug ? pkgs.vimPlugins,
|
|
|
|
luaUtils ? import ./luaUtils { inherit lib pkgs; },
|
|
|
|
}:
|
|
|
|
|
|
|
|
let
|
|
|
|
helpers = rec {
|
|
|
|
/**
|
|
|
|
Determines the name of a plugin.
|
|
|
|
|
|
|
|
Priority:
|
|
|
|
1. plugin.name
|
|
|
|
2. baseNameOf plugin.short
|
|
|
|
3. (derivation) plugin.dir.pname
|
|
|
|
3. (path) baseNameOf plugin.dir
|
|
|
|
|
|
|
|
Type:
|
|
|
|
getName :: Plugin -> String
|
|
|
|
*/
|
|
|
|
getName =
|
|
|
|
plugin:
|
|
|
|
if (plugin ? name && plugin.name != null) then
|
|
|
|
assert builtins.isString plugin.name;
|
|
|
|
plugin.name
|
|
|
|
else if (plugin ? short && plugin.short != null) then
|
|
|
|
assert builtins.isString plugin.short;
|
|
|
|
# TODO: Check how lazy handles this normally
|
|
|
|
baseNameOf plugin.short
|
|
|
|
else if (plugin ? dir && plugin.dir != null) then
|
|
|
|
(
|
2024-05-18 11:18:36 +02:00
|
|
|
assert builtins.any (isType: isType plugin.dir) [
|
|
|
|
lib.isDerivation
|
|
|
|
builtins.isString
|
|
|
|
builtins.isPath
|
|
|
|
];
|
2024-05-05 15:59:53 +02:00
|
|
|
if (lib.isDerivation plugin.dir) then plugin.dir.pname else (baseNameOf plugin.dir)
|
|
|
|
)
|
|
|
|
else
|
|
|
|
throw "Could not determine a plugin name.\n${builtins.toJSON plugin}";
|
|
|
|
|
|
|
|
/**
|
|
|
|
Transforms a set describing a keybind into a list (lazy-key).
|
|
|
|
Takes a set containing:
|
|
|
|
- bind: (string) the key to bind
|
|
|
|
- cmd: (optional string) the command to execute
|
|
|
|
- cmdIsFunction: (optional bool) interpret cmd as a function instead of a string
|
|
|
|
- opts: (optional set) the option set
|
|
|
|
|
|
|
|
For further information on the opts argument take a look at the lazy.nvim LazyKeysSpec definition.
|
|
|
|
|
|
|
|
Type:
|
|
|
|
getKey :: Set -> List
|
|
|
|
*/
|
|
|
|
getKey =
|
|
|
|
{
|
|
|
|
bind,
|
|
|
|
cmd ? null,
|
|
|
|
cmdIsFunction ? false,
|
|
|
|
opts ? null,
|
|
|
|
}:
|
|
|
|
lib.filter (option: !builtins.isNull option) [
|
|
|
|
bind
|
|
|
|
(if (cmdIsFunction == true) && (builtins.isString cmd) then (_: cmd) else cmd)
|
|
|
|
(if builtins.isAttrs opts then opts // { __unpack = true; } else null)
|
|
|
|
];
|
|
|
|
|
|
|
|
/**
|
|
|
|
Helper function to ensure a plugin input is correctly wrapped.
|
|
|
|
|
|
|
|
Correct inputs are:
|
|
|
|
- short plugin url (string)
|
|
|
|
- a plugin package (derivation)
|
|
|
|
- plugin (set)
|
|
|
|
|
|
|
|
Type:
|
2024-11-28 22:53:41 +01:00
|
|
|
pluginWrapper :: (Lambda -> String) -> Set
|
|
|
|
pluginWrapper :: (Lambda -> Derivation) -> Set
|
|
|
|
pluginWrapper :: (Lambda -> Set) -> Set
|
2024-05-05 15:59:53 +02:00
|
|
|
pluginWrapper :: String -> Set
|
|
|
|
pluginWrapper :: Derivation -> Set
|
|
|
|
pluginWrapper :: Set -> Set
|
|
|
|
*/
|
|
|
|
pluginWrapper =
|
|
|
|
pluginOrPackage:
|
|
|
|
if (builtins.isString pluginOrPackage) then
|
|
|
|
{ short = pluginOrPackage; }
|
|
|
|
else if
|
2024-11-28 22:53:41 +01:00
|
|
|
assert (builtins.isAttrs pluginOrPackage || builtins.isFunction pluginOrPackage);
|
|
|
|
(lib.isDerivation pluginOrPackage || builtins.isFunction pluginOrPackage)
|
2024-05-05 15:59:53 +02:00
|
|
|
then
|
2024-11-28 22:53:41 +01:00
|
|
|
{
|
|
|
|
dir = pluginOrPackage;
|
|
|
|
}
|
2024-05-05 15:59:53 +02:00
|
|
|
else
|
|
|
|
pluginOrPackage;
|
|
|
|
|
|
|
|
/**
|
|
|
|
Transforms plugin inputs into
|
|
|
|
|
|
|
|
Valid plugin attributes are:
|
|
|
|
- short, dir, url, name, dev, lazy, enabled, cond, dependencies, init, opts, config, main, build, branch, tag, commit, version, pin, submodules, event, cmd, ft, keys, module, priority, optional
|
|
|
|
|
|
|
|
Type:
|
|
|
|
pluginNormalize :: Set -> Set
|
|
|
|
*/
|
|
|
|
pluginNormalize =
|
|
|
|
pluginOrPackage:
|
|
|
|
let
|
|
|
|
plugin = pluginWrapper pluginOrPackage;
|
|
|
|
runIfSet =
|
|
|
|
fn: key:
|
|
|
|
let
|
|
|
|
val = if (plugin ? "${key}") then plugin."${key}" else null;
|
|
|
|
in
|
|
|
|
if (builtins.isNull val) then val else fn val;
|
|
|
|
# Wrap function arguments in function so they are inserted as is when parsed.
|
|
|
|
stringLiteral = value: if (builtins.isString value) then (_: value) else value;
|
2024-11-28 22:53:41 +01:00
|
|
|
resolvePlugin = value: if (builtins.isFunction value) then value vPlug else value;
|
2024-05-05 15:59:53 +02:00
|
|
|
in
|
|
|
|
lib.pipe plugin [
|
2024-11-28 22:53:41 +01:00
|
|
|
# Resolve dir and dependencies first so getName can resolve names
|
|
|
|
(
|
|
|
|
plugin:
|
|
|
|
plugin
|
|
|
|
// {
|
|
|
|
dir = runIfSet resolvePlugin "dir";
|
|
|
|
dependencies = runIfSet (
|
|
|
|
pluginListFn:
|
|
|
|
(map (pluginOrPackage: getName (pluginWrapper pluginOrPackage))) (resolvePlugin pluginListFn)
|
|
|
|
) "dependencies";
|
|
|
|
}
|
|
|
|
)
|
2024-05-05 15:59:53 +02:00
|
|
|
(
|
|
|
|
plugin:
|
|
|
|
plugin
|
|
|
|
// {
|
|
|
|
__posArgs = runIfSet lib.flatten "short";
|
|
|
|
name = getName plugin;
|
|
|
|
enabled = runIfSet stringLiteral "enabled";
|
|
|
|
cond = runIfSet stringLiteral "cond";
|
|
|
|
init = runIfSet stringLiteral "init";
|
|
|
|
opts = runIfSet stringLiteral "opts";
|
|
|
|
config = runIfSet stringLiteral "config";
|
|
|
|
build = runIfSet stringLiteral "build";
|
|
|
|
cmd = runIfSet stringLiteral "cmd";
|
|
|
|
ft = runIfSet stringLiteral "ft";
|
|
|
|
keys = runIfSet (map getKey) "keys";
|
|
|
|
}
|
|
|
|
)
|
|
|
|
# Remove unused attributes
|
|
|
|
(lib.filterAttrs (key: value: !builtins.isNull value))
|
|
|
|
# short is a positional argument so it has do be removed
|
|
|
|
(plugin: builtins.removeAttrs plugin [ "short" ])
|
|
|
|
];
|
|
|
|
};
|
|
|
|
in
|
|
|
|
rec {
|
|
|
|
inherit helpers;
|
|
|
|
/**
|
|
|
|
Takes a plugin definition normalizes it and convets it into Lua.
|
|
|
|
Returns only the plugin table so it can be inlined.
|
|
|
|
|
|
|
|
Type:
|
|
|
|
lazyPluginClosure :: String -> String
|
|
|
|
lazyPluginClosure :: Derivation -> String
|
|
|
|
lazyPluginClosure :: Set -> String
|
|
|
|
*/
|
|
|
|
lazyPluginClosure = plugin: luaUtils.setToLua (helpers.pluginNormalize plugin);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Takes a plugin definition normalizes it and convets it into Lua.
|
|
|
|
Wraps the result of lazyPluginClosure and adds a return statement in front of it.
|
|
|
|
|
|
|
|
Type:
|
|
|
|
lazyPluginFile :: String -> String
|
|
|
|
lazyPluginFile :: Derivation -> String
|
|
|
|
lazyPluginFile :: Set -> String
|
|
|
|
*/
|
|
|
|
lazyPluginFile =
|
|
|
|
plugin: # lua
|
|
|
|
''return ${lazyPluginClosure plugin}'';
|
|
|
|
|
|
|
|
/**
|
|
|
|
Takes a plugin and passes it to lazyPluginFile.
|
|
|
|
The output is formatted and written to "lua/lazyWrapper/plugins/${name}"
|
|
|
|
Note: ${name} is the Plugin name but all '.' are replaced with '-'.
|
|
|
|
|
|
|
|
Type:
|
|
|
|
writeLazyPluginDir :: String -> Derivation
|
|
|
|
writeLazyPluginDir :: Derivation -> Derivation
|
|
|
|
writeLazyPluginDir :: Set -> Derivation
|
|
|
|
*/
|
|
|
|
writeLazyPluginDir =
|
|
|
|
plugin:
|
|
|
|
let
|
2024-11-30 16:57:00 +01:00
|
|
|
normalizedPlugin = helpers.pluginNormalize plugin;
|
|
|
|
name = lib.replaceStrings [ "." ] [ "-" ] normalizedPlugin.name;
|
2024-05-05 15:59:53 +02:00
|
|
|
in
|
2024-11-30 16:57:00 +01:00
|
|
|
luaUtils.writeLuaFileDir "lua/lazyWrapper/plugins/${name}" ''return ${luaUtils.setToLua normalizedPlugin}'';
|
2024-05-05 15:59:53 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
Builds and configures the lazy plugin directory.
|
|
|
|
Takes a set containing:
|
|
|
|
- lazyPlugins: (list) the list of plugins to link
|
|
|
|
- lazyConfig: (set) lazy config attributes
|
|
|
|
|
|
|
|
Type:
|
|
|
|
lazyPluginsJoin :: Set -> Derivation
|
|
|
|
*/
|
|
|
|
lazyPluginsJoin =
|
|
|
|
{
|
|
|
|
lazyPlugins ? [ ],
|
|
|
|
lazyConfig ? { },
|
|
|
|
}:
|
|
|
|
let
|
|
|
|
init = lazyLuaInit {
|
|
|
|
inherit lazyConfig;
|
|
|
|
hasPlugins = (lib.length lazyPlugins > 0);
|
|
|
|
};
|
|
|
|
in
|
|
|
|
pkgs.symlinkJoin {
|
|
|
|
name = "nvim-lazy-plugins";
|
|
|
|
paths = [ init ] ++ (map (plugin: writeLazyPluginDir plugin) lazyPlugins);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
Generates the init function for nvim.lazy.
|
|
|
|
Takes a set containing:
|
|
|
|
- lazyConfig: (set) lazy config attributes
|
|
|
|
- hasPlugins: (bool) will not load any plugins if set to false
|
|
|
|
|
|
|
|
Type:
|
|
|
|
lazyLuaInit :: Set -> Derivation
|
|
|
|
*/
|
|
|
|
lazyLuaInit =
|
|
|
|
{
|
|
|
|
lazyConfig ? { },
|
|
|
|
hasPlugins ? false,
|
|
|
|
}:
|
|
|
|
let
|
|
|
|
lazyBaseConfig = {
|
|
|
|
checker = {
|
|
|
|
notify = false;
|
|
|
|
};
|
|
|
|
change_detection = {
|
|
|
|
enabled = false;
|
|
|
|
notify = false;
|
|
|
|
};
|
|
|
|
performance = {
|
|
|
|
# TODO: Check if this is really needed
|
|
|
|
reset_packpath = false;
|
|
|
|
rtp = {
|
|
|
|
reset = false;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
in
|
|
|
|
pkgs.writeTextDir "lua/lazyWrapper/init.lua" # lua
|
|
|
|
''
|
|
|
|
vim.opt.rtp:prepend("${vPlug.lazy-nvim}")
|
|
|
|
require("lazy").setup(
|
|
|
|
${
|
|
|
|
# Plugin import on an empty/non existent directory causes an error
|
|
|
|
# Only specify import path if there are plugins to load
|
|
|
|
if hasPlugins then ''"lazyWrapper.plugins"'' else "{}"
|
|
|
|
}
|
|
|
|
, ${
|
|
|
|
# Merge defaults with user config and generate the lua table
|
|
|
|
luaUtils.setToLua (lib.recursiveUpdate lazyBaseConfig lazyConfig)
|
|
|
|
} )
|
|
|
|
'';
|
|
|
|
}
|