{ config, lib, pkgs, ... }: with lib; let cfg = config.services.dotfiles; stowDir = cfg.stowDir; # Function to recursively find all files in a directory findFiles = dir: let files = builtins.attrNames (builtins.readDir dir); in concatMap (name: let path = dir + "/${name}"; in if (builtins.typeOf (builtins.readDir path) == "set") then findFiles path else [ path ] ) files; # Get a list of all packages (directories) in the stow directory stowPackages = builtins.attrNames (builtins.readDir stowDir); # Create an attribute set where each attribute is a package name # and the value is a list of files to be linked. homeManagerLinks = listToAttrs (map (pkg: let pkgPath = stowDir + "/${pkg}"; files = findFiles pkgPath; in nameValuePair pkg (map (file: { source = file; target = removePrefix (pkgPath + "/") file; }) files) ) stowPackages); in { options.services.dotfiles = { enable = mkEnableOption "Enable dotfiles management"; stowDir = mkOption { type = types.path; description = "The directory where your stow packages are located."; }; user = mkOption { type = types.str; description = "The user to manage dotfiles for."; }; }; config = mkIf cfg.enable { home-manager.users.${cfg.user} = { home.file = let allFiles = concatLists (attrValues homeManagerLinks); in listToAttrs (map (file: nameValuePair file.target { source = file.source; } ) allFiles); }; }; }