Repository navigation
Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Repository files navigation
archbtw
=======
I use Arch, btw.
also apparently Nix now, don't tell pacman.
one package manager identity crisis wasn't enough,
so now two package managers live in my house & refuse to talk to each other.
NixOS? Never heard of her.
=======
Home Manager configuration for sicmundus, layered on top of a normal Arch
Linux install. This is NOT NixOS. Arch (pacman) still owns the kernel,
bootloader, firmware, drivers, systemd, networking, filesystems, DBus, and
PipeWire. Nix + Home Manager owns the user environment on top of it: CLI
tools, dev toolchains, shell config, dotfiles, and (eventually) the Hyprland
desktop stack.
Layout
------
flake.nix entry point, pins nixpkgs-unstable + home-manager + agenix
home.nix top-level config, wires up the modules below
modules/packages.nix catch-all for packages with no dedicated module yet;
empty by design, not a placeholder for missing work
modules/cli.nix CLI utilities -- the original Phase 1 set (bat, eza, fd,
ripgrep, fzf, jq, btop, fastfetch, lazygit, gh, direnv,
atuin) plus 22 leaf tools swept in later (zellij, yazi,
zoxide, yt-dlp, ncdu, cloc, bc, socat, pv, tree-sitter,
cbonsai, asciiquarium, gum, tty-clock, ttyper, p7zip,
inotify-tools, w3m, lynx, mpc, rmpc, wev, wtype,
wmctrl) -- see the file for the exact current list,
this README won't be re-synced on every addition
modules/git.nix programs.git -- user/editor/credential.helper, written
to ~/.config/git/config (XDG path, not ~/.gitconfig)
modules/shell.nix zsh: history, completion, autosuggestions, syntax
highlighting, fzf-tab, Powerlevel10k, env vars
modules/aliases.nix all shell aliases -- deduped from the old .zshrc +
~/.aliases, plus a Nix/Home Manager workflow set
(hms/hmb/hmg/ngc/etc, see the file header comment)
modules/dev.nix dev toolchains (go, rustup, nodejs, python3, pipx,
cmake, ninja, llvm, clang)
modules/secrets.nix agenix wiring (flake input + CLI); no secrets defined yet
modules/editors.nix Neovim binary only -- ~/.config/nvim is self-managed lazy.nvim
modules/gui.nix GUI apps that actually work under Nix (see GPU note below)
secrets/secrets.nix agenix recipient manifest, gitignored (has a real
pubkey, deliberately not pushed) -- recreate from
~/.ssh/id_ed25519.pub if this repo is ever cloned fresh
backup/ the original stock `home-manager init` output, kept
for reference, not imported by anything
rice/ plain backup COPY of the live Hyprland/matugen desktop
dotfiles (hypr, waybar, kitty, rofi, swaync, etc), plus
the full ~/Pictures/Wallpapers pool -- not managed or
symlinked by Home Manager, see rice/README. The
Wallpapers folder (~3.7G) is fully committed and pushed
but excluded from this repo's local working tree via
`git sparse-checkout` (see Workflow below) so it
doesn't sit on disk twice; it's still on GitHub in full.
Status
------
Done: Phase 0 (repo skeleton), Phase 1 (CLI), Phase 2 (git), Phase 3 (shell),
Phase 4 (dev), Phase 5 (Neovim), Phase 6 (GUI apps, partial -- see GPU note)
Skipped: Phase 7 (fonts/themes/icons/cursor) -- investigated, deliberately
not migrating. Icons are a git-managed collection in
~/.local/share/icons (built on the "illogical-impulse" Hyprland
dotfiles project, judging by illogical-impulse.svg in there), GTK/
color theming is actively driven by matugen's generated templates
(kitty, quickshell, qt5ct/qt6ct, Hyprland colors.conf, cava,
swayosd, neovim), and the one font actually in use (JetBrainsMono
Nerd Font, in kitty) is hard-blocked from pacman removal by yazi
anyway. Nothing here would gain from a Nix package -- it's already
better managed outside of pacman and Nix both.
Skipped: Phase 8 (Hyprland/Waybar/Hyprlock/Hypridle/Hyprpaper/Rofi/
notifications/clipboard/portal) -- investigated, deliberately not
migrating. hyprland (the live compositor, required by hyprshade),
hyprlock (security-critical -- a broken lock screen can fail open,
not just annoy you), hypridle (confirmed actively running, tightly
IPC-coupled to hyprland/hyprlock), and xdg-desktop-portal-hyprland
(other apps like steam/obs-studio depend on it working) all stay
pacman-only permanently -- no realistic upside (nixpkgs versions
already match pacman's almost exactly) against a uniquely severe
downside (a broken live desktop, not just a broken command).
hyprpaper isn't even running -- mpvpaper is the real live-wallpaper
mechanism, confirmed via WallpaperPicker.qml. waybar/rofi/swaync/
cliphist were left alone too: same GTK/layer-shell GPU-rendering
uncertainty as the Phase 6 Electron apps, and testing them for real
would mean launching a competing instance against the live bar/
notifications mid-session -- not a risk worth taking for apps that
already work fine on pacman.
Done: Phase 9 (final cleanup) -- 12 orphaned packages left over from the
Neovim migration removed (tree-sitter-*, libvterm, msgpack-c, etc,
plus tree-sitter itself once it became a second-order orphan), pacman
db verified clean, nix store gc'd (1792 dead paths, 1005.6 MiB freed,
all 9 generations and current activation verified intact afterward)
Done: post-Phase-1 sweep -- 22 additional leaf CLI tools (see modules/cli.nix
for the list) added after confirming via `pacman -Qi` that every one
had zero pacman reverse-deps (Required By: None); all 22 pacman
packages fully removed after the Nix build/switch was verified
Done: post-Phase-2 cleanup -- dropped the unused `sendemail`/gmail block
from git.nix (no evidence of `git send-email` use, and it put a real
email in this public repo's history for no benefit) and removed the
stale plain ~/.gitconfig on disk, which predated this migration and
was silently shadowing the Nix-managed ~/.config/git/config for
anything both files set. Backed up locally to ~/.config/hyprbackup
(never pushed) before deleting, not left as dead weight in the repo.
GPU acceleration under Nix (read before touching Phase 7/8)
-------------------------------------------------------------
Nix's bundled Mesa can't reach Arch's real GPU driver stack out of the box:
it looks for drivers at /run/opengl-driver (a NixOS-only convention). Fixed
the first hop with a symlink (/run/opengl-driver -> /usr, made permanent via
/etc/tmpfiles.d/opengl-driver.conf) -- this is safe, additive, doesn't touch
actual drivers/Mesa, just tells Nix binaries where Arch's already-working
ones live.
That fixes simple cases, but Electron/Chromium apps (tested: Obsidian) hit a
second wall: Arch's dri_gbm.so needs libgallium-*.so, which lives one
directory up (/usr/lib, not /usr/lib/gbm). Nix's dynamic linker doesn't
consult /etc/ld.so.cache the way a native Arch process does, so it can't find
it. Tried LD_LIBRARY_PATH=/usr/lib as a blanket fix -- this broke worse: it
loaded Arch's glibc ahead of Nix's own and crashed with a GLIBC_PRIVATE
symbol mismatch. Do not try that again without scoping it far more narrowly.
Decision: firefox, brave, obsidian, mpv stay pacman-only permanently (same
tier as python/nodejs -- see below). flameshot was verified clean (no GL/EGL
errors, doesn't need heavy compositing) and is Nix-managed. The real fix for
GPU-heavy apps, if ever wanted, is nixGL (github.com/guibou/nixGL) -- wraps
specific launches with a curated, correctly-scoped library path instead of a
blanket one. Not set up. Expect to hit this again in Phase 7/8 for anything
using GTK/Wayland layer-shell rendering (Waybar, Rofi, Hyprlock) -- check
each one for GL/EGL errors before assuming it'll behave like flameshot did.
What stays on pacman permanently (not a "not done yet", a deliberate never):
zsh it's /bin/zsh, your actual login shell in /etc/passwd
git hard-required by paru, yay, git-filter-repo, zed
python hard-required by ~90 packages incl. reflector, kitty, meson
nodejs/npm hard-required by zed
ninja hard-required by meson
gdb hard-required by debugedit
fzf hard-required by ani-cli, downgrade, fzf-tab-git
jq hard-required by yq
llvm/clang only soft/optional reverse deps, low priority to touch
Real regression hit and fixed: Nix's python3 (added Phase 4) shadowed
/usr/bin/python3 on PATH and broke virt-manager -- its #!/usr/bin/env python3
shebang resolved to Nix's bare python3 instead of Arch's, which has
python-gobject installed and Nix's didn't, so `import gi` failed. Fixed by
removing python3 from dev.nix's global home.packages entirely (see comment
there). General lesson: any Arch tool using `env python3` (or similar
PATH-dependent shebangs) for system integration is at risk from a globally
-shadowing Nix interpreter of the same name -- gdb/nodejs could theoretically
have the same class of issue if something similar surfaces; check for
ModuleNotFoundError-style breakage in system tools after adding any Nix
language runtime, not just after adding libraries directly.
For all of these, the Nix-provided copy is installed and shadows the pacman
one on PATH for your own use; pacman's copy is never removed because
something else on the system depends on it existing.
firefox, brave, obsidian, mpv GPU acceleration doesn't work cleanly
through Nix's Mesa (see note above) --
these have NO Nix-provided copy at all,
pacman's is the only one and stays that way
Everything else that got migrated (bat, eza, fd, ripgrep, btop, fastfetch,
lazygit, gh, direnv, atuin, rustup, the zsh plugin packages, plus the 22
leaf tools listed in modules/cli.nix and programs.git's ~/.config/git/config)
had its pacman package fully removed after verification, plus a second leaf
batch (ani-cli, gifski, irssi, weechat, znc, luarocks, nyx, pamixer, sparse,
stress-ng, yq, wl-clip-persist, tesseract).
Note on starship: zsh theming is Powerlevel10k (modules/shell.nix), not
starship -- an earlier revision of this README wrongly claimed starship had
been migrated, when in fact it wasn't installed anywhere at all. It later
turned out fish's config.fish (a separate, non-Home-Manager-managed shell
config) calls `starship init fish` unconditionally, so the binary being
missing was an actual live breakage, not a doc inaccuracy. Fixed by adding
starship to modules/cli.nix. zsh (via p10k) and fish (via starship) are
two independent prompts on two independent shells; don't conflate them.
Workflow
--------
Never edit ~/.zshrc, ~/.gitconfig, etc directly again -- they're symlinks
into the Nix store now. Edit the module, then:
cd ~/.config/home-manager
git add -A # flakes only see git-tracked files
nix flake check --no-build # catches eval errors before building
nix build .#homeConfigurations.sicmundus.activationPackage --no-link --print-out-paths
# inspect the printed store path's home-files/ if the change is delicate
home-manager switch --flake .#sicmundus
git commit -m "..." # one commit per verified change
Rollback
--------
home-manager generations # list all generations
/nix/store/.../activate # re-activate an older one directly
git log --oneline # source-level history
git revert / git reset --hard <commit> # undo a config change at the source
Removing a pacman package is only ever done after the Nix replacement is
installed, built, switched to, and functionally verified -- never before.
Sparse-checkout (rice/home/Pictures/Wallpapers)
------------------------------------------------
This repo's git history and GitHub remote have the full wallpaper pool
committed (~3.7G, 2226 files), but the local working tree does not
materialize it -- `git sparse-checkout` (non-cone mode) excludes just that
one path via .git/info/sparse-checkout:
/*
!/rice/home/Pictures/Wallpapers/
This avoids a duplicate on-disk copy (the real one lives at
~/Pictures/Wallpapers, untouched by any of this). The files are still fully
tracked -- `git ls-files -v` shows them with the `S` (skip-worktree) flag,
and `git status` correctly reports a clean tree. Fast prompt tools that
bypass git's own status logic (Powerlevel10k's gitstatusd, specifically)
don't honor skip-worktree and will misreport these as modified -- that's a
known cosmetic mismatch, not a real repo problem. To get the files back
locally: `git sparse-checkout disable` (or `add` the specific path).
Also: any single `git push` covering this history must stay under GitHub's
2 GiB pack-size hard limit. The wallpaper commits were split into ~1.2G
batches for this reason (see git log around the "wallpaper pool batch"
commits) -- if more large binary content is ever added to rice/, batch it
the same way rather than committing it all at once.