diff options
| author | Arpit Chakladar <arpitchakladar+git@gmail.com> | 2026-08-29 02:02:23 +0530 |
|---|---|---|
| committer | Arpit Chakladar <arpitchakladar+git@gmail.com> | 2026-08-29 03:50:32 +0530 |
| commit | 41bdeb88009dd232808edee9fc0e4ae94358d8d6 (patch) | |
| tree | c1a41f54e086064dac178ebed24d36ab34087c32 /modules/lib | |
| parent | 530299d97926d45939f831dc3ea5e444d2839d08 (diff) | |
| download | home-manager-config-41bdeb88009dd232808edee9fc0e4ae94358d8d6.tar.gz home-manager-config-41bdeb88009dd232808edee9fc0e4ae94358d8d6.zip | |
refactor: moving script into modules that makes sense
- instead of collecting all scripts into modules/scripts we are moving
them to modules that makes sense (yazi-file-chooser.sh into yazi)
Diffstat (limited to 'modules/lib')
| -rw-r--r-- | modules/lib/default.nix | 48 | ||||
| -rw-r--r-- | modules/lib/script.nix | 146 |
2 files changed, 194 insertions, 0 deletions
diff --git a/modules/lib/default.nix b/modules/lib/default.nix new file mode 100644 index 0000000..fd54fa2 --- /dev/null +++ b/modules/lib/default.nix @@ -0,0 +1,48 @@ +# Internal aggregation for script modules registered via mkScriptModule +{ + config, + lib, + ... +}: +{ + options.scriptPaths = lib.mkOption { + type = lib.types.listOf (lib.types.listOf lib.types.str); + default = [ ]; + internal = true; + description = "Attr paths of script modules registered via mkScriptModule."; + }; + + config = { + home.packages = lib.filter (p: p != null) ( + map (path: (lib.getAttrFromPath path config).package) config.scriptPaths + ); + + xdg.desktopEntries = lib.listToAttrs ( + map + ( + path: + let + name = lib.last path; + sc = lib.getAttrFromPath path config; + in + lib.nameValuePair name { + name = sc.desktop.displayName; + exec = "${lib.getExe config.terminal.kitty.package} --class ${name} -e ${lib.getExe sc.package}"; + icon = sc.desktop.icon; + categories = [ "Utility" ]; + terminal = false; + type = "Application"; + } + ) + ( + lib.filter ( + path: + let + sc = lib.getAttrFromPath path config; + in + sc.enable && sc.desktop.enable + ) config.scriptPaths + ) + ); + }; +} diff --git a/modules/lib/script.nix b/modules/lib/script.nix new file mode 100644 index 0000000..9871b88 --- /dev/null +++ b/modules/lib/script.nix @@ -0,0 +1,146 @@ +# Library for creating script modules +{ + lib, + pkgs, +}: +let + shellArgs = { + zsh = name: file: "--zsh --name _${name} ${file}"; + bash = name: file: "--bash --name ${name}.bash ${file}"; + }; + + mkScript = + name: path: description: env: deps: completion: + let + descLines = lib.filter (s: s != "") (lib.splitString "\n" description); + descComment = + if descLines == [ ] then "" else lib.concatMapStringsSep "\n" (line: "# ${line}") descLines + "\n"; + envVars = lib.concatStringsSep "\n" ( + lib.mapAttrsToList (n: v: "export ${n}=${lib.escapeShellArg (toString v)}") env + ); + base = pkgs.writeShellApplication { + inherit name; + runtimeInputs = deps; + text = '' + ${descComment}${envVars} + ${builtins.readFile path} + ''; + }; + completionDrv = + pkgs.runCommand "${name}-completion" + { + nativeBuildInputs = [ pkgs.installShellFiles ]; + } + ( + "mkdir -p $out\n" + + lib.concatStringsSep "\n" ( + lib.mapAttrsToList (shell: content: '' + installShellCompletion ${shellArgs.${shell} name (pkgs.writeText "_${name}.${shell}" content)} + '') completion + ) + ); + in + if completion == { } then + base + else + pkgs.symlinkJoin { + name = name; + paths = [ + base + completionDrv + ]; + meta = base.meta or { }; + }; + + mkScriptModule = + { + scope ? [ ], + name, + path, + env ? { }, + deps ? [ ], + desktop ? null, + extraLinks ? [ ], + config, + description ? "", + completion ? { }, + }: + let + scriptAttrs = scope ++ [ name ]; + dottedName = lib.concatStringsSep "." scriptAttrs; + c = lib.getAttrFromPath scriptAttrs config; + scriptDrv = mkScript name path description env deps completion; + in + { + options = lib.setAttrByPath scriptAttrs { + enable = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Whether to enable the ${name} script."; + }; + package = lib.mkOption { + type = lib.types.nullOr lib.types.package; + readOnly = true; + description = "The derivation for the ${name} script."; + }; + completion.enable = lib.mkOption { + type = lib.types.bool; + default = completion != { }; + description = "Whether to install completions for the ${name} script."; + }; + desktop = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Whether to create a .desktop entry for this script."; + }; + displayName = lib.mkOption { + type = lib.types.str; + default = name; + description = "Display name for the .desktop entry."; + }; + icon = lib.mkOption { + type = lib.types.str; + default = "kitty"; + description = "Icon for the .desktop entry."; + }; + }; + }; + + config = + lib.setAttrByPath scriptAttrs ( + lib.mkIf c.enable ( + { + package = scriptDrv; + } + // lib.optionalAttrs (desktop != null) { inherit desktop; } + ) + ) + // { + home.file = lib.mkIf c.enable ( + builtins.listToAttrs ( + map (linkPath: { + name = lib.removePrefix "~/" linkPath; + value = { + source = "${scriptDrv}/bin/${name}"; + }; + }) extraLinks + ) + ); + assertions = [ + { + assertion = !c.enable || !c.desktop.enable || config.terminal.kitty.enable; + message = "${dottedName}.desktop.enable requires terminal.kitty.enable because desktop entries launch scripts in kitty."; + } + { + assertion = !c.completion.enable || completion != { }; + message = "${dottedName}.completion.enable is true but no completion text was provided to mkScriptModule."; + } + ]; + scriptPaths = [ scriptAttrs ]; + }; + }; +in +{ + inherit mkScript mkScriptModule; +} |
