257 lines
7.6 KiB
Nix
257 lines
7.6 KiB
Nix
|
{
|
||
|
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
|
||
|
(
|
||
|
assert ((builtins.isString plugin.dir) || (lib.isDerivation plugin.dir));
|
||
|
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:
|
||
|
pluginWrapper :: String -> Set
|
||
|
pluginWrapper :: Derivation -> Set
|
||
|
pluginWrapper :: Set -> Set
|
||
|
*/
|
||
|
pluginWrapper =
|
||
|
pluginOrPackage:
|
||
|
if (builtins.isString pluginOrPackage) then
|
||
|
{ short = pluginOrPackage; }
|
||
|
else if
|
||
|
assert (lib.isDerivation pluginOrPackage || builtins.isAttrs pluginOrPackage);
|
||
|
(lib.isDerivation pluginOrPackage)
|
||
|
then
|
||
|
{ dir = pluginOrPackage; }
|
||
|
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;
|
||
|
in
|
||
|
lib.pipe plugin [
|
||
|
(
|
||
|
plugin:
|
||
|
plugin
|
||
|
// {
|
||
|
__posArgs = runIfSet lib.flatten "short";
|
||
|
#if (builtins.isNull short) then short else [ short ];
|
||
|
name = getName plugin;
|
||
|
enabled = runIfSet stringLiteral "enabled";
|
||
|
cond = runIfSet stringLiteral "cond";
|
||
|
dependencies = runIfSet (map (
|
||
|
pluginOrPackage: getName (pluginWrapper pluginOrPackage)
|
||
|
)) "dependencies";
|
||
|
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
|
||
|
# normalie plugin file name
|
||
|
name = lib.replaceStrings [ "." ] [ "-" ] (helpers.getName (helpers.pluginWrapper plugin));
|
||
|
in
|
||
|
luaUtils.writeLuaFileDir "lua/lazyWrapper/plugins/${name}" (lazyPluginFile plugin);
|
||
|
|
||
|
/**
|
||
|
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)
|
||
|
} )
|
||
|
'';
|
||
|
}
|