The function below lets you create a directory in your home-manager config that auto-creates symlinks for non-Nix dotfiles from ~/.config/ using xdg.configFile and mkOutOfStoreSymlink. This gives the following advantages:
- You can keep all your non-Nix dotfiles in your home-manager repo.
- You don't have to do
home-manager switchon each dotfile change. Changes are instantly reflected. - You don't need to hard-code the paths for each symlink, the linking is instead file-based. Just add the new dotfile to the directory, and you're done.
For example, if your home-manager config is in ~/nixos/ and looks like this...:
~/nixos
├── ...
├── flake.nix
└── configs
├── starship.toml
└── fish
└── config.fish
...then home-mamager will create the following symlinks in ~/.config:
~/.config
├── ...
├── starship.toml -> ~/nixos/configs/starship.toml
└── fish
└── config.fish -> ~/nixos/configs/fish/config.fish
Don't forget to git add when adding a new dotfile. Otherwise, they will be ignored by Nix. Then run home-manager switch to create the new symlink.
{ config }:
{
# -------------------------------------------------------------------------
# `configsPath`: a path value to a directory who's files/directories
# should be symlinked to from `~/.config/`.
#
# `configsAbsolutePath`: an absolute path to `configsPath`.
#
# The reason this function requires two path parameters to the same
# directory is that it uses `builtins.readDir` which would require
# `--impure` if only an absolute path were used. If using only a literal
# Nix path, the symlinks would point to the Nix store, and thereby require
# a build whenever a config file is edited.
#
# `returns`: an attribute set suitable for `xdg.configFile`.
# -----------------------------------------------------------------
configSymlinks = configsPath: configsAbsolutePath:
let
inherit (config.lib.file) mkOutOfStoreSymlink;
mkSymlink = name: {
name = name;
value.source = mkOutOfStoreSymlink "${configsAbsolutePath}/${name}";
};
in configsPath
|> builtins.readDir
|> builtins.attrNames
|> map mkSymlink
|> builtins.listToAttrs;
}You call the function like this:
# Both arguments should point to your `configs` directory in home-manager. The
# first is relative to this file, the second is the absolute path.
xdg.configFile = configs.configSymlinks ./configs "~/nixos/configs/";Please let me know if there's some way to improve the implementation so that you only have to pass in one path parameter.