diff --git a/modules/home/config.nix b/modules/home/config.nix new file mode 100644 index 0000000..c3a0b70 --- /dev/null +++ b/modules/home/config.nix @@ -0,0 +1,53 @@ +{ + config, + inputs, + lib, + ... +}: { + options.modules.home.config = lib.mkOption { + type = with lib.types; attrsOf path; + default = {}; + description = '' + Files and directories to expose under $XDG_CONFIG_HOME as + out-of-store symlinks pointing at the live source tree in + ~/.nix. + + This lets tools that prefer to manage their own config (Emacs, + Helix, etc.) edit their config files in place without needing a + home-manager rebuild between changes, while still letting Nix + catch missing source files at eval time. + + Keys are paths relative to $XDG_CONFIG_HOME. Values are Nix + paths into this repo (e.g. `./emacs/init.el`). + ''; + example = lib.literalExpression '' + { + "emacs/init.el" = ./emacs/init.el; + "emacs/lisp" = ./emacs/lisp; + } + ''; + }; + + config = let + cfg = config.modules.home.config; + repoRoot = "${config.home.homeDirectory}/.nix"; + + # Under flakes, a path literal like `./init.el` evaluates to a + # store path (the source tree gets copied to /nix/store/HASH-source/). + # We strip that prefix and re-anchor at the live repo so the symlink + # points at the editable file, not the immutable store copy. + storePrefix = "${inputs.self}/"; + mkLivePath = path: let + pathStr = toString path; + in + if lib.hasPrefix storePrefix pathStr + then "${repoRoot}/${lib.removePrefix storePrefix pathStr}" + else pathStr; + in { + xdg.configFile = + lib.mapAttrs (_: path: { + source = config.lib.file.mkOutOfStoreSymlink (mkLivePath path); + }) + cfg; + }; +} diff --git a/modules/home/default.nix b/modules/home/default.nix index 768366e..2542417 100644 --- a/modules/home/default.nix +++ b/modules/home/default.nix @@ -4,6 +4,7 @@ ./carapace.nix ./claude-code.nix ./cli-common.nix + ./config.nix ./datagrip.nix ./discord.nix ./docker.nix