diff --git a/modules/modules.nix b/modules/modules.nix index dbeebfbf..a8698490 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -175,6 +175,7 @@ let ./programs/noti.nix ./programs/notmuch.nix ./programs/nushell.nix + ./programs/nu-scripts.nix ./programs/obs-studio.nix ./programs/octant.nix ./programs/offlineimap.nix diff --git a/modules/programs/nu-scripts.nix b/modules/programs/nu-scripts.nix new file mode 100644 index 00000000..35929587 --- /dev/null +++ b/modules/programs/nu-scripts.nix @@ -0,0 +1,107 @@ +{ pkgs, lib, config, ... }: +let + inherit (lib) mkIf mkEnableOption mkOption types pipe; + + cfg = config.modules.nushell.nuScripts; + scripts = "${pkgs.nu_scripts.outPath}/share/nu_scripts/"; + + managedIncludeOption = let + filterOption = description: + mkOption { + inherit description; + type = with types; nullOr (listOf str); + default = null; + }; + in name: { + enable = mkEnableOption '' + management of ${name}. + + If the include and exclude options are both unset all items will be included. + ''; + + include = filterOption + "${name} to include. Matches infix name of directory/file in nu_scripts"; + exclude = filterOption + "${name} to exclude. Matches infix name of directory/file in nu_scripts"; + }; + + pathCompletions = scripts + "custom-completions/"; + pathCompletionsAuto = pathCompletions + "auto-generate/completions/"; + pathModules = scripts + "modules/"; + pathAliases = scripts + "aliases/"; +in { + meta.maintainers = [ lib.maintainers."1adept" ]; + + options.modules.nushell.nuScripts = { + enable = mkEnableOption "script management for nu_script scripts"; + + completions = managedIncludeOption "completions"; + completionsAutoGenerated = + managedIncludeOption "auto generated completions"; + modules = managedIncludeOption "modules"; + aliases = managedIncludeOption "aliases"; + }; + + config = mkIf (cfg.enable && config.modules.nushell.enable) { + # Add nu_scripts + home.packages = [ pkgs.nu_scripts ]; + + programs.nushell.extraConfig = let + getFiles = path: + { enable, include ? [ ], exclude ? [ ], ... }: + let + isNuFile = lib.hasSuffix ".nu"; + + # Collect all nu-files in ${path} + nuFiles = pipe path [ + (builtins.readDir) + (lib.mapAttrsToList (name: value: + if isNuFile name then + [ name ] + else + lib.optional (value == "directory") (pipe (path + "/" + name) [ + (builtins.readDir) + (lib.mapAttrs (name2: value2: "${name}/${name2}")) + (lib.attrValues) + ]))) + (lib.flatten) + (lib.filter isNuFile) + ]; + + inList = list: item: lib.any (lib.flip lib.hasInfix item) list; + + selectedFiles = lib.filter (item: + (include == null || inList include item) + && (exclude == null || !inList exclude item)) nuFiles; + + result = map (name: path + name) selectedFiles; + in lib.optionals enable result; + + useFiles = files: + pipe files [ + (map (file: "use ${file} *")) + (builtins.concatStringsSep "\n") + ]; + + completions = useFiles (getFiles pathCompletions cfg.completions); + completionsAuto = + useFiles (getFiles pathCompletionsAuto cfg.completionsAutoGenerated); + aliases = useFiles (getFiles pathAliases cfg.aliases); + modules = useFiles (getFiles pathModules cfg.modules); + + # Mk after main config file. This may be necessary for some scripts to be evaluated + in lib.mkAfter '' + # Generated with home-manager from github:nushell/nu_scripts + # Completions -------------------------------------------- + ${completions} + ${completionsAuto} + # Modules ------------------------------------------------ + ${modules} + # Aliases ------------------------------------------------ + ${aliases} + # -------------------------------------------------------- + # Generated END + ''; + }; +} +