new post about how you can choose not to use #Nix to manage some parts of your configuration, how to do it, and the benefits you get from doing that

instant changes, no rebuilds, and you can still get pinning for dependencies
https://jade.fyi/blog/use-nix-less/

You don't have to use Nix to manage your dotfiles

computers i guess

btw this is partially in reply to @PierreZ's post about problems with NixOS because i read that and scratched my head because i do just edit my zshrc when i feel like it and don't have any rebuilds in my way and then i remembered that this exact problem is a very very common way for new users to be causing themselves pain but thinking it's good for them.

https://pierrezemb.fr/posts/nixos-good-bad-ugly/#the-friction-of-simple-changes-on-nixos

Three Years of Nix and NixOS: The Good, the Bad, and the Ugly

A review of Nix/NixOS after using it on all my machines for three years. I'll cover what works, what doesn't, and why it's the first OS that's stuck with me.

Pierre Zemb's Blog

@leftpaddotpy as seen on my systems

also with the additional gotcha of git submoduling an entire other person's dotfiles

@helle @leftpaddotpy nooooo no submodulessssssss...

(please imagine this said in a very tiny voice by someone half-asleep)

@leftpaddotpy re: "home-manager and lib.file.mkOutOfStoreSymlink", when I bashed my head against that problem a few years ago, I came up with an alternative approach.

I decouple the build path and the runtime path of my dotfiles repo (where the symlinks point to), and treat the runtime path as an input/constant, like so: https://gist.github.com/solson/bccba4a2060c854f28554a349c161883

(I replace `toString self`, the `/nix/store/<hash>-source` prefix, with `/x`, the directory where I put my personal monorepo these days.)

flake-outputs.nix

GitHub Gist: instantly share code, notes, and snippets.

Gist

@leftpaddotpy Of course, this is still not user-friendly, and I'm aware of some of your other strong criticisms of home-manager. I just have a strong memory of getting blindsided by this problem and then "solving" it. ^^

Some of my other solutions likely still line up with yours, since e.g. I don't manage Neovim with home-manager at all, but I do use it to inject certain Nix store paths by generating a JSON file that Neovim reads: https://gist.github.com/solson/803e5062e79db7471221171cb353fe31

gist:803e5062e79db7471221171cb353fe31

GitHub Gist: instantly share code, notes, and snippets.

Gist

@rx yeah, I'm not trying to write a dunk post on home manager here; it does do things which are really cool and it's just one choice on a spectrum from entirely unmanaged to the pretty low tech stuff I'm doing to nix everything.

unfortunately for my desire to personally use it, i keep helping friends with "I'm so sorry you have to deal with this" situations because they've often gotten tangled in it in ways that make them sad for which the resolution is indeed often to just selectively remove stuff like nvim from it. however, it's thankfully quite easy to do that selectively.

@leftpaddotpy I would love to see more official support and design consideration for selective adoption, which can come in many forms, e.g.

1. Mostly mutable config which imports generated config (like my nvim JSON)
2. Mostly immutable config which imports some unmanaged config (`.foorc.local`)
3. This trick I recently learned about to symlink config files mutably on dev machines, but ship the same files immutably for server deploys: https://github.com/belak/dotfiles/blob/63b5ab962f899c728e1069dcfa2c5fe509c42861/nix/home/modules/dotfiles.nix

dotfiles/nix/home/modules/dotfiles.nix at 63b5ab962f899c728e1069dcfa2c5fe509c42861 · belak/dotfiles

My personal environment configuration. Contribute to belak/dotfiles development by creating an account on GitHub.

GitHub
@leftpaddotpy I think a lot of this could be streamlined, better documented, integrated into h-m modules as first-class concepts, etc

@leftpaddotpy

The simplest solution for dotfiles, […], is to symlink a bunch of files into a Git repo.

I’d argue that the simplest solution is to just put the home dir itself into git. Am I missing anything?

Apart from the obvious bit that then you must never run git add . but I don’t think that’s a big issue?

@liskin there's a horrible solution to this actually. you can put * in gitignore and then !foo for each thing you actually want. i know people who do this weird git pattern and different people who put their home directory directly in git.

i don't personally think the latter is great because i don't like the home directory layout and think it's poor code organization. also it will make it pretty easy to do weird tooling mistakes with things that expect a parent repo. but it is technically possible!

@leftpaddotpy What I actually do is I have the .git in src/dotfiles but its worktree is set to ~, solving the problem of the repo being exposed by default. For the root dotfiles, the worktree is / 🙂

And the gitignore thing… I have an alias for git status that only looks at subdirectories that have .gitignore in them. So by touch .vim/.gitignore I mark .vim as wanted. Slightly better than having a global .gitignore, as that would confuse nvim’s detection of LSP root dir and perhaps have other unintended consequences.

So yeah there are hacks but having to symlink stuff is just a different hack.

(I’m not actually arguing, I was just curious why many people bother with symlinks or Nix, and the discussion helped understand)

@leftpaddotpy One thing I really like about my setup is that I can `git grep` and it tells me where that thing actually is 😁

@liskin FASCINATING. i love hearing about people's workflows, especially if they managed to combine together the right advanced features to get what they want (and what they want is a creative use of the tool).

i think originally i used symlinks (and my own bad script) because i didn't like the aesthetics of any of the dotfiles managers which copy the structure of the home directory and didn't want to learn yet another thing. these days, in principle, I've become an advanced enough git user that i could have adopted your workflow but i still have incompatible opinions about the layout that lead to using symlinks.

you could definitely write a blog post about this invention.

@leftpaddotpy now that I think about it I do actually use symlinks a bit, but the other way around - https://github.com/liskin/dotfiles/tree/home/.nvim - as a shortcut for stuff that lives deep in xdg dirs and I edit often enough to be annoyed by it

and yeah it's held together by Makefiles and bash scripts - it's a complete insanity, but too much work to do better (even if there was consensus on what better is, even if there was a chance that better now will be the same as better in 5 years)

(yeah the blog thing... goes somewhere on my already overflowing to do list, I'm afraid)
dotfiles/.nvim at home · liskin/dotfiles

My personal monorepo: dotfiles, /etc-files, single-file scripts, vim plugins, webexts/userscripts, xmonad config, all that stuff… - liskin/dotfiles

GitHub
@leftpaddotpy @liskin we clone our dotfiles into ~/.config. it avoids the above problems and requires like 2 symlinks for the few things that don't support XDG config
@kouhai @leftpaddotpy @liskin imo the most cursed part of it is that we end up putting ~/.config/bin in our $PATH
@Qyriad @kouhai @liskin i have this as well but it's in ~/bin and //bin in my repo
@leftpaddotpy @Qyriad @kouhai @liskin ~/.local/bin has been our tradition for many years now
@helle @Qyriad @kouhai @liskin we don't do this for scripts we own because tools like pip put junk in there
@leftpaddotpy @helle @Qyriad @liskin ditto for usr local bin
@kouhai @leftpaddotpy @helle @Qyriad @liskin looks at dotfiles with arbitrary mappings between config files and home directory paths

looks at fedi i am perfectly normal and can be trusted with configuration scripts
@kouhai @leftpaddotpy @helle @Qyriad @liskin no i didn't write a script called track-config.sh haha that would be absurd
@jyn @leftpaddotpy @helle @Qyriad @liskin I worry for your immortal configuration, jyn
@kouhai @leftpaddotpy @helle @Qyriad @liskin look it gives me less issues than using nix ....

@jyn @kouhai @helle @Qyriad @liskin as this post shows, there are different amounts of using nix, and you can achieve "not having to use homebrew or worry about slow updating linux distros with incomplete packaging of dev tools" without making your life worse by putting nix in your way.

but anyway, the arbitrary mappings thing is something i do as well, but it is as symlinks so i don't have to keep track of the thing once it's created.

@Qyriad @leftpaddotpy @liskin honestly with how well supported XDG config is, this is a great idea!

I have my dotfiles repo with $HOME as worktree (inspired by https://mitxela.com/projects/dotfiles_management) but as you can see https://codeberg.org/valpackett/dotfiles almost everything is in the .config.. almost.

Dotfiles Management - mitxela.com

Tracking config files

@leftpaddotpy
fwiw there's a third, imo slightly underrated alternative for the "symlink into git repo", which is to hardcode the full path to where you expect the dotfiles repo to be, e.g.

mkSymlink = p: config.lib.file.mkOutOfStoreSymlink "${config.home.homeDirectory}/system/${p}";

(this is a bit tangential to the actual point of the article ofc, but it's still usually worth considering along with the other options)

@refi64 oh interesting, i thought i remembered that it asserted that whatever you give it is a path.

@leftpaddotpy IMO the simplest and best thing for dotfiles is no symlinks at all.

https://mitxela.com/projects/dotfiles_management described a "trick" with a bare repo and a --work-tree of literally / but I use --work-tree=$HOME instead: https://codeberg.org/valpackett/dotfiles

home-mangler is nice for user packages. I'd keep using it even with NixOS. I'm not sold on the "monolithic machine conf down to user stuff" thing at all, I'd rather think of NixOS as a distro construction kit :p

Dotfiles Management - mitxela.com

Tracking config files

@valpackett home-mangler is written by a friend. it was actually what made me write flakey-profile because i knew it could be done fully declaratively with hardly any code.
@valpackett the reason i use symlinks is that i want to control my repo organization (especially because it contains more than just configs).

@leftpaddotpy Do you think eval times are the crux of the issue here? E.g. if it was 100x faster, and even a large home-manager config took under 1s to eval+build+activate, would that solve the iteration loop problem? (You could just hook your editor to apply the config on save, like hot reloading.)

Also please write that blog post on why Nix evaluations are slow and what to do about them, would be very much interested.

@kuruczgy Mostly! I think not exactly because you still have to deal with the cognitive overhead of figuring out where the heck that store path came from that doesn't exist with symlinks.