From 847359287b48eb59e4e1d3cc02574095026dd0f3 Mon Sep 17 00:00:00 2001 From: LeMarsu Date: Tue, 21 Apr 2026 02:07:03 +0200 Subject: [PATCH] feat: can declare options to pass to `setup` via `setup` plugin option --- lib/evalModules.nix | 4 +- lib/modules/plugin/default.nix | 98 +++++++++++++++++++++++----- lua/sloth-flake/command/describe.lua | 1 + lua/sloth-flake/dep.lua | 12 ++++ 4 files changed, 97 insertions(+), 18 deletions(-) diff --git a/lib/evalModules.nix b/lib/evalModules.nix index c4d1803..a60584e 100644 --- a/lib/evalModules.nix +++ b/lib/evalModules.nix @@ -3,6 +3,7 @@ sloth, ... }: let + inherit (pkgs) callPackage; inherit (pkgs.lib) evalModules; sLib = sloth.lib; in { @@ -10,8 +11,9 @@ in { modules ? [], specialArgs ? {}, }: let + lua = callPackage ./lua.nix {}; moduleConfig = evalModules { - specialArgs = specialArgs // {inherit pkgs;}; + specialArgs = specialArgs // {inherit pkgs lua;}; modules = modules ++ [sLib.defaultModule]; class = "sloth"; }; diff --git a/lib/modules/plugin/default.nix b/lib/modules/plugin/default.nix index 0007891..7cd4f6c 100644 --- a/lib/modules/plugin/default.nix +++ b/lib/modules/plugin/default.nix @@ -3,8 +3,24 @@ callModule, ... }: let - inherit (builtins) isPath; - inherit (pkgs.lib) fileContents fix literalExample mergeAttrsList mkOption optionalAttrs types; + 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 = { @@ -32,6 +48,25 @@ 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}; @@ -41,21 +76,28 @@ }; name = getPluginName plugin.plugin; in - 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;}) - ])); + 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, ...}: { @@ -134,6 +176,8 @@ in 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; @@ -164,6 +208,26 @@ in ''; }; + 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 = []; diff --git a/lua/sloth-flake/command/describe.lua b/lua/sloth-flake/command/describe.lua index af9d53f..388444f 100644 --- a/lua/sloth-flake/command/describe.lua +++ b/lua/sloth-flake/command/describe.lua @@ -18,6 +18,7 @@ local function describe(dep) utils.info('Is lazy: %s', yesno(dep.is_lazy)) utils.info('Has init: %s', yesno(dep.has_init)) utils.info('Has config: %s', yesno(dep.has_config)) + utils.info('Has setup: %s', yesno(dep.has_setup)) utils.info('Dependencies: %s', list(dep.dependency_names)) utils.info('Filetypes: %s', list(dep.ft)) utils.info('Commands: %s', list(dep.cmd)) diff --git a/lua/sloth-flake/dep.lua b/lua/sloth-flake/dep.lua index 3b4b9ce..34daf67 100644 --- a/lua/sloth-flake/dep.lua +++ b/lua/sloth-flake/dep.lua @@ -42,8 +42,16 @@ function M.new(values) dep:config() end + local setup = self.values.setup local config = self.values.config or function() end config() + if setup then + local lib = require(self.values.luaRequire) + if type(setup) == 'function' then + setup = setup(lib) + end + lib.setup(setup) + end end }, exit = { @@ -139,6 +147,10 @@ function M:get_has_config() return not not self.values.config end +function M:get_has_setup() + return not not self.values.setup +end + function M:get_has_events() return self.ft or self.events end