Config for tmux, zsh, and shell utilities, managed with Nix / Home Manager.
- Nix with flakes (the Determinate installer enables them) — see bootstrap below.
home/— Home Manager modules; the source of truth for the whole environmenthome/shell.nix— zsh entry point: env, aliases, vi-mode, functionshome/tmux.nix— tmux config,C-aprefix, vi bindings.local/bin/— shell utilities (tmux-sessionizer,tmux-launcher)
A Home Manager flake reproduces
this whole environment (zsh, starship, fzf, lazygit, yazi, tmux, neovim, plus
Node/Rust/C++ toolchains) on macOS, WSL, and Debian — no NixOS required. The
home/*.nix modules are the source of truth; they declare the shell/tool
configs as native programs.* modules.
flake.nix— entry point; defines hostsosx,wsl,debian,pi,workhome/— the Home Manager modulesdefault.nix— imports + stateVersionpackages.nix— toolchains (Node/Rust/clang) + CLI utilitiesshell.nix— zsh, fzf, starship, env, aliases, vi-modeprograms.nix— lazygit, yazi, neovim, gittmux.nix— tmux + nix-managed pluginsscripts.nix—.local/bin/*→~/.local/bin
# 1. install Nix (Determinate installer enables flakes for you)
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
# 2. get the repo
git clone <repo> ~/git/dots && cd ~/git/dots
# 3. activate (pick the host matching the machine; adjust username in flake.nix)
nix run home-manager/master -- switch --flake .#wsl # or debian / osx
# subsequent updates
home-manager switch --flake ~/git/dots#wslEdit the
username/homeDirectoryinflake.nixif your login differs. Validate without activating:nix flake check.
A few configs are deliberately not managed by Nix — each host edits its own
copy (e.g. local.nix, ~/.config/tmux/sessionizer.toml). Their tracked
*.example templates are materialized at the right path by one convenience
script:
./copy-examples.sh # create any missing config from its template
./copy-examples.sh --force # overwrite existing configs from the templatesIt skips files that already exist (so it's safe to re-run), creates parent
directories, and warns if a tracked *.example has no destination mapped yet —
add new templates to the MAP table near the top of the script.
Home Manager never overwrites files it didn't create. If ~/.zshrc,
~/.config/..., etc. already exist, switch aborts with an "in the way"
error instead of clobbering them. Let HM move the conflicts aside as it links:
home-manager switch -b backup --flake .#<host>-b backup renames each existing file to <name>.backup before linking, so
nothing is lost — diff or delete the .backup files afterwards.
Packages (Homebrew / apt) are left untouched — HM installs its own into the
Nix profile; both can coexist on PATH. Remove the old ones later if you want.
Once a machine is on Home Manager, the dotfiles in $HOME are read-only
symlinks into /nix/store — you can't edit them in place. The workflow is
always: edit the source in this repo, then re-activate.
# 1. edit either:
# - a .nix module under home/ (e.g. add a package to home/packages.nix)
# - or a referenced config file (home/yazi/theme.toml, home/starship.toml, …)
# 2. apply it:
home-manager switch --flake .#<host> # host: osx | wsl | debian | pi | workUseful commands:
nix flake check # validate the config without applying it
nix flake update # bump nixpkgs / home-manager, rewrites flake.lock
home-manager generations # list past builds; roll back by running an older one's activate scriptCommit
flake.lockafter the firstswitch. It pins exact package versions so every machine builds an identical environment; without it, each machine resolvesnixpkgsto whatever is current that day.
Mental model (for the Nix-unfamiliar):
flake.nixlists the pinned inputs and names the host configs; thehome/*.nixfiles declare what you want (packages, programs, settings);switchmakes your$HOMEmatch that declaration. You describe the end state — Nix works out the steps. Editing a.nixfile changes nothing until you runswitchagain.
<prefix>f opens a session-finder menu whose entries (key → directories) come
from a TOML config. It uses a default + optional override model:
- Default —
~/.config/tmux/sessionizer.toml.exampleis shipped by Home Manager (read-only, fromhome/tmux-sessionizer.toml.example). The menu falls back to it when no override exists, so<prefix>fworks out of the box. - Override —
~/.config/tmux/sessionizer.toml, if present, takes precedence. It is not Nix-managed (machine-local, likelocal.nix), so it's yours to create and edit freely.
To customize, create the override and edit it. Either run the convenience script (see below) or copy the example by hand:
./copy-examples.sh # creates it if missing
# …or manually:
cp ~/.config/tmux/sessionizer.toml.example ~/.config/tmux/sessionizer.toml
$EDITOR ~/.config/tmux/sessionizer.tomlThe menu reads the file fresh on every <prefix>f keypress, so edits to your
override are live — no home-manager switch, no tmux reload. (Changing the
shipped default in home/tmux-sessionizer.toml.example still needs a switch.)
Home Manager owns ~/.config/git/config (read-only symlink into the store), but
your user.name / user.email are deliberately not declared in Nix. The
managed config ends with [include] path = ~/.config/git/config.local, and that
local file is yours to create and edit freely — no local.nix, no
home-manager switch. Git silently ignores it when absent, so a fresh machine
still works.
Set or change your identity any time with:
git config -f ~/.config/git/config.local user.name "Your Name"
git config -f ~/.config/git/config.local user.email "you@example.com"Verify where it resolves from with git config --show-origin --get user.email.
A quick reference for everything declared across the home/*.nix modules, grouped by purpose.
| Tool | Alias | What it does |
|---|---|---|
| aoe (agent-of-empires) | aoe |
TUI for running multiple AI coding agents in parallel across git branches. Custom pastel-rainbow theme shipped in this repo. |
| tokscale | toks |
Tracks token usage across agentic coding tools (Claude Code, OpenCode, etc.). Supports monthly/hourly reports, a TUI, and a social submission mode. |
| openai-whisper | whisper |
Local speech-to-text transcription. |
| copilot-sessions | .local/bin |
Shell helper for managing GitHub Copilot CLI sessions. |
Neovim (pinned to 0.12.0 via a separate nixpkgs input — see flake.nix). The binary comes from Nix; the config does not — ~/.config/nvim is a live symlink to ~/git/init.lua, so edits there take effect immediately with no rebuild. Aliases: vim, vi.
LSP servers installed alongside it:
| Server | Language |
|---|---|
lua-language-server |
Lua |
pyright |
Python |
bash-language-server |
Bash / Zsh |
marksman |
Markdown |
clangd (via clang-tools) |
C / C++ (forced to C++23 via ~/.config/clangd/config.yaml) |
rust-analyzer |
Rust |
Formatters: stylua, black, isort, prettier, mdformat.
| Tool | Notes |
|---|---|
| zsh | vi-mode, fzf-tab completion, 100k history, emacs-in-insert keybindings (^A/^E/^R…) |
| starship | Prompt — config at home/starship.toml |
| fzf | Fuzzy finder — ^R history, ^T file, ALT-C dir; unified nav keys across all pickers |
| fzf-tab | Replaces zsh's Tab completion menu with fzf |
| zoxide | Smart cd that learns jump targets; --cmd cd shadows the builtin; cdi for interactive picker |
| Tool | Alias | Notes |
|---|---|---|
| lazygit | lg |
TUI for git — pastel-rainbow theme |
| delta | diff |
Syntax-highlighted diffs and git pager; Coldark-Dark syntax theme |
| gh (GitHub CLI) | gh |
Auth + API; gh co = gh pr checkout |
| gh-dash | gh dash |
TUI dashboard for PRs and issues across repos |
| gh-notify | gh notify |
fzf TUI for GitHub notifications |
yazi — terminal file manager with previews. Launched via the y wrapper (returns to the last directory on exit). Preview dependencies installed alongside it: ffmpeg, jq, poppler-utils, _7zz, resvg, imagemagick, chafa.
| Alias | Tool | Replaces |
|---|---|---|
ls, l, ll, la, tree |
eza | ls — icons, git status, pastel-rainbow theme |
cat |
bat | cat — syntax highlighting, Coldark-Dark theme |
du |
dust | du — disk-usage tree |
| (interactive) | dua | du — interactive disk-usage analyzer |
df |
duf | df — filesystem usage |
ps |
procs | ps — process listing |
watch |
viddy | watch — live command output |
diff |
delta | diff — syntax-highlighted diffs |
cd |
zoxide | cd — smart jump (learns from usage) |
| — | fd | find (not aliased — different CLI) |
| — | ripgrep (rg) |
grep (not aliased — different CLI) |
| — | tealdeer (tldr) |
man (not aliased — different CLI) |
| Tool | Notes |
|---|---|
| btop | top replacement — custom pastel-rainbow theme, proc tree, per-core CPU |
| fastfetch | System info banner |
| macchina | Lightweight system info |
| hyfetch | Pride-flag system info banner |
| colima | Docker/container runtime for macOS (lightweight alternative to Docker Desktop) |
| Tool | Notes |
|---|---|
| tailscale | Mesh VPN — remote access between machines (node love at 100.73.134.15) |
| nmap | Port scanner |
| curl | HTTP client |
| dig | DNS lookups |
| mtr | Traceroute + ping combined |
- Node.js 22 (
node,npm,npx) — replaces the old Homebrew nvm lazy-load - Rust (
rustc,cargo,rustfmt,clippy,rust-analyzer) - Clang / C++ (
clang,clang++with-std=c++20alias,clangd,cmake) - Python 3 (
python,pipaliases); uv for fast package/project management - tree-sitter CLI — used by nvim-treesitter to compile parsers
| Script | Notes |
|---|---|
| clipd | Daemon that polls pbpaste (macOS) or Wayland clipboard and stores history under ~/.local/share/cliph/. Runs as a launchd agent on macOS; auto-started from zshrc on Linux/Wayland. |
| cliph | fzf picker over clipboard history — bound to ^Y in zsh insert-mode and prefix+y in tmux. |
| Script | Notes |
|---|---|
tmux-sessionizer |
prefix+f — fzf menu to create/switch tmux sessions by project dir (config: ~/.config/tmux/sessionizer.toml) |
tmux-launcher |
prefix+g — quick-launch menu for common commands in new windows/panes |
tmux-sessionizer-menu |
display-menu variant of the sessionizer |
tmux-rainbow |
Renders the sine-wave pastel-rainbow gradient in the tmux status bar |
tmux-agent-monitor |
Monitors AI agent panes and alerts on completion/errors |
tmux-ssh-menu |
prefix+s — fzf menu for SSH connections |
tmux-remote-shell |
Opens a remote shell in a new tmux split via SSH |
tmux-resurrect-prune |
Prunes old tmux-resurrect save files |
tmux-continuum-ensure-hook |
Ensures continuum save hooks are registered |
tmux-conf-info |
Prints a summary of active tmux configuration |
rainbow-prompt |
Generates the starship custom module gradient (called by starship.toml) |
taskfzf |
fzf interface for Taskwarrior tasks |
clipd / cliph |
Clipboard history daemon + picker (see Clipboard above) |
copilot-sessions |
GitHub Copilot CLI session manager |
install-tailscaled-daemon |
One-shot script to install the tailscale daemon service |
wsl-sync-dns |
Syncs WSL /etc/resolv.conf with the Windows DNS config |
fix-sudo-path |
(Linux) Adds Nix bin paths to sudo's secure_path (via an /etc/sudoers.d/nix-path drop-in) so Nix-installed tools work under sudo |
enable-wake-on-lan |
Enables Wake-on-LAN on the active network interface |
rom-claude-mem |
Standalone /memory picker for Claude Code — edit user/project CLAUDE.md or open the auto-memory folder outside the REPL |
install-sshd-daemon |
(Linux) Sets up the openssh daemon as a user service |