···22 description = "Personal cross-platform dotfiles flake";
3344 inputs = {
55+ # Base package set used by every target system.
56 nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
77+88+ # macOS system configuration framework.
69 nix-darwin.url = "github:nix-darwin/nix-darwin/master";
710 nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
1111+1212+ # User-level configuration framework shared by macOS and Linux.
813 home-manager.url = "github:nix-community/home-manager";
914 home-manager.inputs.nixpkgs.follows = "nixpkgs";
10151616+ # Overlay for a newer Neovim package in the shared package set.
1117 neovim-nightly-overlay.url = "github:nix-community/neovim-nightly-overlay";
1218 };
13191420 outputs = inputs@{ self, nixpkgs, nix-darwin, home-manager, ... }:
1521 let
2222+ # Reuse helper functions from nixpkgs throughout the flake.
1623 lib = nixpkgs.lib;
2424+2525+ # Decide whether a host should be built with nix-darwin or standalone
2626+ # Home Manager based on its target system string.
1727 isDarwin = host: lib.hasSuffix "darwin" host.system;
2828+2929+ # Fill in default paths so every host entry has the same shape, even when
3030+ # `homeDirectory` or `flakeDirectory` are omitted in `hosts.nix`.
3131+ # {
3232+ # system
3333+ # username
3434+ # homeDirectory
3535+ # flakeDirectory
3636+ # }
1837 mkHost = host:
1938 let
2039 homeDirectory = host.homeDirectory or (
···2847 inherit homeDirectory;
2948 flakeDirectory = host.flakeDirectory or "${homeDirectory}/.dot";
3049 };
5050+5151+ # Load the host inventory and normalize each entry once up front.
3152 hosts = lib.mapAttrs (_: host: mkHost host) (import ./hosts.nix);
5353+5454+ # Import nixpkgs for one target system with the repo's shared policy.
3255 mkPkgs = system: import nixpkgs {
3356 inherit system;
3457 config.allowUnfree = true;
3558 };
5959+6060+ # Shared Home Manager module wiring reused by both standalone Home
6161+ # Manager configs and the Home Manager module embedded in nix-darwin.
3662 mkHomeModule = host: {
3737- imports = [ ./home.nix ];
6363+ # Import the Home Manager module tree from `home/default.nix`.
6464+ imports = [ ./home ];
3865 home = {
3966 inherit (host) username homeDirectory;
4067 };
4168 };
6969+7070+ # Build a standalone Home Manager configuration for non-Darwin hosts.
4271 mkHome = _: host: home-manager.lib.homeManagerConfiguration {
4372 pkgs = mkPkgs host.system;
4473 extraSpecialArgs = {
···4675 };
4776 modules = [ (mkHomeModule host) ];
4877 };
7878+7979+ # Build a nix-darwin system for macOS hosts and attach the same Home
8080+ # Manager module so user config stays defined in one place.
4981 mkDarwin = hostName: host: nix-darwin.lib.darwinSystem {
5082 system = host.system;
8383+8484+ # `specialArgs` is an escape hatch from the Nix module system
8585+ # (defined in nixpkgs `lib/modules.nix` -> `lib.evalModules`).
8686+ # It passes arbitrary values directly into every module's function
8787+ # argument list before option evaluation begins.
8888+ #
8989+ # There is no predefined list of allowed keys: you invent the names
9090+ # here and destructure them in the receiving module:
9191+ #
9292+ # # darwin/default.nix
9393+ # { config, pkgs, hostName, flakeDirectory, username, ... }: { ... }
9494+ #
9595+ # Values passed here:
9696+ # self - the flake's own output set
9797+ # hostName - the attribute name from `darwinConfigurations`
9898+ # flakeDirectory - absolute path where the flake lives on disk
9999+ # username - primary user account name
100100+ # homeDirectory - absolute path to the user's home directory
51101 specialArgs = {
52102 inherit self hostName;
53103 inherit (host) flakeDirectory username homeDirectory;
54104 };
105105+55106 modules = [
5656- ./macos.nix
107107+ ./darwin
57108 home-manager.darwinModules.home-manager
58109 {
59110 home-manager.useGlobalPkgs = true;
60111 home-manager.useUserPackages = true;
112112+ # `extraSpecialArgs` is the home-manager equivalent of
113113+ # `specialArgs`: arbitrary values forwarded into every home-manager
114114+ # module's function arguments.
115115+ # Here we pass the full `inputs` attrset so that modules in
116116+ # `home/default.nix` can reference other flake inputs (e.g.
117117+ # overlays, plugins) without those inputs having to be declared
118118+ # as options.
61119 home-manager.extraSpecialArgs = {
62120 inherit inputs;
63121 };
···66124 ];
67125 };
68126 in {
127127+ # Export only Darwin hosts as nix-darwin configurations.
69128 darwinConfigurations = lib.mapAttrs mkDarwin (lib.filterAttrs (_: host: isDarwin host) hosts);
70129130130+ # Export only non-Darwin hosts as standalone Home Manager configs.
71131 homeConfigurations = lib.mapAttrs mkHome (lib.filterAttrs (_: host: !isDarwin host) hosts);
72132 };
73133}