feat: can use flakeModules perSystem to build package with new ongoing module API

dev
LeMarsu 2025-10-06 17:47:49 +02:00
parent 27c8d275c5
commit fabe787feb
5 changed files with 326 additions and 6 deletions

View File

@ -49,6 +49,21 @@
"type": "github" "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": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1660438583, "lastModified": 1660438583,
@ -68,6 +83,7 @@
"inputs": { "inputs": {
"flake-parts": "flake-parts", "flake-parts": "flake-parts",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"nixpkgs-lib": "nixpkgs-lib_2",
"yants": "yants" "yants": "yants"
} }
}, },

View File

@ -3,16 +3,18 @@
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
nixpkgs-lib.url = "github:nix-community/nixpkgs.lib";
yants.url = "github:divnix/yants"; yants.url = "github:divnix/yants";
flake-parts.url = "github:hercules-ci/flake-parts"; flake-parts.url = "github:hercules-ci/flake-parts";
}; };
outputs = {flake-parts, ...} @ inputs: let outputs = {flake-parts, ...} @ inputs: (flake-parts.lib.mkFlake {inherit inputs;} {
in (flake-parts.lib.mkFlake {inherit inputs;} {
systems = ["x86_64-linux"]; systems = ["x86_64-linux"];
imports = [ imports = with flake-parts.flakeModules; [
flakeModules
./dev ./dev
./flakeModule.nix
./lib ./lib
]; ];
}); });

51
flakeModule.nix Normal file
View File

@ -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 = "sloths 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;
});
};
}

View File

@ -12,8 +12,11 @@
types = import ./types.nix {inherit (inputs) yants;}; types = import ./types.nix {inherit (inputs) yants;};
in { in {
flake.lib = { flake = {
mkNeovimPkg = import ./mkNeovimPkg.nix {inherit version types;}; lib = {
mkPluginsFromInputs = import ./mkPluginsFromInputs.nix; mkNeovimPkg = import ./mkNeovimPkg.nix {inherit version types;};
mkPluginsFromInputs = import ./mkPluginsFromInputs.nix;
};
mkLib = import ./lib.nix;
}; };
} }

248
lib/lib.nix Normal file
View File

@ -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;
}