From 27c8d275c501590a3510307e0b58f54156fd2e53 Mon Sep 17 00:00:00 2001 From: LeMarsu Date: Sat, 28 Feb 2026 00:56:00 +0100 Subject: [PATCH 01/12] refactor: simplify configuration creation --- lib/mkNeovimPkg.nix | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/mkNeovimPkg.nix b/lib/mkNeovimPkg.nix index c1366f8..9852686 100644 --- a/lib/mkNeovimPkg.nix +++ b/lib/mkNeovimPkg.nix @@ -86,18 +86,20 @@ then deps.textOrContent init else buildInit (optionalAttrs (! isNull init) init); - neovimConfig = - pkgs.neovimUtils.makeNeovimConfig { - inherit customRC; - plugins = extractPlugins plugins; - extraLuaPackages = ps: - (extractLuaPackagesFn plugins ps) ++ (extraLuaPackages ps); - } - // {luaRcContent = customRC;}; - params = - removeAttrs neovimConfig ["manifestRc" "neovimRcContent"] - // {inherit viAlias vimAlias;}; - pkg = pkgs.wrapNeovimUnstable package params; + neovimConfig = pkgs.neovimUtils.makeNeovimConfig { + # inherit customRC; + customLuaRC = customRC; + plugins = extractPlugins plugins; + extraLuaPackages = ps: + (extractLuaPackagesFn plugins ps) ++ (extraLuaPackages ps); + inherit viAlias vimAlias; + # autoconfigure = false; + }; + # // {luaRcContent = customRC;}; + # params = + # removeAttrs neovimConfig ["neovimRcContent"] + # // {inherit viAlias vimAlias;}; + pkg = pkgs.wrapNeovimUnstable package neovimConfig; mkDiffAlias = name: (flip optionalString) '' cat < $out/bin/${name} From fabe787feb2df23a51a5056af4d1dae91d9c02c6 Mon Sep 17 00:00:00 2001 From: LeMarsu Date: Mon, 6 Oct 2025 17:47:49 +0200 Subject: [PATCH 02/12] feat: can use flakeModules perSystem to build package with new ongoing module API --- flake.lock | 16 ++++ flake.nix | 8 +- flakeModule.nix | 51 ++++++++++ lib/default.nix | 9 +- lib/lib.nix | 248 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 326 insertions(+), 6 deletions(-) create mode 100644 flakeModule.nix create mode 100644 lib/lib.nix diff --git a/flake.lock b/flake.lock index 1333f2a..75643cd 100644 --- a/flake.lock +++ b/flake.lock @@ -49,6 +49,21 @@ "type": "github" } }, + "nixpkgs-lib_2": { + "locked": { + "lastModified": 1754788789, + "narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "a73b9c743612e4244d865a2fdee11865283c04e6", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, "nixpkgs_2": { "locked": { "lastModified": 1660438583, @@ -68,6 +83,7 @@ "inputs": { "flake-parts": "flake-parts", "nixpkgs": "nixpkgs", + "nixpkgs-lib": "nixpkgs-lib_2", "yants": "yants" } }, diff --git a/flake.nix b/flake.nix index 4779fb8..afc3b4e 100644 --- a/flake.nix +++ b/flake.nix @@ -3,16 +3,18 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + nixpkgs-lib.url = "github:nix-community/nixpkgs.lib"; yants.url = "github:divnix/yants"; flake-parts.url = "github:hercules-ci/flake-parts"; }; - outputs = {flake-parts, ...} @ inputs: let - in (flake-parts.lib.mkFlake {inherit inputs;} { + outputs = {flake-parts, ...} @ inputs: (flake-parts.lib.mkFlake {inherit inputs;} { systems = ["x86_64-linux"]; - imports = [ + imports = with flake-parts.flakeModules; [ + flakeModules ./dev + ./flakeModule.nix ./lib ]; }); diff --git a/flakeModule.nix b/flakeModule.nix new file mode 100644 index 0000000..1ee749a --- /dev/null +++ b/flakeModule.nix @@ -0,0 +1,51 @@ +{config, ...}: { + config.flake.flakeModules.default = { + lib, + flake-parts-lib, + ... + }: let + inherit (lib) attrsToList listToAttrs mkOption types; + inherit (flake-parts-lib) mkPerSystemOption; + topConfig = config; + in { + options.perSystem = mkPerSystemOption ({ + pkgs, + config, + ... + }: let + cfg = config.sloth; + inherit (cfg) lib; + + packageModule = types.submodule { + options.modules = mkOption { + description = "modules used to create your neovim package"; + type = with types; listOf attrs; + default = []; + }; + }; + + buildPackage = { name, value }: { + inherit name; + value = (lib.evalSlothModules {inherit (value) modules;}).neovimPackage; + }; + packagesList = map buildPackage (attrsToList cfg.packages); + in { + options.sloth = { + lib = mkOption { + type = types.attrs; + description = "sloth’s lib"; + default = topConfig.flake.mkLib {inherit pkgs;}; + defaultText = "mkLib { inherit pkgs; }"; + }; + + packages = mkOption { + description = "neovim package to create with sloth"; + default = {}; + type = with types; attrsOf packageModule; + }; + }; + + config.packages = listToAttrs packagesList; + }); + }; +} diff --git a/lib/default.nix b/lib/default.nix index 15f3192..598d998 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -12,8 +12,11 @@ types = import ./types.nix {inherit (inputs) yants;}; in { - flake.lib = { - mkNeovimPkg = import ./mkNeovimPkg.nix {inherit version types;}; - mkPluginsFromInputs = import ./mkPluginsFromInputs.nix; + flake = { + lib = { + mkNeovimPkg = import ./mkNeovimPkg.nix {inherit version types;}; + mkPluginsFromInputs = import ./mkPluginsFromInputs.nix; + }; + mkLib = import ./lib.nix; }; } diff --git a/lib/lib.nix b/lib/lib.nix new file mode 100644 index 0000000..19a692a --- /dev/null +++ b/lib/lib.nix @@ -0,0 +1,248 @@ +{pkgs, ...}: let + inherit (pkgs) lib; + inherit (lib) concatMap evalModules literalExample mkEnableOption mkOption mkPackageOption optional types; + + initModule = types.submodule { + options = { + init = mkOption { + type = with types; nullOr (either path str); + default = null; + description = '' + Lua code to call before plugins loaded + ''; + }; + + postInit = mkOption { + type = with types; nullOr (either path str); + default = null; + description = '' + Lua code called after init but before import + ''; + }; + + config = mkOption { + type = with types; nullOr (either path str); + default = null; + description = '' + Lua code called after all plugins are loaded + ''; + }; + }; + }; + + pluginModule = types.submodule { + 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. + ''; + }; + + plugin = mkOption { + # TODO Type should allow `basicPluginType` + 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; listOf package; + default = []; + description = '' + Ensure those packages are available + ''; + }; + + lazy = mkEnableOption "loading lazily the plugin"; + + events = mkOption { + # TODO See eventType + type = with types; listOf str; + default = []; + description = '' + List of events on which the plugin should be loaded + ''; + }; + + 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 = mkOption { + # TODO See keymapType + type = with types; listOf str; + default = []; + description = '' + List of keystrokes on which the plugin should be loaded + ''; + }; + + # priority = mkOption { + # type = types.int; + # default = []; + # description = '' + # Priority of the module. Influence the order of loading plugins. + # Highest values get loaded before. + # ''; + # }; + }; + }; + + runtimeModule = types.submodule { + options = { + version = mkOption { + type = with types; nullOr str; + description = "Optional version of your runtime"; + default = null; + example = "2025.10.16"; + }; + + src = mkOption { + type = with types; either path attrs; + description = "Files to include in your runtime"; + example = ./my-runtime; + }; + + extraOptions = mkOption { + type = types.attrs; + description = "Extra options to pass to `vimUtils.buildVimPlugin`"; + default = {}; + example.nvimRequireCheck = ["my-module.my-submodule"]; + }; + }; + }; + + convertPkgToPlugin = pkg: { + plugin = pkg; + }; + + extraLuaPackagesType = + (with types; functionTo package) + // { + merge = loc: defs: let + fnList = concatMap (def: def.value) defs; + concatPackages = ps: fn: fn ps; + in + ps: concatMap (concatPackages ps) fnList; + }; + + defaultModule = { + config, + lib, + ... + }: { + options = { + package = mkPackageOption pkgs "neovim-unwrapped" {}; + + plugins = mkOption { + description = '' + List of plugins to enable in this installation + ''; + type = with types; listOf (coercedTo package convertPkgToPlugin pluginModule); + default = []; + }; + + # Will probably be not needed + # dependenciesExtraArgs = mkOption { + # default = {}; + # }; + + extraLuaPackages = mkOption { + description = '' + function to define extra lua packages that should be included in + neovim environment. + ''; + type = extraLuaPackagesType; + example = literalExample "p: [p.nvim-nio]"; + defaultText = literalExample "_: []"; + default = _: []; + }; + + runtime = mkOption { + type = types.nullOr runtimeModule; + default = null; + description = '' + Your runtime submodule. You can configure what files should be + indluded in your runtime + ''; + }; + + init = mkOption { + default = null; + description = '' + init.lua configuration + ''; + type = with types; nullOr (oneOf [path str initModule]); + example = ./init.lua; + }; + + viAlias = mkEnableOption "creation on `vi` alias"; + vimAlias = mkEnableOption "creation on `vim` alias"; + vimdiffAlias = mkEnableOption "creation on `vimdiff` alias"; + nvimdiffAlias = mkEnableOption "creation on `nvimdiff` alias"; + + neovimOptions = mkOption { + type = types.attrs; + description = "The resulting configuration passed to `pkgs.wrapNeovimUnstable`"; + default = pkgs.neovimUtils.makeNeovimConfig { + # inherit customRC; + # plugins = extractPlugins plugins; + # extraLuaPackages = ps: + # (extractLuaPackagesFn plugins ps) ++ (extraLuaPackages ps); + }; + }; + + neovimPackage = mkOption { + type = types.package; + description = "The neovim package generated from your configuration."; + # defaultText = lib.literalExpression "pkgs.hello"; + default = pkgs.wrapNeovimUnstable config.package config.neovimOptions; + }; + }; + }; +in { + evalSlothModules = { + modules ? [], + specialArgs ? {}, + }: let + moduleConfig = evalModules { + specialArgs = specialArgs // {inherit pkgs;}; + modules = modules ++ [defaultModule]; + }; + in + moduleConfig.config; +} From c12a87bfa11a8c0b24d59ffd0dcbe38096437bcc Mon Sep 17 00:00:00 2001 From: LeMarsu Date: Thu, 16 Oct 2025 02:19:52 +0200 Subject: [PATCH 03/12] feat: add new `mkNeovimPackage` method that take modules and extraArgs and return a neovim package --- flakeModule.nix | 4 ++-- lib/lib.nix | 35 ++++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/flakeModule.nix b/flakeModule.nix index 1ee749a..8f87321 100644 --- a/flakeModule.nix +++ b/flakeModule.nix @@ -14,7 +14,7 @@ ... }: let cfg = config.sloth; - inherit (cfg) lib; + sLib = (cfg).lib; packageModule = types.submodule { options.modules = mkOption { @@ -26,7 +26,7 @@ buildPackage = { name, value }: { inherit name; - value = (lib.evalSlothModules {inherit (value) modules;}).neovimPackage; + value = sLib.mkNeovimPkg {inherit (value) modules;}; }; packagesList = map buildPackage (attrsToList cfg.packages); in { diff --git a/lib/lib.nix b/lib/lib.nix index 19a692a..31b3634 100644 --- a/lib/lib.nix +++ b/lib/lib.nix @@ -1,6 +1,6 @@ {pkgs, ...}: let inherit (pkgs) lib; - inherit (lib) concatMap evalModules literalExample mkEnableOption mkOption mkPackageOption optional types; + inherit (lib) concatMap evalModules fix literalExample mkEnableOption mkOption mkPackageOption optional types; initModule = types.submodule { options = { @@ -234,15 +234,24 @@ }; }; }; -in { - evalSlothModules = { - modules ? [], - specialArgs ? {}, - }: let - moduleConfig = evalModules { - specialArgs = specialArgs // {inherit pkgs;}; - modules = modules ++ [defaultModule]; - }; - in - moduleConfig.config; -} +in + fix (sLib: { + inherit defaultModule; + + evalSlothModules = { + modules ? [], + specialArgs ? {}, + }: let + moduleConfig = evalModules { + specialArgs = specialArgs // {inherit pkgs;}; + modules = modules ++ [sLib.defaultModule]; + }; + in + moduleConfig.config; + + mkNeovimPkg = { + modules ? [], + specialArgs ? {}, + }: + (sLib.evalSlothModules {inherit modules specialArgs;}).neovimPackage; + }) From bf329e5f4289e2eb2ea6b85f0b0fcd0f7664caae Mon Sep 17 00:00:00 2001 From: LeMarsu Date: Sat, 18 Oct 2025 19:13:07 +0200 Subject: [PATCH 04/12] feat: new module interface has 100% feature parity --- flakeModule.nix | 36 +++-- lib/default.nix | 4 +- lib/init.nix | 51 +++++++ lib/lib.nix | 249 +++++++++------------------------ lib/mkPluginsFromInputs.nix | 4 +- lib/oldMkPluginsFromInputs.nix | 20 +++ lib/plugin/default.nix | 136 ++++++++++++++++++ lib/plugin/event.nix | 60 ++++++++ lib/plugin/keymap.nix | 42 ++++++ lib/runtime.nix | 53 +++++++ lib/sloth.nix | 80 +++++++++++ 11 files changed, 538 insertions(+), 197 deletions(-) create mode 100644 lib/init.nix create mode 100644 lib/oldMkPluginsFromInputs.nix create mode 100644 lib/plugin/default.nix create mode 100644 lib/plugin/event.nix create mode 100644 lib/plugin/keymap.nix create mode 100644 lib/runtime.nix create mode 100644 lib/sloth.nix diff --git a/flakeModule.nix b/flakeModule.nix index 8f87321..2f6fd01 100644 --- a/flakeModule.nix +++ b/flakeModule.nix @@ -14,19 +14,35 @@ ... }: let cfg = config.sloth; - sLib = (cfg).lib; + sLib = cfg.lib; - packageModule = types.submodule { - options.modules = mkOption { - description = "modules used to create your neovim package"; - type = with types; listOf attrs; - default = []; + packageModule = types.submodule ({config, ...}: { + options = { + module = mkOption { + description = "module used to create your neovim package"; + type = types.deferredModule; + }; + + modules = mkOption { + description = "modules used to create your neovim package"; + type = with types; listOf attrs; + default = [config.module]; + }; + + specialArgs = mkOption { + description = "specialArgs to follow to your modules"; + type = types.attrs; + default = {}; + }; }; - }; + }); - buildPackage = { name, value }: { + buildPackage = { + name, + value, + }: { inherit name; - value = sLib.mkNeovimPkg {inherit (value) modules;}; + value = sLib.mkNeovimPkg {inherit (value) modules specialArgs;}; }; packagesList = map buildPackage (attrsToList cfg.packages); in { @@ -35,7 +51,7 @@ type = types.attrs; description = "sloth’s lib"; default = topConfig.flake.mkLib {inherit pkgs;}; - defaultText = "mkLib { inherit pkgs; }"; + defaultText = "mkLib {inherit pkgs;}"; }; packages = mkOption { diff --git a/lib/default.nix b/lib/default.nix index 598d998..8c0461f 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -15,8 +15,8 @@ in { flake = { lib = { mkNeovimPkg = import ./mkNeovimPkg.nix {inherit version types;}; - mkPluginsFromInputs = import ./mkPluginsFromInputs.nix; + mkPluginsFromInputs = import ./oldMkPluginsFromInputs.nix; }; - mkLib = import ./lib.nix; + mkLib = import ./lib.nix {inherit version;}; }; } diff --git a/lib/init.nix b/lib/init.nix new file mode 100644 index 0000000..ba4886f --- /dev/null +++ b/lib/init.nix @@ -0,0 +1,51 @@ +{pkgs, ...}: let + inherit (builtins) isAttrs isPath isString readFile; + inherit (pkgs.lib) fix mkOption types; +in + fix (self: { + module = types.submodule { + options = { + init = mkOption { + type = with types; nullOr (either path str); + default = null; + description = '' + Lua code to call before plugins loaded + ''; + }; + + postInit = mkOption { + type = with types; nullOr (either path str); + default = null; + description = '' + Lua code called after init but before import + ''; + }; + + config = mkOption { + type = with types; nullOr (either path str); + default = null; + description = '' + Lua code called after all plugins are loaded + ''; + }; + }; + }; + + option = mkOption { + default = null; + description = '' + init.lua configuration + ''; + type = with types; nullOr (oneOf [path str self.module]); + example = ./init.lua; + }; + + mkCustomLuaRc = init: + if isString init + then init + else if isPath init + then readFile init + else if isAttrs init + then "print('not implmented yet')" + else null; + }) diff --git a/lib/lib.nix b/lib/lib.nix index 31b3634..ce0a14b 100644 --- a/lib/lib.nix +++ b/lib/lib.nix @@ -1,181 +1,82 @@ -{pkgs, ...}: let - inherit (pkgs) lib; - inherit (lib) concatMap evalModules fix literalExample mkEnableOption mkOption mkPackageOption optional types; +{version, ...}: {pkgs, ...}: let + inherit (builtins) concatLists; + inherit (pkgs) bash lib; + inherit + (lib) + callPackageWith + concatMap + evalModules + fix + flip + literalExample + mkEnableOption + mkOption + mkPackageOption + optional + optionalString + types + ; - initModule = types.submodule { - options = { - init = mkOption { - type = with types; nullOr (either path str); - default = null; - description = '' - Lua code to call before plugins loaded - ''; - }; + callModule = callPackageWith {inherit pkgs callModule;}; - postInit = mkOption { - type = with types; nullOr (either path str); - default = null; - description = '' - Lua code called after init but before import - ''; - }; - - config = mkOption { - type = with types; nullOr (either path str); - default = null; - description = '' - Lua code called after all plugins are loaded - ''; - }; - }; - }; - - pluginModule = types.submodule { - 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. - ''; - }; - - plugin = mkOption { - # TODO Type should allow `basicPluginType` - 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; listOf package; - default = []; - description = '' - Ensure those packages are available - ''; - }; - - lazy = mkEnableOption "loading lazily the plugin"; - - events = mkOption { - # TODO See eventType - type = with types; listOf str; - default = []; - description = '' - List of events on which the plugin should be loaded - ''; - }; - - 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 = mkOption { - # TODO See keymapType - type = with types; listOf str; - default = []; - description = '' - List of keystrokes on which the plugin should be loaded - ''; - }; - - # priority = mkOption { - # type = types.int; - # default = []; - # description = '' - # Priority of the module. Influence the order of loading plugins. - # Highest values get loaded before. - # ''; - # }; - }; - }; - - runtimeModule = types.submodule { - options = { - version = mkOption { - type = with types; nullOr str; - description = "Optional version of your runtime"; - default = null; - example = "2025.10.16"; - }; - - src = mkOption { - type = with types; either path attrs; - description = "Files to include in your runtime"; - example = ./my-runtime; - }; - - extraOptions = mkOption { - type = types.attrs; - description = "Extra options to pass to `vimUtils.buildVimPlugin`"; - default = {}; - example.nvimRequireCheck = ["my-module.my-submodule"]; - }; - }; - }; - - convertPkgToPlugin = pkg: { - plugin = pkg; + modules = { + init = callModule ./init.nix {}; + plugin = callModule ./plugin {}; + runtime = callModule ./runtime.nix {}; + sloth = callModule ./sloth.nix {}; }; extraLuaPackagesType = - (with types; functionTo package) + (with types; functionTo (listOf package)) // { merge = loc: defs: let - fnList = concatMap (def: def.value) defs; + fnList = map (def: def.value) defs; concatPackages = ps: fn: fn ps; in ps: concatMap (concatPackages ps) fnList; }; + mkDiffAlias = name: + (flip optionalString) '' + cat < $out/bin/${name} + #!${bash}/bin/bash + exec $out/bin/nvim -d "\''${@}" + SH + chmod 555 $out/bin/${name} + ''; + defaultModule = { config, lib, ... - }: { + }: let + pkg = pkgs.wrapNeovimUnstable config.package config.neovimOptions; + + customLuaRC = modules.init.mkCustomLuaRc config.init; + + plugins = concatLists [ + (map modules.plugin.extract config.plugins) + (optional (! isNull config.runtime) (modules.runtime.mkPlugin config.runtime)) + [(modules.sloth.mkPlugin version config.plugins)] + ]; + + neovimOptions = pkgs.neovimUtils.makeNeovimConfig { + inherit (config) extraLuaPackages viAlias vimAlias; + inherit customLuaRC plugins; + wrapRc = customLuaRC != null; + # inherit customRC; + }; + + neovimPackage = pkg.overrideAttrs (final: super: { + postBuild = + super.postBuild + + (mkDiffAlias "vimdiff" config.vimdiffAlias) + + (mkDiffAlias "nvimdiff" config.nvimdiffAlias); + }); + in { options = { package = mkPackageOption pkgs "neovim-unwrapped" {}; - plugins = mkOption { - description = '' - List of plugins to enable in this installation - ''; - type = with types; listOf (coercedTo package convertPkgToPlugin pluginModule); - default = []; - }; - # Will probably be not needed # dependenciesExtraArgs = mkOption { # default = {}; @@ -192,23 +93,9 @@ default = _: []; }; - runtime = mkOption { - type = types.nullOr runtimeModule; - default = null; - description = '' - Your runtime submodule. You can configure what files should be - indluded in your runtime - ''; - }; - - init = mkOption { - default = null; - description = '' - init.lua configuration - ''; - type = with types; nullOr (oneOf [path str initModule]); - example = ./init.lua; - }; + init = modules.init.option; + runtime = modules.runtime.option; + plugins = modules.plugin.option; viAlias = mkEnableOption "creation on `vi` alias"; vimAlias = mkEnableOption "creation on `vim` alias"; @@ -218,25 +105,21 @@ neovimOptions = mkOption { type = types.attrs; description = "The resulting configuration passed to `pkgs.wrapNeovimUnstable`"; - default = pkgs.neovimUtils.makeNeovimConfig { - # inherit customRC; - # plugins = extractPlugins plugins; - # extraLuaPackages = ps: - # (extractLuaPackagesFn plugins ps) ++ (extraLuaPackages ps); - }; + default = neovimOptions; }; neovimPackage = mkOption { type = types.package; description = "The neovim package generated from your configuration."; # defaultText = lib.literalExpression "pkgs.hello"; - default = pkgs.wrapNeovimUnstable config.package config.neovimOptions; + default = neovimPackage; }; }; }; in fix (sLib: { inherit defaultModule; + mkPluginsFromInputs = import ./mkPluginsFromInputs.nix {inherit pkgs;}; evalSlothModules = { modules ? [], diff --git a/lib/mkPluginsFromInputs.nix b/lib/mkPluginsFromInputs.nix index df450aa..546bbfc 100644 --- a/lib/mkPluginsFromInputs.nix +++ b/lib/mkPluginsFromInputs.nix @@ -1,11 +1,11 @@ -{ - pkgs, +{pkgs, ...}: { inputs, predicate ? pkgs.lib.strings.hasPrefix "plugin-", nameMap ? builtins.substring 7 (-1), buildVimPlugin ? pkgs.vimUtils.buildVimPlugin, }: let inherit (builtins) attrNames filter foldl' mapAttrs; + names = filter predicate (attrNames inputs); mkPlugin = m: k: let name = nameMap k; diff --git a/lib/oldMkPluginsFromInputs.nix b/lib/oldMkPluginsFromInputs.nix new file mode 100644 index 0000000..df450aa --- /dev/null +++ b/lib/oldMkPluginsFromInputs.nix @@ -0,0 +1,20 @@ +{ + pkgs, + inputs, + predicate ? pkgs.lib.strings.hasPrefix "plugin-", + nameMap ? builtins.substring 7 (-1), + buildVimPlugin ? pkgs.vimUtils.buildVimPlugin, +}: let + inherit (builtins) attrNames filter foldl' mapAttrs; + names = filter predicate (attrNames inputs); + mkPlugin = m: k: let + name = nameMap k; + pluginDef = { + inherit name; + src = inputs.${k}; + }; + in + m // {${name} = pluginDef;}; + plugins = foldl' mkPlugin {} names; +in + mapAttrs (_: buildVimPlugin) plugins diff --git a/lib/plugin/default.nix b/lib/plugin/default.nix new file mode 100644 index 0000000..268ba2b --- /dev/null +++ b/lib/plugin/default.nix @@ -0,0 +1,136 @@ +{ + pkgs, + callModule, + ... +}: let + inherit (pkgs.lib) fix literalExample mkOption types; + + 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}. + ''; + }; +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 `basicPluginType` + 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"; + + lazy = mkOption { + type = types.bool; + default = with config; hasCommands || hasFileTypes || hasEvents || hasKeymaps; + example = true; + description = '' + Whether to enable loading lazily the plugin. + ''; + }; + + # 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; + }; + }) diff --git a/lib/plugin/event.nix b/lib/plugin/event.nix new file mode 100644 index 0000000..85ca2ac --- /dev/null +++ b/lib/plugin/event.nix @@ -0,0 +1,60 @@ +{pkgs, ...}: let + inherit (builtins) elemAt isList isString mapAttrs match ; + inherit (pkgs.lib) fix mkOption splitString types ; + + wrapArray = value: + if isList value + then value + else [value]; + + hasMatch = pattern: str: isList (match pattern str); + coerceToEvent = event: let + part = elemAt (splitString " " event); + value = + if ! isString event + then event + else if ! hasMatch ".* .*" event + then {name = event;} + else { + name = part 0; + pattern = part 1; + }; + in + mapAttrs (_: wrapArray) value; + coerceToListOfEvent = events: + if isList events + then map coerceToEvent events + else [(coerceToEvent events)]; + + typeOrListOf = t: with types; coercedTo t (e: [e]) (listOf t); +in + fix (self: { + module = types.submodule { + options = { + name = mkOption { + type = typeOrListOf types.str; + default = "n"; + example = "v"; + description = '' + The name of the event + ''; + }; + + pattern = mkOption { + type = typeOrListOf types.str; + example = ""; + description = '' + The pattern of the event + ''; + }; + }; + }; + + option = mkOption { + type = with types; coercedTo (either str (listOf str)) coerceToListOfEvent (listOf self.module); + default = []; + description = '' + List of events on which the plugin should be loaded + ''; + }; + }) diff --git a/lib/plugin/keymap.nix b/lib/plugin/keymap.nix new file mode 100644 index 0000000..326e248 --- /dev/null +++ b/lib/plugin/keymap.nix @@ -0,0 +1,42 @@ +{pkgs, ...}: let + inherit (pkgs.lib) fix mkOption types; + + coerceStrToKeymap = mapping: { + inherit mapping; + mode = ["n"]; + }; + + typeOrListOf = t: with types; coercedTo t (e: [e]) (listOf t); + + modeType = types.enum ["n" "v" "s" "i" "o" "x"]; +in + fix (self: { + module = types.submodule { + options = { + mode = mkOption { + type = typeOrListOf modeType; + default = "n"; + example = "v"; + description = '' + The mode of the keymap. + ''; + }; + + mapping = mkOption { + type = typeOrListOf types.str; + example = ""; + description = '' + The actual keymap + ''; + }; + }; + }; + + option = mkOption { + type = with types; listOf (coercedTo str coerceStrToKeymap self.module); + default = []; + description = '' + List of keystrokes on which the plugin should be loaded + ''; + }; + }) diff --git a/lib/runtime.nix b/lib/runtime.nix new file mode 100644 index 0000000..b1c34b9 --- /dev/null +++ b/lib/runtime.nix @@ -0,0 +1,53 @@ +{pkgs, ...}: let + inherit (pkgs) vimUtils; + inherit (pkgs.lib) fix mkOption types; +in fix (self: { + module = types.submodule { + options = { + src = mkOption { + type = with types; either path attrs; + description = "Files to include in your runtime"; + example = ./my-runtime; + }; + + version = mkOption { + type = with types; nullOr str; + description = "Optional version of your runtime"; + default = null; + example = "2025.10.16"; + }; + + extraOptions = mkOption { + type = with types; attrsOf anything; + description = "Extra options to pass to `vimUtils.buildVimPlugin`"; + default = {}; + example.nvimRequireCheck = ["my-module.my-submodule"]; + }; + }; + }; + + option = mkOption { + type = types.nullOr self.module; + default = null; + description = '' + Your runtime submodule. You can configure what files should be + indluded in your runtime + ''; + }; + + mkPlugin = opts: let + inherit (opts) src version extraOptions; + in + vimUtils.buildVimPlugin ( + extraOptions + // {inherit src;} + // ( + if isNull version + then {name = "runtime";} + else { + pname = "runtime"; + inherit version; + } + ) + ); +}) diff --git a/lib/sloth.nix b/lib/sloth.nix new file mode 100644 index 0000000..9be5f7b --- /dev/null +++ b/lib/sloth.nix @@ -0,0 +1,80 @@ +{pkgs, ...}: let + inherit (builtins) foldl' isPath; + inherit (pkgs) vimUtils; + inherit (pkgs.lib) fileContents fix optionalAttrs; + + fs = pkgs.lib.fileset; + + lua = import ./lua.nix {}; + + versionLua = version: with lua; nix2lua (return (lambda (return version))); + pluginsLuaDef = plugins: + with lua; nix2lua (return (foldl' pluginLuaDef {} plugins)); + + textOrContent = content: + if isPath content + then fileContents content + else content; + + pluginLuaDef = memo: plugin: let + mkTypeFn = type: let + content = textOrContent plugin.${type}; + in + optionalAttrs (! isNull plugin.${type}) { + ${type} = with lua; lambda (raw content); + }; + pluginName = plugin: + if plugin ? pname + then plugin.pname + else plugin.name; + name = pluginName plugin.plugin; + in + memo + // { + ${name} = + { + name = pluginName plugin.plugin; + dependencies = map pluginName plugin.dependencies; + } + // (mkTypeFn "init") + // (mkTypeFn "config") + // (optionalAttrs plugin.lazy { + lazy = true; + }) + // (optionalAttrs plugin.hasCommands { + inherit (plugin) cmd; + }) + // (optionalAttrs plugin.hasFileTypes { + inherit (plugin) ft; + }) + // (optionalAttrs plugin.hasEvents { + inherit (plugin) events; + }) + // (optionalAttrs plugin.hasKeymaps { + inherit (plugin) keymaps; + }); + }; +in + fix (self: { + mkPlugin = version: plugins: + vimUtils.buildVimPlugin { + inherit version; + pname = "sloth-flake"; + src = fs.toSource { + root = ../.; + fileset = ../lua/sloth-flake; + }; + nvimRequireCheck = "sloth-flake"; + buildPhase = '' + dir=lua/sloth-flake + + cat <<'LUA' > $dir/dependencies.lua + ${pluginsLuaDef plugins} + LUA + + cat <<'LUA' > $dir/version.lua + ${versionLua version} + LUA + ''; + }; + }) From 44bfef1f1c00f990af3bb90402cb0b084679ee3a Mon Sep 17 00:00:00 2001 From: LeMarsu Date: Sun, 8 Mar 2026 03:56:53 +0100 Subject: [PATCH 05/12] chore: reorganize lib folder hierarchy --- lib/evalModules.nix | 25 +++++ lib/lib.nix | 148 +++------------------------ lib/mkPluginsFromInputs.nix | 38 +++---- lib/modules/default.nix | 119 +++++++++++++++++++++ lib/{ => modules}/init.nix | 0 lib/{ => modules}/plugin/default.nix | 0 lib/{ => modules}/plugin/event.nix | 0 lib/{ => modules}/plugin/keymap.nix | 0 lib/{ => modules}/runtime.nix | 0 lib/{ => modules}/sloth.nix | 6 +- 10 files changed, 179 insertions(+), 157 deletions(-) create mode 100644 lib/evalModules.nix create mode 100644 lib/modules/default.nix rename lib/{ => modules}/init.nix (100%) rename lib/{ => modules}/plugin/default.nix (100%) rename lib/{ => modules}/plugin/event.nix (100%) rename lib/{ => modules}/plugin/keymap.nix (100%) rename lib/{ => modules}/runtime.nix (100%) rename lib/{ => modules}/sloth.nix (95%) diff --git a/lib/evalModules.nix b/lib/evalModules.nix new file mode 100644 index 0000000..ec3a3f4 --- /dev/null +++ b/lib/evalModules.nix @@ -0,0 +1,25 @@ +{ + pkgs, + sloth, + ... +}: let + inherit (pkgs.lib) evalModules; + sLib = sloth.lib; +in { + evalSlothModules = { + modules ? [], + specialArgs ? {}, + }: let + moduleConfig = evalModules { + specialArgs = specialArgs // {inherit pkgs;}; + modules = modules ++ [sLib.defaultModule]; + }; + in + moduleConfig.config; + + mkNeovimPkg = { + modules ? [], + specialArgs ? {}, + }: + (sLib.evalSlothModules {inherit modules specialArgs;}).neovimPackage; +} diff --git a/lib/lib.nix b/lib/lib.nix index ce0a14b..1111993 100644 --- a/lib/lib.nix +++ b/lib/lib.nix @@ -1,140 +1,16 @@ -{version, ...}: {pkgs, ...}: let - inherit (builtins) concatLists; - inherit (pkgs) bash lib; - inherit - (lib) - callPackageWith - concatMap - evalModules - fix - flip - literalExample - mkEnableOption - mkOption - mkPackageOption - optional - optionalString - types - ; +{version, ...}: {pkgs, ...}: +pkgs.lib.fix (lib: let + inherit (pkgs.lib) callPackageWith mergeAttrsList; - callModule = callPackageWith {inherit pkgs callModule;}; - - modules = { - init = callModule ./init.nix {}; - plugin = callModule ./plugin {}; - runtime = callModule ./runtime.nix {}; - sloth = callModule ./sloth.nix {}; + callModule = callPackageWith { + inherit pkgs callModule; + sloth = {inherit lib version;}; }; - extraLuaPackagesType = - (with types; functionTo (listOf package)) - // { - merge = loc: defs: let - fnList = map (def: def.value) defs; - concatPackages = ps: fn: fn ps; - in - ps: concatMap (concatPackages ps) fnList; - }; - - mkDiffAlias = name: - (flip optionalString) '' - cat < $out/bin/${name} - #!${bash}/bin/bash - exec $out/bin/nvim -d "\''${@}" - SH - chmod 555 $out/bin/${name} - ''; - - defaultModule = { - config, - lib, - ... - }: let - pkg = pkgs.wrapNeovimUnstable config.package config.neovimOptions; - - customLuaRC = modules.init.mkCustomLuaRc config.init; - - plugins = concatLists [ - (map modules.plugin.extract config.plugins) - (optional (! isNull config.runtime) (modules.runtime.mkPlugin config.runtime)) - [(modules.sloth.mkPlugin version config.plugins)] - ]; - - neovimOptions = pkgs.neovimUtils.makeNeovimConfig { - inherit (config) extraLuaPackages viAlias vimAlias; - inherit customLuaRC plugins; - wrapRc = customLuaRC != null; - # inherit customRC; - }; - - neovimPackage = pkg.overrideAttrs (final: super: { - postBuild = - super.postBuild - + (mkDiffAlias "vimdiff" config.vimdiffAlias) - + (mkDiffAlias "nvimdiff" config.nvimdiffAlias); - }); - in { - options = { - package = mkPackageOption pkgs "neovim-unwrapped" {}; - - # Will probably be not needed - # dependenciesExtraArgs = mkOption { - # default = {}; - # }; - - extraLuaPackages = mkOption { - description = '' - function to define extra lua packages that should be included in - neovim environment. - ''; - type = extraLuaPackagesType; - example = literalExample "p: [p.nvim-nio]"; - defaultText = literalExample "_: []"; - default = _: []; - }; - - init = modules.init.option; - runtime = modules.runtime.option; - plugins = modules.plugin.option; - - viAlias = mkEnableOption "creation on `vi` alias"; - vimAlias = mkEnableOption "creation on `vim` alias"; - vimdiffAlias = mkEnableOption "creation on `vimdiff` alias"; - nvimdiffAlias = mkEnableOption "creation on `nvimdiff` alias"; - - neovimOptions = mkOption { - type = types.attrs; - description = "The resulting configuration passed to `pkgs.wrapNeovimUnstable`"; - default = neovimOptions; - }; - - neovimPackage = mkOption { - type = types.package; - description = "The neovim package generated from your configuration."; - # defaultText = lib.literalExpression "pkgs.hello"; - default = neovimPackage; - }; - }; - }; + callModules = modules: mergeAttrsList (map (path: callModule path {}) modules); in - fix (sLib: { - inherit defaultModule; - mkPluginsFromInputs = import ./mkPluginsFromInputs.nix {inherit pkgs;}; - - evalSlothModules = { - modules ? [], - specialArgs ? {}, - }: let - moduleConfig = evalModules { - specialArgs = specialArgs // {inherit pkgs;}; - modules = modules ++ [sLib.defaultModule]; - }; - in - moduleConfig.config; - - mkNeovimPkg = { - modules ? [], - specialArgs ? {}, - }: - (sLib.evalSlothModules {inherit modules specialArgs;}).neovimPackage; - }) + callModules [ + ./evalModules.nix + ./mkPluginsFromInputs.nix + ./modules + ]) diff --git a/lib/mkPluginsFromInputs.nix b/lib/mkPluginsFromInputs.nix index 546bbfc..194cd37 100644 --- a/lib/mkPluginsFromInputs.nix +++ b/lib/mkPluginsFromInputs.nix @@ -1,20 +1,22 @@ -{pkgs, ...}: { - inputs, - predicate ? pkgs.lib.strings.hasPrefix "plugin-", - nameMap ? builtins.substring 7 (-1), - buildVimPlugin ? pkgs.vimUtils.buildVimPlugin, -}: let +{pkgs, ...}: let inherit (builtins) attrNames filter foldl' mapAttrs; - - names = filter predicate (attrNames inputs); - mkPlugin = m: k: let - name = nameMap k; - pluginDef = { - inherit name; - src = inputs.${k}; - }; +in { + mkPluginsFromInputs = { + inputs, + predicate ? pkgs.lib.strings.hasPrefix "plugin-", + nameMap ? builtins.substring 7 (-1), + buildVimPlugin ? pkgs.vimUtils.buildVimPlugin, + }: let + names = filter predicate (attrNames inputs); + mkPlugin = m: k: let + name = nameMap k; + pluginDef = { + inherit name; + src = inputs.${k}; + }; + in + m // {${name} = pluginDef;}; + plugins = foldl' mkPlugin {} names; in - m // {${name} = pluginDef;}; - plugins = foldl' mkPlugin {} names; -in - mapAttrs (_: buildVimPlugin) plugins + mapAttrs (_: buildVimPlugin) plugins; +} diff --git a/lib/modules/default.nix b/lib/modules/default.nix new file mode 100644 index 0000000..efc25fe --- /dev/null +++ b/lib/modules/default.nix @@ -0,0 +1,119 @@ +{ + pkgs, + callModule, + sloth, + ... +}: let + inherit (builtins) concatLists; + inherit (pkgs) bash lib; + inherit + (lib) + concatMap + flip + literalExample + mkEnableOption + mkOption + mkPackageOption + optional + optionalString + types + ; + + modules = { + init = callModule ./init.nix {}; + plugin = callModule ./plugin {}; + runtime = callModule ./runtime.nix {}; + sloth = callModule ./sloth.nix {}; + }; + + extraLuaPackagesType = + (with types; functionTo (listOf package)) + // { + merge = loc: defs: let + fnList = map (def: def.value) defs; + concatPackages = ps: fn: fn ps; + in + ps: concatMap (concatPackages ps) fnList; + }; + + mkDiffAlias = name: + (flip optionalString) '' + cat < $out/bin/${name} + #!${bash}/bin/bash + exec $out/bin/nvim -d "\''${@}" + SH + chmod 555 $out/bin/${name} + ''; +in { + defaultModule = { + config, + lib, + ... + }: let + pkg = pkgs.wrapNeovimUnstable config.package config.neovimOptions; + + customLuaRC = modules.init.mkCustomLuaRc config.init; + + plugins = concatLists [ + (map modules.plugin.extract config.plugins) + (optional (! isNull config.runtime) (modules.runtime.mkPlugin config.runtime)) + [(modules.sloth.mkPlugin sloth.version config.plugins)] + ]; + + neovimOptions = pkgs.neovimUtils.makeNeovimConfig { + inherit (config) extraLuaPackages viAlias vimAlias; + inherit customLuaRC plugins; + wrapRc = customLuaRC != null; + # inherit customRC; + }; + + neovimPackage = pkg.overrideAttrs (final: super: { + postBuild = + super.postBuild + + (mkDiffAlias "vimdiff" config.vimdiffAlias) + + (mkDiffAlias "nvimdiff" config.nvimdiffAlias); + }); + in { + options = { + package = mkPackageOption pkgs "neovim-unwrapped" {}; + + # Will probably be not needed + # dependenciesExtraArgs = mkOption { + # default = {}; + # }; + + extraLuaPackages = mkOption { + description = '' + function to define extra lua packages that should be included in + neovim environment. + ''; + type = extraLuaPackagesType; + example = literalExample "p: [p.nvim-nio]"; + defaultText = literalExample "_: []"; + default = _: []; + }; + + init = modules.init.option; + runtime = modules.runtime.option; + plugins = modules.plugin.option; + + viAlias = mkEnableOption "creation on `vi` alias"; + vimAlias = mkEnableOption "creation on `vim` alias"; + vimdiffAlias = mkEnableOption "creation on `vimdiff` alias"; + nvimdiffAlias = mkEnableOption "creation on `nvimdiff` alias"; + + neovimOptions = mkOption { + type = types.attrs; + description = "The resulting configuration passed to `pkgs.wrapNeovimUnstable`"; + default = neovimOptions; + }; + + neovimPackage = mkOption { + type = types.package; + description = "The neovim package generated from your configuration."; + # defaultText = lib.literalExpression "pkgs.hello"; + default = neovimPackage; + }; + }; + }; +} diff --git a/lib/init.nix b/lib/modules/init.nix similarity index 100% rename from lib/init.nix rename to lib/modules/init.nix diff --git a/lib/plugin/default.nix b/lib/modules/plugin/default.nix similarity index 100% rename from lib/plugin/default.nix rename to lib/modules/plugin/default.nix diff --git a/lib/plugin/event.nix b/lib/modules/plugin/event.nix similarity index 100% rename from lib/plugin/event.nix rename to lib/modules/plugin/event.nix diff --git a/lib/plugin/keymap.nix b/lib/modules/plugin/keymap.nix similarity index 100% rename from lib/plugin/keymap.nix rename to lib/modules/plugin/keymap.nix diff --git a/lib/runtime.nix b/lib/modules/runtime.nix similarity index 100% rename from lib/runtime.nix rename to lib/modules/runtime.nix diff --git a/lib/sloth.nix b/lib/modules/sloth.nix similarity index 95% rename from lib/sloth.nix rename to lib/modules/sloth.nix index 9be5f7b..a91d581 100644 --- a/lib/sloth.nix +++ b/lib/modules/sloth.nix @@ -5,7 +5,7 @@ fs = pkgs.lib.fileset; - lua = import ./lua.nix {}; + lua = import ../lua.nix {}; versionLua = version: with lua; nix2lua (return (lambda (return version))); pluginsLuaDef = plugins: @@ -61,8 +61,8 @@ in inherit version; pname = "sloth-flake"; src = fs.toSource { - root = ../.; - fileset = ../lua/sloth-flake; + root = ../..; + fileset = ../../lua/sloth-flake; }; nvimRequireCheck = "sloth-flake"; buildPhase = '' From 1d6bc8871949c56b967efc6c33484f60ee31d75e Mon Sep 17 00:00:00 2001 From: LeMarsu Date: Sun, 8 Mar 2026 05:36:42 +0100 Subject: [PATCH 06/12] refactor: better use of readOnly options --- lib/modules/default.nix | 27 ++++++++-- lib/modules/plugin/default.nix | 55 ++++++++++++++++++- lib/modules/runtime.nix | 98 ++++++++++++++++++---------------- lib/modules/sloth.nix | 71 ++++++------------------ 4 files changed, 147 insertions(+), 104 deletions(-) diff --git a/lib/modules/default.nix b/lib/modules/default.nix index efc25fe..29221e9 100644 --- a/lib/modules/default.nix +++ b/lib/modules/default.nix @@ -1,7 +1,6 @@ { pkgs, callModule, - sloth, ... }: let inherit (builtins) concatLists; @@ -56,8 +55,8 @@ in { plugins = concatLists [ (map modules.plugin.extract config.plugins) - (optional (! isNull config.runtime) (modules.runtime.mkPlugin config.runtime)) - [(modules.sloth.mkPlugin sloth.version config.plugins)] + (optional (! isNull config.runtime) config.runtime.package) + [config.slothPlugin] ]; neovimOptions = pkgs.neovimUtils.makeNeovimConfig { @@ -102,8 +101,29 @@ in { vimdiffAlias = mkEnableOption "creation on `vimdiff` alias"; nvimdiffAlias = mkEnableOption "creation on `nvimdiff` alias"; + pluginLuaDefinitions = mkOption { + description = '' + All lua definitions of plugins. Used by sloth vim plugin + ''; + type = with types; attrsOf anything; + readOnly = true; + internal = true; + default = modules.sloth.mkPluginLuaDefinitions config.plugins; + }; + + slothPlugin = mkOption { + description = '' + The resulted sloth plugin + ''; + type = types.package; + readOnly = true; + internal = true; + default = modules.sloth.mkSlothPlugin config.pluginLuaDefinitions; + }; + neovimOptions = mkOption { type = types.attrs; + readOnly = true; description = "The resulting configuration passed to `pkgs.wrapNeovimUnstable`"; default = neovimOptions; }; @@ -111,6 +131,7 @@ in { neovimPackage = mkOption { type = types.package; description = "The neovim package generated from your configuration."; + readOnly = true; # defaultText = lib.literalExpression "pkgs.hello"; default = neovimPackage; }; diff --git a/lib/modules/plugin/default.nix b/lib/modules/plugin/default.nix index 268ba2b..152b5b9 100644 --- a/lib/modules/plugin/default.nix +++ b/lib/modules/plugin/default.nix @@ -3,7 +3,9 @@ callModule, ... }: let - inherit (pkgs.lib) fix literalExample mkOption types; + inherit (builtins) isPath; + inherit (pkgs.lib) fileContents fix literalExample mergeAttrsList mkOption optionalAttrs types; + lua = import ../../lua.nix {}; modules = { keymap = callModule ./keymap.nix {}; @@ -23,6 +25,37 @@ Wether this plugin has ${description}. ''; }; + + textOrContent = content: + if isPath content + then fileContents content + else content; + + getPluginName = plugin: plugin.pname or plugin.name; + 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 + 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;}) + ])); in fix (self: { module = types.submodule ({config, ...}: { @@ -111,6 +144,26 @@ in ''; }; + 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. + ''; + }; + # priority = mkOption { # type = types.int; # default = []; diff --git a/lib/modules/runtime.nix b/lib/modules/runtime.nix index b1c34b9..bf4030b 100644 --- a/lib/modules/runtime.nix +++ b/lib/modules/runtime.nix @@ -1,53 +1,61 @@ {pkgs, ...}: let inherit (pkgs) vimUtils; inherit (pkgs.lib) fix mkOption types; -in fix (self: { - module = types.submodule { - options = { - src = mkOption { - type = with types; either path attrs; - description = "Files to include in your runtime"; - example = ./my-runtime; - }; +in + fix (self: { + module = types.submodule ({config, ...}: { + options = { + src = mkOption { + type = with types; either path attrs; + description = "Files to include in your runtime"; + example = ./my-runtime; + }; - version = mkOption { - type = with types; nullOr str; - description = "Optional version of your runtime"; - default = null; - example = "2025.10.16"; - }; + version = mkOption { + type = with types; nullOr str; + description = "Optional version of your runtime"; + default = null; + example = "2025.10.16"; + }; - extraOptions = mkOption { - type = with types; attrsOf anything; - description = "Extra options to pass to `vimUtils.buildVimPlugin`"; - default = {}; - example.nvimRequireCheck = ["my-module.my-submodule"]; + extraOptions = mkOption { + type = with types; attrsOf anything; + description = "Extra options to pass to `vimUtils.buildVimPlugin`"; + default = {}; + example.nvimRequireCheck = ["my-module.my-submodule"]; + }; + + package = mkOption { + type = types.package; + description = "The resulted runtime package"; + default = self.mkPlugin config; + example.nvimRequireCheck = ["my-module.my-submodule"]; + }; }; + }); + + option = mkOption { + type = types.nullOr self.module; + default = null; + description = '' + Your runtime submodule. You can configure what files should be + indluded in your runtime + ''; }; - }; - option = mkOption { - type = types.nullOr self.module; - default = null; - description = '' - Your runtime submodule. You can configure what files should be - indluded in your runtime - ''; - }; - - mkPlugin = opts: let - inherit (opts) src version extraOptions; - in - vimUtils.buildVimPlugin ( - extraOptions - // {inherit src;} - // ( - if isNull version - then {name = "runtime";} - else { - pname = "runtime"; - inherit version; - } - ) - ); -}) + mkPlugin = opts: let + inherit (opts) src version extraOptions; + in + vimUtils.buildVimPlugin ( + extraOptions + // {inherit src;} + // ( + if isNull version + then {name = "runtime";} + else { + pname = "runtime"; + inherit version; + } + ) + ); + }) diff --git a/lib/modules/sloth.nix b/lib/modules/sloth.nix index a91d581..138f7bf 100644 --- a/lib/modules/sloth.nix +++ b/lib/modules/sloth.nix @@ -1,64 +1,20 @@ -{pkgs, ...}: let - inherit (builtins) foldl' isPath; +{ + pkgs, + sloth, + ... +}: let inherit (pkgs) vimUtils; - inherit (pkgs.lib) fileContents fix optionalAttrs; - + inherit (pkgs.lib) fix listToAttrs nameValuePair; fs = pkgs.lib.fileset; - lua = import ../lua.nix {}; versionLua = version: with lua; nix2lua (return (lambda (return version))); - pluginsLuaDef = plugins: - with lua; nix2lua (return (foldl' pluginLuaDef {} plugins)); - - textOrContent = content: - if isPath content - then fileContents content - else content; - - pluginLuaDef = memo: plugin: let - mkTypeFn = type: let - content = textOrContent plugin.${type}; - in - optionalAttrs (! isNull plugin.${type}) { - ${type} = with lua; lambda (raw content); - }; - pluginName = plugin: - if plugin ? pname - then plugin.pname - else plugin.name; - name = pluginName plugin.plugin; - in - memo - // { - ${name} = - { - name = pluginName plugin.plugin; - dependencies = map pluginName plugin.dependencies; - } - // (mkTypeFn "init") - // (mkTypeFn "config") - // (optionalAttrs plugin.lazy { - lazy = true; - }) - // (optionalAttrs plugin.hasCommands { - inherit (plugin) cmd; - }) - // (optionalAttrs plugin.hasFileTypes { - inherit (plugin) ft; - }) - // (optionalAttrs plugin.hasEvents { - inherit (plugin) events; - }) - // (optionalAttrs plugin.hasKeymaps { - inherit (plugin) keymaps; - }); - }; + luaDefsToLua = luaDefs: with lua; nix2lua (return luaDefs); in fix (self: { - mkPlugin = version: plugins: + mkSlothPlugin = luaDefs: vimUtils.buildVimPlugin { - inherit version; + inherit (sloth) version; pname = "sloth-flake"; src = fs.toSource { root = ../..; @@ -69,12 +25,17 @@ in dir=lua/sloth-flake cat <<'LUA' > $dir/dependencies.lua - ${pluginsLuaDef plugins} + ${luaDefsToLua luaDefs} LUA cat <<'LUA' > $dir/version.lua - ${versionLua version} + ${versionLua sloth.version} LUA ''; }; + + mkPluginLuaDefinitions = plugins: let + extractDef = plugin: nameValuePair plugin.pluginName plugin.luaDefinition; + in + listToAttrs (map extractDef plugins); }) From aff1dbc0794074204e1ffa29fc756450d9a3b9ca Mon Sep 17 00:00:00 2001 From: LeMarsu Date: Sun, 8 Mar 2026 05:36:42 +0100 Subject: [PATCH 07/12] feat: lua render now handle indentation --- .gitignore | 1 + flake.nix | 1 + flakeModule.nix | 2 +- lib/deps.nix | 6 +- lib/legacyLua.nix | 92 +++++++++++++++++ lib/lua.nix | 182 ++++++++++++++++++++------------- lib/modules/plugin/default.nix | 4 +- lib/modules/sloth.nix | 7 +- tests/default.nix | 32 ++++++ tests/luaRender.lua | 28 +++++ 10 files changed, 275 insertions(+), 80 deletions(-) create mode 100644 lib/legacyLua.nix create mode 100644 tests/default.nix create mode 100644 tests/luaRender.lua diff --git a/.gitignore b/.gitignore index f3bf9c3..8a2e0a6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .direnv .envrc +result diff --git a/flake.nix b/flake.nix index afc3b4e..183db16 100644 --- a/flake.nix +++ b/flake.nix @@ -16,6 +16,7 @@ ./dev ./flakeModule.nix ./lib + ./tests ]; }); } diff --git a/flakeModule.nix b/flakeModule.nix index 2f6fd01..8bac535 100644 --- a/flakeModule.nix +++ b/flakeModule.nix @@ -25,7 +25,7 @@ modules = mkOption { description = "modules used to create your neovim package"; - type = with types; listOf attrs; + type = with types; listOf deferredModule; default = [config.module]; }; diff --git a/lib/deps.nix b/lib/deps.nix index 8693ac6..5004ba1 100644 --- a/lib/deps.nix +++ b/lib/deps.nix @@ -10,7 +10,7 @@ inherit (lib.attrsets) attrNames optionalAttrs; inherit (lib.lists) concatMap; inherit (lib.strings) fileContents splitString; - lua = callPackage ./lua.nix {}; + lua = callPackage ./legacyLua.nix {}; callPackage = lib.callPackageWith (pkgs // dependenciesExtraArgs); hasMatch = pattern: str: isList (match pattern str); @@ -144,7 +144,7 @@ ''; }; - versionLua = version: with lua; nix2lua (return (lambda (return version))); + versionLua = version: with lua; nix2lua (return (lambda [] (return version))); textOrContent = content: if isPath content @@ -156,7 +156,7 @@ content = textOrContent plugin.${type}; in optionalAttrs (! isNull plugin.${type}) { - ${type} = with lua; lambda (raw content); + ${type} = with lua; lambda [] (raw content); }; pluginName = plugin: if plugin ? pname diff --git a/lib/legacyLua.nix b/lib/legacyLua.nix new file mode 100644 index 0000000..76bf8f3 --- /dev/null +++ b/lib/legacyLua.nix @@ -0,0 +1,92 @@ +{...}: let + inherit (builtins) match isNull typeOf concatStringsSep attrNames concatMap; + fix = f: let x = f x; in x; + + commaJoin = concatStringsSep ", "; + wrapNotNull' = val: value: + if isNull val + then [] + else [value]; + wrapNotNull = val: wrapNotNull' val val; + + toLua = { + ast = { + raw = {data, ...}: data; + return = {data, ...}: "return ${nix2lua data}"; + fn = { + data, + name, + args, + ... + }: "function ${name}(${commaJoin args})\n${nix2lua data}\nend"; + }; + + type = fix (type: { + null = _: "nil"; + string = data: ''"${data}"''; + path = type.string; + lambda = data: builtins.trace "Skipping function" null; + int = data: toString data; + + bool = data: + if data + then "true" + else "false"; + + ast = data: let + astType = data.__ast; + in + if toLua.ast ? ${astType} + then toLua.ast.${astType} data + else abort ''Unknown ast type ${astType}''; + + list = data: let + nix2luaList = val: wrapNotNull (nix2lua val); + listContent = commaJoin (concatMap nix2luaList data); + in "{ ${listContent} }"; + + set = data: let + mkKeyValue = key: let + value = data.${key}; + luaKey = + if isNull (match "[a-zA-Z_][a-zA-Z_0-9]+" key) + then ''["${key}"]'' + else key; + luaValue = nix2lua value; + in + wrapNotNull' luaValue '' + ${luaKey} = ${luaValue}, + ''; + attrsContent = concatMap mkKeyValue (attrNames data); + in '' + { + ${concatStringsSep "" attrsContent}} + ''; + }); + }; + + newAst = type: set: set // {__ast = type;}; + + nix2lua = data: let + type = typeOf data; + in + if data ? __ast + then toLua.type.ast data + else if toLua.type ? ${type} + then toLua.type.${type} data + else abort ''Type "${type}"''; +in + fix (lua: { + inherit nix2lua; + + raw = data: newAst "raw" {inherit data;}; + + function = name: args: data: + newAst "fn" { + inherit name data args; + }; + + lambda = lua.function ""; + + return = data: newAst "return" {inherit data;}; + }) diff --git a/lib/lua.nix b/lib/lua.nix index 5455d1e..942c5d8 100644 --- a/lib/lua.nix +++ b/lib/lua.nix @@ -1,92 +1,132 @@ -{...}: let - inherit (builtins) match isNull typeOf concatStringsSep attrNames concatMap; +{pkgs, ...}: let + inherit + (builtins) + attrNames + concatStringsSep + filter + isAttrs + isBool + isFloat + isInt + isList + isPath + isNull + isString + match + toJSON + typeOf + ; + inherit + (pkgs.lib) + assertMsg + concatStrings + fix + imap0 + isDerivation + mapAttrsToList + optionalString + splitString + toPretty + ; commaJoin = concatStringsSep ", "; - wrapNotNull' = val: value: - if isNull val - then [] - else [value]; - wrapNotNull = val: wrapNotNull' val val; - toLua = { + renderLua = { + multiline ? true, + indent ? "", + asBindings ? false, + } @ args: v: let + innerIndent = "${indent} "; + introSpace = + if multiline + then "\n${innerIndent}" + else " "; + outroSpace = + if multiline + then "\n${indent}" + else " "; + innerArgs = + args + // { + indent = + if asBindings + then indent + else innerIndent; + asBindings = false; + }; + ast = { - raw = {data, ...}: data; - return = {data, ...}: "return ${nix2lua data}"; - fn = { + render = args: data: let + astType = data.__ast; + in + if ast ? ${astType} + then ast.${astType} args data + else abort ''Unknown ast type ${astType}''; + raw = args: { + data, + __no_indent ? false, + ... + }: let + content = + if __no_indent + then data + else concatStringsSep "\n" (imap0 (idx: line: "${optionalString (idx != 0) args.indent}${line}") (splitString "\n" data)); + in + content; + return = args: {data, ...}: "return ${renderLua args data}"; + fn = args: { data, name, args, ... - }: "function ${name}(${commaJoin args})\n${nix2lua data}\nend"; + }: "function ${name}(${commaJoin args})${introSpace}${renderLua innerArgs data}${outroSpace}end"; }; - type = rec { - null = _: "nil"; - string = data: ''"${data}"''; - path = string; - lambda = data: builtins.trace "Skipping function" null; - int = data: toString data; + generatedBindings = assert assertMsg (badBindingNames == []) "Bad Lua var names: ${toPretty {} badBindingNames}"; + concatStrings (mapAttrsToList (key: value: "${indent}${key} = ${renderLua innerArgs value}\n") v); - bool = data: - if data - then "true" - else "false"; + concatItems = concatStringsSep ",${introSpace}"; + varNameRe = "[[:alpha:]_][[:alnum:]_]*"; + matchBindingName = match "${varNameRe}(\\.${varNameRe})*"; + badBindingNames = filter (name: matchBindingName name == null) (attrNames v); - ast = data: let - astType = data.__ast; - in - if toLua.ast ? ${astType} - then toLua.ast.${astType} data - else abort ''Unknown ast type ${astType}''; + luaKey = key: + if match varNameRe key == null + then "[${toJSON key}]" + else key; - list = data: let - nix2luaList = val: wrapNotNull (nix2lua val); - listContent = commaJoin (concatMap nix2luaList data); - in "{ ${listContent} }"; + withSpaces = val: optionalString (val != "") "${introSpace}${val}${outroSpace}"; - set = data: let - mkKeyValue = key: let - value = data.${key}; - luaKey = - if isNull (match "[a-zA-Z_][a-zA-Z_0-9]+" key) - then ''["${key}"]'' - else key; - luaValue = nix2lua value; - in - wrapNotNull' luaValue '' - ${luaKey} = ${luaValue}, - ''; - attrsContent = concatMap mkKeyValue (attrNames data); - in '' - { - ${concatStringsSep "" attrsContent}} - ''; - }; - }; + mkKV = key: value: "${luaKey key} = ${renderLua innerArgs value}"; + in + if asBindings + then generatedBindings + else if isNull v + then "nil" + else if isInt v || isFloat v || isString v || isBool v + then toJSON v + else if isPath v || isDerivation v + then toJSON "${v}" + else if isList v + then "{${withSpaces (concatItems (map (renderLua innerArgs) v))}}" + else if v ? __ast + then ast.render args v + else if isAttrs v + then "{${withSpaces (concatItems (mapAttrsToList mkKV v))}}" + else abort "generators.renderLua: type ${typeOf v} is unsupported"; newAst = type: set: set // {__ast = type;}; +in + fix (lua: { + inherit renderLua; - nix2lua = data: let - type = typeOf data; - in - if data ? __ast - then toLua.type.ast data - else if toLua.type ? ${type} - then toLua.type.${type} data - else abort ''Type "${type}"''; -in rec { - inherit nix2lua; + writeLua = name: value: pkgs.writeText name (lua.renderLua {} value); - raw = data: newAst "raw" {inherit data;}; + raw = data: newAst "raw" {inherit data;}; - functionWithArgs = name: args: data: - newAst "fn" { - inherit name data args; - }; + function = name: args: data: newAst "fn" {inherit name data args;}; - function = name: data: functionWithArgs name [] data; + lambda = lua.function ""; - lambda = function ""; - - return = data: newAst "return" {inherit data;}; -} + return = data: newAst "return" {inherit data;}; + }) diff --git a/lib/modules/plugin/default.nix b/lib/modules/plugin/default.nix index 152b5b9..36d1805 100644 --- a/lib/modules/plugin/default.nix +++ b/lib/modules/plugin/default.nix @@ -5,7 +5,7 @@ }: let inherit (builtins) isPath; inherit (pkgs.lib) fileContents fix literalExample mergeAttrsList mkOption optionalAttrs types; - lua = import ../../lua.nix {}; + lua = callModule ../../lua.nix {}; modules = { keymap = callModule ./keymap.nix {}; @@ -37,7 +37,7 @@ content = textOrContent plugin.${type}; in optionalAttrs (! isNull plugin.${type}) { - ${type} = with lua; lambda (raw content); + ${type} = with lua; lambda [] (raw content); }; name = getPluginName plugin.plugin; in diff --git a/lib/modules/sloth.nix b/lib/modules/sloth.nix index 138f7bf..1340f84 100644 --- a/lib/modules/sloth.nix +++ b/lib/modules/sloth.nix @@ -1,15 +1,16 @@ { pkgs, sloth, + callModule, ... }: let inherit (pkgs) vimUtils; inherit (pkgs.lib) fix listToAttrs nameValuePair; fs = pkgs.lib.fileset; - lua = import ../lua.nix {}; + lua = callModule ../lua.nix {}; - versionLua = version: with lua; nix2lua (return (lambda (return version))); - luaDefsToLua = luaDefs: with lua; nix2lua (return luaDefs); + versionLua = version: with lua; renderLua {} (return (lambda [] (return version))); + luaDefsToLua = luaDefs: with lua; renderLua {} (return luaDefs); in fix (self: { mkSlothPlugin = luaDefs: diff --git a/tests/default.nix b/tests/default.nix new file mode 100644 index 0000000..276448a --- /dev/null +++ b/tests/default.nix @@ -0,0 +1,32 @@ +{ + perSystem = {pkgs, ...}: let + lua = import ../lib/lua.nix {inherit pkgs;}; + + diffFiles = actual: expected: + pkgs.runCommandWith { + name = "diffFiles"; + derivationArgs.nativeBuildInputs = [pkgs.diffutils]; + } + '' + diff -u ${expected} ${actual} + echo "Comparaison successful." + touch $out + ''; + in { + checks.luaRender = + diffFiles ./luaRender.lua + <| lua.writeLua "debug.lua" { + a.b.c = 42; + list = [42 4.2 true false null]; + fn = lua.lambda [] <| lua.raw "print('hello world')"; + math.succ = lua.function "" ["n"] <| lua.return <| lua.raw "n + 1"; + non-var-name = 42; + multilineFunc = + lua.function "" [] + <| lua.raw '' + print("hello world") + print("goodbye world") + ''; + }; + }; +} diff --git a/tests/luaRender.lua b/tests/luaRender.lua new file mode 100644 index 0000000..d21ae3a --- /dev/null +++ b/tests/luaRender.lua @@ -0,0 +1,28 @@ +{ + a = { + b = { + c = 42 + } + }, + fn = function () + print('hello world') + end, + list = { + 42, + 4.2, + true, + false, + nil + }, + math = { + succ = function (n) + return n + 1 + end + }, + multilineFunc = function () + print("hello world") + print("goodbye world") + + end, + ["non-var-name"] = 42 +} \ No newline at end of file From 2816b256d4068555fb797613dc60933492686fa9 Mon Sep 17 00:00:00 2001 From: LeMarsu Date: Wed, 11 Mar 2026 21:02:09 +0100 Subject: [PATCH 08/12] fix: init can be build from config --- lib/modules/init.nix | 56 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/lib/modules/init.nix b/lib/modules/init.nix index ba4886f..848b787 100644 --- a/lib/modules/init.nix +++ b/lib/modules/init.nix @@ -1,6 +1,56 @@ -{pkgs, ...}: let +{ + pkgs, + callModule, + ... +}: let inherit (builtins) isAttrs isPath isString readFile; - inherit (pkgs.lib) fix mkOption types; + inherit + (pkgs.lib) + fileContents + fix + mkOption + optionalAttrs + optionalString + types + ; + + lua = callModule ../lua.nix {}; + + textOrContent = content: + if isPath content + then fileContents content + else content; + + buildInit = { + init ? null, + postInit ? null, + config ? null, + }: let + initStr = optionalString (! isNull init) '' + (function() + ${textOrContent init} + end)(); + + ''; + + postInitContent = optionalAttrs (! isNull postInit) { + post_init = lua.lambda [] (textOrContent (lua.raw postInit)); + }; + + slothCall = "require('sloth-flake').setup ${lua.renderLua {} postInitContent}"; + + configStr = optionalString (! isNull config) '' + + (function() + ${textOrContent config} + end)() + ''; + in '' + -- Generated by sloth-flake + ${initStr} + ${slothCall} + ${configStr} + ''; in fix (self: { module = types.submodule { @@ -46,6 +96,6 @@ in else if isPath init then readFile init else if isAttrs init - then "print('not implmented yet')" + then buildInit init else null; }) From c00555d6d8dfaee812754e1d0dc994e62ee5aa83 Mon Sep 17 00:00:00 2001 From: LeMarsu Date: Wed, 11 Mar 2026 21:48:36 +0100 Subject: [PATCH 09/12] refactor: init module has simler configuration --- lib/modules/default.nix | 20 +++++++++----------- lib/modules/init.nix | 34 ++++++++++++++++++++-------------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/lib/modules/default.nix b/lib/modules/default.nix index 29221e9..b631b2c 100644 --- a/lib/modules/default.nix +++ b/lib/modules/default.nix @@ -51,19 +51,17 @@ in { }: let pkg = pkgs.wrapNeovimUnstable config.package config.neovimOptions; - customLuaRC = modules.init.mkCustomLuaRc config.init; - - plugins = concatLists [ - (map modules.plugin.extract config.plugins) - (optional (! isNull config.runtime) config.runtime.package) - [config.slothPlugin] - ]; - - neovimOptions = pkgs.neovimUtils.makeNeovimConfig { + neovimOptions = pkgs.neovimUtils.makeNeovimConfig rec { inherit (config) extraLuaPackages viAlias vimAlias; - inherit customLuaRC plugins; + + customLuaRC = config.init.finalContent; wrapRc = customLuaRC != null; - # inherit customRC; + + plugins = concatLists [ + (map modules.plugin.extract config.plugins) + (optional (! isNull config.runtime) config.runtime.package) + [config.slothPlugin] + ]; }; neovimPackage = pkg.overrideAttrs (final: super: { diff --git a/lib/modules/init.nix b/lib/modules/init.nix index 848b787..da255a2 100644 --- a/lib/modules/init.nix +++ b/lib/modules/init.nix @@ -4,18 +4,15 @@ ... }: let inherit (builtins) isAttrs isPath isString readFile; - inherit - (pkgs.lib) - fileContents - fix - mkOption - optionalAttrs - optionalString - types - ; + inherit (pkgs.lib) fileContents fix mkOption optionalAttrs optionalString types; lua = callModule ../lua.nix {}; + coerceToModule = value: + if isAttrs value + then value + else {finalContent = textOrContent value;}; + textOrContent = content: if isPath content then fileContents content @@ -25,6 +22,7 @@ init ? null, postInit ? null, config ? null, + ... }: let initStr = optionalString (! isNull init) '' (function() @@ -34,10 +32,10 @@ ''; postInitContent = optionalAttrs (! isNull postInit) { - post_init = lua.lambda [] (textOrContent (lua.raw postInit)); + post_init = lua.lambda [] (lua.raw (textOrContent postInit)); }; - slothCall = "require('sloth-flake').setup ${lua.renderLua {} postInitContent}"; + slothCall = "require('sloth-flake').setup ${lua.renderLua {} postInitContent};"; configStr = optionalString (! isNull config) '' @@ -53,7 +51,7 @@ ''; in fix (self: { - module = types.submodule { + module = types.submodule ({config, ...}: { options = { init = mkOption { type = with types; nullOr (either path str); @@ -78,15 +76,23 @@ in Lua code called after all plugins are loaded ''; }; + + finalContent = mkOption { + type = with types; nullOr str; + default = self.mkCustomLuaRc config; + description = '' + The resulted init package. + ''; + }; }; - }; + }); option = mkOption { default = null; description = '' init.lua configuration ''; - type = with types; nullOr (oneOf [path str self.module]); + type = with types; coercedTo (nullOr (oneOf [path str])) coerceToModule self.module; example = ./init.lua; }; From cf660fa367fdb31d571c6850c10a4a0505e87aa6 Mon Sep 17 00:00:00 2001 From: LeMarsu Date: Wed, 11 Mar 2026 21:29:29 +0100 Subject: [PATCH 10/12] refactor: sloth plugin derivation is less hackish --- lib/modules/sloth.nix | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/lib/modules/sloth.nix b/lib/modules/sloth.nix index 1340f84..e92718a 100644 --- a/lib/modules/sloth.nix +++ b/lib/modules/sloth.nix @@ -9,8 +9,8 @@ fs = pkgs.lib.fileset; lua = callModule ../lua.nix {}; - versionLua = version: with lua; renderLua {} (return (lambda [] (return version))); - luaDefsToLua = luaDefs: with lua; renderLua {} (return luaDefs); + defsFile = luaDefs: with lua; writeLua "sloth-plugins-definitions.lua" (return luaDefs); + versionFile = with lua; writeLua "sloth-version.lua" (return (lambda [] (return sloth.version))); in fix (self: { mkSlothPlugin = luaDefs: @@ -24,14 +24,8 @@ in nvimRequireCheck = "sloth-flake"; buildPhase = '' dir=lua/sloth-flake - - cat <<'LUA' > $dir/dependencies.lua - ${luaDefsToLua luaDefs} - LUA - - cat <<'LUA' > $dir/version.lua - ${versionLua sloth.version} - LUA + ln -s ${defsFile luaDefs} $dir/dependencies.lua + ln -s ${versionFile} $dir/version.lua ''; }; From 43d374b618509f4bf030719a4743c65b764a8a6b Mon Sep 17 00:00:00 2001 From: LeMarsu Date: Wed, 11 Mar 2026 22:26:47 +0100 Subject: [PATCH 11/12] chore: few clean before RC --- lib/evalModules.nix | 1 + lib/modules/default.nix | 5 ----- lib/modules/plugin/default.nix | 2 +- lib/modules/runtime.nix | 1 + 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/evalModules.nix b/lib/evalModules.nix index ec3a3f4..c4d1803 100644 --- a/lib/evalModules.nix +++ b/lib/evalModules.nix @@ -13,6 +13,7 @@ in { moduleConfig = evalModules { specialArgs = specialArgs // {inherit pkgs;}; modules = modules ++ [sLib.defaultModule]; + class = "sloth"; }; in moduleConfig.config; diff --git a/lib/modules/default.nix b/lib/modules/default.nix index b631b2c..6ab0267 100644 --- a/lib/modules/default.nix +++ b/lib/modules/default.nix @@ -74,11 +74,6 @@ in { options = { package = mkPackageOption pkgs "neovim-unwrapped" {}; - # Will probably be not needed - # dependenciesExtraArgs = mkOption { - # default = {}; - # }; - extraLuaPackages = mkOption { description = '' function to define extra lua packages that should be included in diff --git a/lib/modules/plugin/default.nix b/lib/modules/plugin/default.nix index 36d1805..0007891 100644 --- a/lib/modules/plugin/default.nix +++ b/lib/modules/plugin/default.nix @@ -85,7 +85,7 @@ in }; plugin = mkOption { - # TODO Type should allow `basicPluginType` + # TODO Type should allow old `basicPluginType` ({name:, src:})? type = with types; nullOr package; default = null; description = '' diff --git a/lib/modules/runtime.nix b/lib/modules/runtime.nix index bf4030b..efed9d8 100644 --- a/lib/modules/runtime.nix +++ b/lib/modules/runtime.nix @@ -28,6 +28,7 @@ in package = mkOption { type = types.package; description = "The resulted runtime package"; + readOnly = true; default = self.mkPlugin config; example.nvimRequireCheck = ["my-module.my-submodule"]; }; From 2761e11d622ba4e0e55e219b894557e8e810836e Mon Sep 17 00:00:00 2001 From: LeMarsu Date: Wed, 11 Mar 2026 22:37:33 +0100 Subject: [PATCH 12/12] chore: remove all API code --- flake.lock | 52 +-------- flake.nix | 4 +- lib/default.nix | 23 +--- lib/deps.nix | 200 --------------------------------- lib/legacyLua.nix | 92 --------------- lib/mkNeovimPkg.nix | 117 ------------------- lib/oldMkPluginsFromInputs.nix | 20 ---- lib/types.nix | 138 ----------------------- 8 files changed, 8 insertions(+), 638 deletions(-) delete mode 100644 lib/deps.nix delete mode 100644 lib/legacyLua.nix delete mode 100644 lib/mkNeovimPkg.nix delete mode 100644 lib/oldMkPluginsFromInputs.nix delete mode 100644 lib/types.nix diff --git a/flake.lock b/flake.lock index 75643cd..b627cd3 100644 --- a/flake.lock +++ b/flake.lock @@ -49,60 +49,10 @@ "type": "github" } }, - "nixpkgs-lib_2": { - "locked": { - "lastModified": 1754788789, - "narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=", - "owner": "nix-community", - "repo": "nixpkgs.lib", - "rev": "a73b9c743612e4244d865a2fdee11865283c04e6", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixpkgs.lib", - "type": "github" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1660438583, - "narHash": "sha256-rJUTYxFKlWUJI3njAwEc1pKAVooAViZGJvsgqfh/q/E=", - "owner": "nix-community", - "repo": "nixpkgs.lib", - "rev": "bbd8f7cd87d0b29294ef3072ffdbd61d60f05da4", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixpkgs.lib", - "type": "github" - } - }, "root": { "inputs": { "flake-parts": "flake-parts", - "nixpkgs": "nixpkgs", - "nixpkgs-lib": "nixpkgs-lib_2", - "yants": "yants" - } - }, - "yants": { - "inputs": { - "nixpkgs": "nixpkgs_2" - }, - "locked": { - "lastModified": 1686863218, - "narHash": "sha256-kooxYm3/3ornWtVBNHM3Zh020gACUyFX2G0VQXnB+mk=", - "owner": "divnix", - "repo": "yants", - "rev": "8f0da0dba57149676aa4817ec0c880fbde7a648d", - "type": "github" - }, - "original": { - "owner": "divnix", - "repo": "yants", - "type": "github" + "nixpkgs": "nixpkgs" } } }, diff --git a/flake.nix b/flake.nix index 183db16..0067efb 100644 --- a/flake.nix +++ b/flake.nix @@ -1,10 +1,8 @@ { - description = "My neovim configuration"; + description = "Sloth-flake - a nix power neovim plugin manager"; inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; - nixpkgs-lib.url = "github:nix-community/nixpkgs.lib"; - yants.url = "github:divnix/yants"; flake-parts.url = "github:hercules-ci/flake-parts"; }; diff --git a/lib/default.nix b/lib/default.nix index 8c0461f..9ebb611 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -1,22 +1,11 @@ -{ - self, - inputs, - ... -}: let +{self, ...}: let inherit (builtins) readFile replaceStrings; versionFile = replaceStrings ["\n"] [""] (readFile ../VERSION); - version = + dirty = if self.sourceInfo ? dirtyShortRev - then "${versionFile}-${self.sourceInfo.dirtyShortRev}" - else versionFile; - - types = import ./types.nix {inherit (inputs) yants;}; + then "-${self.sourceInfo.dirtyShortRev}" + else ""; + version = "${versionFile}${dirty}"; in { - flake = { - lib = { - mkNeovimPkg = import ./mkNeovimPkg.nix {inherit version types;}; - mkPluginsFromInputs = import ./oldMkPluginsFromInputs.nix; - }; - mkLib = import ./lib.nix {inherit version;}; - }; + flake.mkLib = import ./lib.nix {inherit version;}; } diff --git a/lib/deps.nix b/lib/deps.nix deleted file mode 100644 index 5004ba1..0000000 --- a/lib/deps.nix +++ /dev/null @@ -1,200 +0,0 @@ -{ - pkgs, - lib, - vimUtils, - dependenciesExtraArgs, - types, - ... -}: let - inherit (builtins) foldl' isPath isList isString mapAttrs match elemAt; - inherit (lib.attrsets) attrNames optionalAttrs; - inherit (lib.lists) concatMap; - inherit (lib.strings) fileContents splitString; - lua = callPackage ./legacyLua.nix {}; - callPackage = lib.callPackageWith (pkgs // dependenciesExtraArgs); - - hasMatch = pattern: str: isList (match pattern str); - wrapArray = value: - if isList value - then value - else [value]; - - defaultPlugin = { - enabled = true; - init = null; - config = null; - dependencies = []; - lazy = false; - cmd = []; - ft = []; - events = []; - keymaps = []; - }; - - remotePluginToNeovimPlugin = p: - vimUtils.buildVimPlugin rec { - inherit (p) src 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 - value = - if ! isString event - then event - else if ! hasMatch ".* .*" event - then {name = event;} - else let - part = elemAt (splitString " " event); - in { - name = part 0; - pattern = part 1; - }; - in - mapAttrs (_: wrapArray) value; - normalizeEvents = events: - if isList events - then map normalizeEvent events - else [(normalizeEvent events)]; - - withPluginDefaults = dep: defaultPlugin // dep; - normalizePlugin = d: let - dep = types.dependency d; - plugin = - if ! dep ? plugin - then {plugin = dep;} - else let - inherit (dep) plugin; - in - if attrNames plugin == ["name" "src"] - then dep // {plugin = remotePluginToNeovimPlugin plugin;} - else dep; - p = withPluginDefaults plugin; - in - p - // rec { - hasCommands = p.cmd != []; - hasFileTypes = p.ft != []; - keymaps = normalizeKeymaps p.keymaps; - hasKeymaps = p.keymaps != []; - events = normalizeEvents p.events; - hasEvents = p.events != []; - lazy = p.lazy || hasCommands || hasFileTypes || hasEvents || hasKeymaps; - optional = lazy || p.init != null; - }; - - normalizeOrImportPlugin = dep: - if isPath dep - then normalizePlugins (callPackage dep {}) - else [(normalizePlugin dep)]; - normalizePlugins = concatMap normalizeOrImportPlugin; - - mkRuntimePlugin = { - src, - version, - ... - }@opts: - vimUtils.buildVimPlugin ({ - inherit src; - } - // (optionalAttrs (opts ? nvimRequireCheck) { - inherit (opts) nvimRequireCheck; - }) - // (optionalAttrs (isNull version) { - name = "runtime"; - }) - // (optionalAttrs (! isNull version) { - inherit version; - pname = "runtime"; - })); - - mkSlothFlakePlugin = version: plugins: - vimUtils.buildVimPlugin { - inherit version; - pname = "sloth-flake"; - src = with lib.fileset; - toSource { - root = ../.; - fileset = ../lua/sloth-flake; - }; - nvimRequireCheck = "sloth-flake"; - buildPhase = '' - dir=lua/sloth-flake - - cat <<'LUA' > $dir/dependencies.lua - ${pluginsLuaDef plugins} - LUA - - cat <<'LUA' > $dir/version.lua - ${versionLua version} - LUA - ''; - }; - - versionLua = version: with lua; nix2lua (return (lambda [] (return version))); - - textOrContent = content: - if isPath content - then fileContents content - else content; - - pluginLuaDef = memo: plugin: let - mkTypeFn = type: let - content = textOrContent plugin.${type}; - in - optionalAttrs (! isNull plugin.${type}) { - ${type} = with lua; lambda [] (raw content); - }; - pluginName = plugin: - if plugin ? pname - then plugin.pname - else plugin.name; - name = pluginName plugin.plugin; - in - memo - // { - ${name} = - { - name = pluginName plugin.plugin; - dependencies = map pluginName plugin.dependencies; - } - // (mkTypeFn "init") - // (mkTypeFn "config") - // (optionalAttrs plugin.lazy { - lazy = true; - }) - // (optionalAttrs plugin.hasCommands { - inherit (plugin) cmd; - }) - // (optionalAttrs plugin.hasFileTypes { - inherit (plugin) ft; - }) - // (optionalAttrs plugin.hasEvents { - inherit (plugin) events; - }) - // (optionalAttrs plugin.hasKeymaps { - inherit (plugin) keymaps; - }); - }; - pluginsLuaDef = plugins: - with lua; nix2lua (return (foldl' pluginLuaDef {} plugins)); -in { - inherit normalizePlugin; - inherit normalizePlugins; - inherit mkSlothFlakePlugin; - inherit mkRuntimePlugin; - inherit textOrContent; -} diff --git a/lib/legacyLua.nix b/lib/legacyLua.nix deleted file mode 100644 index 76bf8f3..0000000 --- a/lib/legacyLua.nix +++ /dev/null @@ -1,92 +0,0 @@ -{...}: let - inherit (builtins) match isNull typeOf concatStringsSep attrNames concatMap; - fix = f: let x = f x; in x; - - commaJoin = concatStringsSep ", "; - wrapNotNull' = val: value: - if isNull val - then [] - else [value]; - wrapNotNull = val: wrapNotNull' val val; - - toLua = { - ast = { - raw = {data, ...}: data; - return = {data, ...}: "return ${nix2lua data}"; - fn = { - data, - name, - args, - ... - }: "function ${name}(${commaJoin args})\n${nix2lua data}\nend"; - }; - - type = fix (type: { - null = _: "nil"; - string = data: ''"${data}"''; - path = type.string; - lambda = data: builtins.trace "Skipping function" null; - int = data: toString data; - - bool = data: - if data - then "true" - else "false"; - - ast = data: let - astType = data.__ast; - in - if toLua.ast ? ${astType} - then toLua.ast.${astType} data - else abort ''Unknown ast type ${astType}''; - - list = data: let - nix2luaList = val: wrapNotNull (nix2lua val); - listContent = commaJoin (concatMap nix2luaList data); - in "{ ${listContent} }"; - - set = data: let - mkKeyValue = key: let - value = data.${key}; - luaKey = - if isNull (match "[a-zA-Z_][a-zA-Z_0-9]+" key) - then ''["${key}"]'' - else key; - luaValue = nix2lua value; - in - wrapNotNull' luaValue '' - ${luaKey} = ${luaValue}, - ''; - attrsContent = concatMap mkKeyValue (attrNames data); - in '' - { - ${concatStringsSep "" attrsContent}} - ''; - }); - }; - - newAst = type: set: set // {__ast = type;}; - - nix2lua = data: let - type = typeOf data; - in - if data ? __ast - then toLua.type.ast data - else if toLua.type ? ${type} - then toLua.type.${type} data - else abort ''Type "${type}"''; -in - fix (lua: { - inherit nix2lua; - - raw = data: newAst "raw" {inherit data;}; - - function = name: args: data: - newAst "fn" { - inherit name data args; - }; - - lambda = lua.function ""; - - return = data: newAst "return" {inherit data;}; - }) diff --git a/lib/mkNeovimPkg.nix b/lib/mkNeovimPkg.nix deleted file mode 100644 index 9852686..0000000 --- a/lib/mkNeovimPkg.nix +++ /dev/null @@ -1,117 +0,0 @@ -{ - version, - types, -}: { - pkgs, - package ? pkgs.neovim-unwrapped, - dependencies ? [], - dependenciesExtraArgs ? {}, - extraLuaPackages ? (_: []), - runtime ? null, - init ? null, - viAlias ? false, - vimAlias ? false, - vimdiffAlias ? false, - nvimdiffAlias ? false, - ... -} @ config: let - inherit (builtins) isString isPath map; - inherit (pkgs) callPackage bash lib; - inherit (lib.strings) optionalString; - inherit (lib.lists) concatMap optional; - inherit (lib.trivial) flip; - inherit (lib.attrsets) optionalAttrs; - - deps = callPackage ./deps.nix {inherit dependenciesExtraArgs types;}; - - normalizedPlugins = deps.normalizePlugins dependencies; - sloth-flake = deps.mkSlothFlakePlugin version normalizedPlugins; - runtimePlugin = deps.mkRuntimePlugin runtime; - plugins = - normalizedPlugins - ++ ( - deps.normalizePlugins - ([sloth-flake] ++ (optional (runtime != null) runtimePlugin)) - ); - - extractPlugin = p: {inherit (p) optional plugin;}; - extractPlugins = map extractPlugin; - - extractLuaPackageFn = plugin: - optional (plugin ? extraLuaPackages) plugin.extraLuaPackages; - extractLuaPackagesFn = plugins: let - fnList = concatMap extractLuaPackageFn plugins; - concatPackages = ps: fn: fn ps; - in - ps: concatMap (concatPackages ps) fnList; - - buildInit = { - init ? null, - postInit ? null, - config ? null, - }: let - initStr = optionalString (! isNull init) '' - (function() - ${deps.textOrContent init} - end)(); - - ''; - - slothCall = - if isNull postInit - then "require('sloth-flake').setup {}" - else '' - require('sloth-flake').setup { - post_init = function() - ${deps.textOrContent postInit} - end, - }; - ''; - - configStr = optionalString (! isNull config) '' - - (function() - ${deps.textOrContent config} - end)() - ''; - in '' - -- Generated by sloth-flake - ${initStr} - ${slothCall} - ${configStr} - ''; - - customRC = - if isString init || isPath init - then deps.textOrContent init - else buildInit (optionalAttrs (! isNull init) init); - - neovimConfig = pkgs.neovimUtils.makeNeovimConfig { - # inherit customRC; - customLuaRC = customRC; - plugins = extractPlugins plugins; - extraLuaPackages = ps: - (extractLuaPackagesFn plugins ps) ++ (extraLuaPackages ps); - inherit viAlias vimAlias; - # autoconfigure = false; - }; - # // {luaRcContent = customRC;}; - # params = - # removeAttrs neovimConfig ["neovimRcContent"] - # // {inherit viAlias vimAlias;}; - pkg = pkgs.wrapNeovimUnstable package neovimConfig; - mkDiffAlias = name: - (flip optionalString) '' - cat < $out/bin/${name} - #!${bash}/bin/bash - exec $out/bin/nvim -d "\''${@}" - SH - chmod 555 $out/bin/${name} - ''; -in - builtins.seq (types.mkNeovimPkgOptions config) (pkg.overrideAttrs (final: super: { - postBuild = - super.postBuild - + (mkDiffAlias "vimdiff" vimdiffAlias) - + (mkDiffAlias "nvimdiff" nvimdiffAlias); - })) diff --git a/lib/oldMkPluginsFromInputs.nix b/lib/oldMkPluginsFromInputs.nix deleted file mode 100644 index df450aa..0000000 --- a/lib/oldMkPluginsFromInputs.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ - pkgs, - inputs, - predicate ? pkgs.lib.strings.hasPrefix "plugin-", - nameMap ? builtins.substring 7 (-1), - buildVimPlugin ? pkgs.vimUtils.buildVimPlugin, -}: let - inherit (builtins) attrNames filter foldl' mapAttrs; - names = filter predicate (attrNames inputs); - mkPlugin = m: k: let - name = nameMap k; - pluginDef = { - inherit name; - src = inputs.${k}; - }; - in - m // {${name} = pluginDef;}; - plugins = foldl' mkPlugin {} names; -in - mapAttrs (_: buildVimPlugin) plugins diff --git a/lib/types.nix b/lib/types.nix deleted file mode 100644 index acb3bd6..0000000 --- a/lib/types.nix +++ /dev/null @@ -1,138 +0,0 @@ -{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 - runtimeType = with yants; - openStruct "runtime" { - # The version of the runtime - version = option string; - - # The content of the runtime directory - src = any; - }; - - neovimInitType = with yants; - struct "neovimInit" { - # Lua code to call before plugins loaded - init = option (either string path); - # Lua code called after init but before import - postInit = option (either string path); - # Lua code called after all plugins are loaded - config = option (either string path); - }; - - # As simple remote plugin definition - basicPluginType = with yants; - struct "basicPlugin" { - # The name of your plugin. - name = string; - # The sources of your plugin - # TODO What is the type of a source ? - src = any; - }; - - eventType = with yants; - struct "event" { - # The name of the event - 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 - pluginType = with yants; - struct "plugin" { - # Whether this plugin should be enabled. This option allows specific - # plugins to be disabled. - # enable = option bool; - - # The init configuration of your plugin. - # This should be called before loading your plugin. - init = option (either path string); - - # The configuration of your plugin. - # This should be called after loading your plugin. - config = option (either path string); - - # Ensure thoses plugins are loaded before the current one - plugin = either drv basicPluginType; - - # Ensure thoses plugins are loaded before the current one - dependencies = option (list drv); - - # Ensure those packages are available - extraLuaPackages = option function; - - # Should this plugin be load lazily ? - lazy = option bool; - - # List of events on which the plugin should be loaded - events = option (stringOrStringListOr eventType); - - # List of commands on which the plugin should be loaded - cmd = option stringList; - - # List of filetypes on which the plugin should be loaded - ft = option stringList; - - # List of keystrokes on which the plugin should be loaded - keymaps = option (stringOrStringListOr keymapType); - - # Priority of the module. Influence the order of loading plugins. - # Highest values get loaded before. - # priority = option int; - }; - - # A dependency. - # TODO Complete doc - dependency = with yants; eitherN [path drv pluginType]; - - mkNeovimPkgOptions = with yants; - struct "mkNeovimPkgOptions" { - # The configuration of mkNeovimPkg - pkgs = attrs any; - - # The neovim package to wrap with your conifguration. - # Default is pkgs.neovim-unwrapped - package = option drv; - - # init.lua configuration - init = option (eitherN [string path neovimInitType]); - - # An array of dependencies. - dependencies = option (list dependency); - - # Extra argument to pass to dependencies files - dependenciesExtraArgs = option (attrs any); - - # Ensure those packages are available - extraLuaPackages = option function; - - # Runtime configuration - runtime = option runtimeType; - - # Create a vi alias - viAlias = option bool; - - # Create a vim alias - vimAlias = option bool; - - # Create a vimdiff alias to run neovim in diff mode - vimdiffAlias = option bool; - - # Create a nvimdiff alias to run neovim in diff mode - nvimdiffAlias = option bool; - }; -}