254 lines
7.1 KiB
Nix
254 lines
7.1 KiB
Nix
{
|
|
pkgs,
|
|
callModule,
|
|
...
|
|
}: let
|
|
inherit (builtins) concatMap elemAt isPath length pathExists readDir;
|
|
inherit
|
|
(pkgs.lib)
|
|
assertMsg
|
|
attrsToList
|
|
concatStringsSep
|
|
fileContents
|
|
fix
|
|
hasSuffix
|
|
literalExample
|
|
mergeAttrsList
|
|
mkOption
|
|
optional
|
|
optionalAttrs
|
|
pipe
|
|
removeSuffix
|
|
types
|
|
;
|
|
lua = callModule ../../lua.nix {};
|
|
|
|
modules = {
|
|
keymap = callModule ./keymap.nix {};
|
|
event = callModule ./event.nix {};
|
|
};
|
|
|
|
coercePkgToPlugin = pkg: {
|
|
plugin = pkg;
|
|
};
|
|
|
|
mkROBoolOption = default: description:
|
|
mkOption {
|
|
type = types.bool;
|
|
inherit default;
|
|
readOnly = true;
|
|
description = ''
|
|
Wether this plugin has ${description}.
|
|
'';
|
|
};
|
|
|
|
textOrContent = content:
|
|
if isPath content
|
|
then fileContents content
|
|
else content;
|
|
|
|
getPluginName = plugin: plugin.pname or plugin.name;
|
|
|
|
findLuaRequire = plugin: let
|
|
luaDir = "${plugin.plugin}/lua";
|
|
readOptionalDir = dir: optionalAttrs (pathExists dir) (readDir dir);
|
|
convertPath = attr:
|
|
if attr.value == "directory"
|
|
then optional (pathExists "${luaDir}/${attr.name}/init.lua") attr.name
|
|
else optional (hasSuffix ".lua" attr.name) (removeSuffix ".lua" attr.name);
|
|
requireNames = pipe plugin.plugin [
|
|
(path: "${path}/lua")
|
|
readOptionalDir
|
|
attrsToList
|
|
(concatMap convertPath)
|
|
];
|
|
in
|
|
if length requireNames == 1
|
|
then elemAt requireNames 0
|
|
else null;
|
|
|
|
mkLuaDefinition = plugin: let
|
|
mkTypeFn = type: let
|
|
content = textOrContent plugin.${type};
|
|
in
|
|
optionalAttrs (! isNull plugin.${type}) {
|
|
${type} = with lua; lambda [] (raw content);
|
|
};
|
|
name = getPluginName plugin.plugin;
|
|
in
|
|
assert assertMsg (with plugin; hasSetup -> hasLuaRequire) (concatStringsSep " " [
|
|
''Solth is unable to find the lib to require for plugin "${name}".''
|
|
''Either specify it with `luaRequire = "plugin-name";` or call setup''
|
|
''in a config option: `config = "require('plugin-name').setup { ... }";`.''
|
|
]);
|
|
mergeAttrsList ([
|
|
{
|
|
inherit name;
|
|
dependencies = map getPluginName plugin.dependencies;
|
|
}
|
|
(mkTypeFn "init")
|
|
(mkTypeFn "config")
|
|
]
|
|
++ (with plugin; [
|
|
(optionalAttrs lazy {lazy = true;})
|
|
(optionalAttrs hasCommands {inherit cmd;})
|
|
(optionalAttrs hasFileTypes {inherit ft;})
|
|
(optionalAttrs hasEvents {inherit events;})
|
|
(optionalAttrs hasKeymaps {inherit keymaps;})
|
|
(optionalAttrs hasLuaRequire {inherit luaRequire;})
|
|
(optionalAttrs hasSetup {inherit setup;})
|
|
]));
|
|
in
|
|
fix (self: {
|
|
module = types.submodule ({config, ...}: {
|
|
options = {
|
|
init = mkOption {
|
|
type = with types; nullOr (either path str);
|
|
default = null;
|
|
description = ''
|
|
The init configuration of your plugin.
|
|
This will be called before loading your plugin.
|
|
'';
|
|
};
|
|
|
|
config = mkOption {
|
|
type = with types; nullOr (either path str);
|
|
default = null;
|
|
description = ''
|
|
The configuration of your plugin.
|
|
This will be called after loading your plugin.
|
|
'';
|
|
};
|
|
|
|
optional = mkOption {
|
|
type = types.bool;
|
|
default = config.lazy || config.init != null;
|
|
example = true;
|
|
};
|
|
|
|
plugin = mkOption {
|
|
# TODO Type should allow old `basicPluginType` ({name:<str>, src:<source>})?
|
|
type = with types; nullOr package;
|
|
default = null;
|
|
description = ''
|
|
Ensure thoses plugins are loaded before the current one
|
|
'';
|
|
};
|
|
|
|
dependencies = mkOption {
|
|
type = with types; listOf package;
|
|
default = [];
|
|
description = ''
|
|
Ensure thoses plugins are loaded before the current one
|
|
'';
|
|
};
|
|
|
|
extraLuaPackages = mkOption {
|
|
type = with types; functionTo (listOf package);
|
|
example = literalExample "p: [p.nvim-nio]";
|
|
defaultText = literalExample "_: []";
|
|
default = _: [];
|
|
description = ''
|
|
Ensure those packages are available
|
|
'';
|
|
};
|
|
|
|
cmd = mkOption {
|
|
type = with types; listOf str;
|
|
default = [];
|
|
description = ''
|
|
List of commands on which the plugin should be loaded
|
|
'';
|
|
};
|
|
|
|
ft = mkOption {
|
|
type = with types; listOf str;
|
|
default = [];
|
|
description = ''
|
|
List of filetypes on which the plugin should be loaded
|
|
'';
|
|
};
|
|
|
|
keymaps = modules.keymap.option;
|
|
events = modules.event.option;
|
|
|
|
hasCommands = mkROBoolOption (config.cmd != []) "declared commands";
|
|
hasFileTypes = mkROBoolOption (config.ft != []) "file types";
|
|
hasKeymaps = mkROBoolOption (config.keymaps != []) "keymaps";
|
|
hasEvents = mkROBoolOption (config.events != []) "events";
|
|
hasSetup = mkROBoolOption (config.setup != null) "setup";
|
|
hasLuaRequire = mkROBoolOption (config.luaRequire != null) "luaRequire";
|
|
|
|
lazy = mkOption {
|
|
type = types.bool;
|
|
default = with config; hasCommands || hasFileTypes || hasEvents || hasKeymaps;
|
|
example = true;
|
|
description = ''
|
|
Whether to enable loading lazily the plugin.
|
|
'';
|
|
};
|
|
|
|
pluginName = mkOption {
|
|
type = types.str;
|
|
readOnly = true;
|
|
internal = true;
|
|
default = getPluginName config.plugin;
|
|
description = ''
|
|
Name of the plugin.
|
|
'';
|
|
};
|
|
|
|
luaDefinition = mkOption {
|
|
type = with types; attrsOf anything;
|
|
readOnly = true;
|
|
internal = true;
|
|
default = mkLuaDefinition config;
|
|
description = ''
|
|
Lua definition of the plugin.
|
|
'';
|
|
};
|
|
|
|
luaRequire = mkOption {
|
|
type = with types; nullOr str;
|
|
default = findLuaRequire config;
|
|
description = ''
|
|
Name of the lua module to require.
|
|
|
|
An heuristic should find it, but may fail sometimes.
|
|
'';
|
|
};
|
|
|
|
setup = mkOption {
|
|
type = with types; nullOr (attrsOf anything);
|
|
default = null;
|
|
description = ''
|
|
Option to pass the the setup function.
|
|
|
|
Will call `require("''${config.luaRequire}").setup(''${toLua config.setup})`.
|
|
'';
|
|
};
|
|
|
|
# priority = mkOption {
|
|
# type = types.int;
|
|
# default = [];
|
|
# description = ''
|
|
# Priority of the module. Influence the order of loading plugins.
|
|
# Highest values get loaded before.
|
|
# '';
|
|
# };
|
|
};
|
|
});
|
|
|
|
option = mkOption {
|
|
description = ''
|
|
List of plugins to enable in this installation
|
|
'';
|
|
type = with types; listOf (coercedTo package coercePkgToPlugin self.module);
|
|
default = [];
|
|
};
|
|
|
|
extract = plugin: {
|
|
inherit (plugin) plugin optional;
|
|
};
|
|
})
|