Update the interactive-shell README and keybindings reference for changes made after the initial docs commit: no scheduled GC (manual only), NO_TMUX escape hatch, default-terminal tmux-256color + truecolor, the JetBrainsMono Nerd Font (new Fonts section + iTerm2 caveat), the UseKeychain IgnoreUnknown guard, and the vim-tmux-navigator (Ctrl-hjkl) + resurrect save/restore tmux bindings. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Interactive shell environment
Everything the shell, terminal multiplexer, git and ssh do beyond their defaults, and where each is defined. All of it is managed declaratively through home-manager — edit the listed file and rebuild, never the generated dotfiles.
Keyboard shortcuts have their own reference: KEYBINDINGS.md.
| Area | Defined in |
|---|---|
| zsh, CLI tools, tmux, ssh, auto-tmux | shell.nix |
| git (+ delta, commitizen) | git.nix |
| vim | editor.nix |
| GUI apps, GTK/Firefox theming, cursor | desktop.nix (graphical hosts only) |
Shared by every host via default.nix; the work box also layers
../../system/modules/work/default.nix
on top (work email, its own ssh config, extra packages).
zsh
| Feature | Notes |
|---|---|
| oh-my-zsh | plugins git, man, sudo (Esc-Esc to prepend sudo), colored-man-pages, extract; theme robbyrussell |
| Autosuggestion | fish-style history suggestions as you type (→ to accept) |
| Syntax highlighting | commands coloured by validity as you type |
| Completion | menu completion; the dump is rebuilt on every activation (see Maintenance) |
| History | 100k in-memory/on-disk, deduped, space-prefixed commands ignored, timestamped, shared live across sessions |
| History substring search | type a fragment, then ↑/↓ cycles matching past commands — works in foot, iTerm2 and the Linux TTY (both CSI and SS3 arrow encodings bound) |
| Prompt | hostname is prefixed when over SSH |
Aliases: ls/ll/la/lt → eza (icons + git), cls → clear. git aliases live in git.nix (below).
CLI tools
| Tool | What it gives you |
|---|---|
fzf |
Ctrl-R fuzzy history, Ctrl-T file picker, Alt-C fuzzy cd |
zoxide |
z <fragment> jumps to frecent directories |
direnv + nix-direnv |
per-project environments auto-loaded on cd (cached Nix dev shells) |
eza |
modern ls (drives the ls aliases) |
bat |
syntax-highlighting pager; behaves like cat when piped |
nix-index |
command-not-found: an unknown command tells you which Nix package provides it (prebuilt DB, no manual indexing) |
comma (,) |
run an uninstalled program once: , cowsay hi |
nh |
nicer nixos-rebuild/home-manager with diffs; $NH_FLAKE set to the repo. No scheduled GC (it could reap paths a running generation still references) — collect garbage manually with nh clean all / nix-collect-garbage -d |
tmux
Auto-start: opening any interactive terminal — foot, iTerm2, the WSL shell, the
Linux console — drops you straight into a tmux session named main (attach if it
exists, else create). Panes run a plain non-login zsh. It deliberately does not
fire for SSH sessions, VS Code's integrated terminal, already-inside-tmux, or
non-interactive shells. Escape hatch: NO_TMUX=1 <terminal> opens a bare shell.
| Setting | Value |
|---|---|
| Mode keys | vi |
| Mouse | on |
| Scrollback | 500000 lines |
escape-time |
10ms (the 500ms default lagged vim's ESC) |
focus-events |
on (vim autoread) |
base-index / pane-base-index |
1 |
| Splits | prefix s vertical, prefix v horizontal (stock %/" unbound) |
| Pane nav | Alt+arrows (no prefix) |
| Terminal | default-terminal tmux-256color; truecolor advertised per outer terminal (foot*, xterm-256color/iTerm2) via terminal-features … RGB |
| Clipboard | set-clipboard on; foot terminal-features advertise truecolor/sync/OSC52/title/cursor |
Plugins: sensible, vim-tmux-navigator (Ctrl-h/j/k/l across vim ↔ tmux),
yank, catppuccin (Mocha statusline), resurrect + continuum
(sessions auto-save and restore across reboots). The statusline draws Nerd-Font
glyphs — see Fonts.
Fonts
JetBrainsMono Nerd Font is installed on every host (in common-nixos.nix,
because tmux runs everywhere; the Mac installs it to /Library/Fonts via the
Darwin config). foot uses it as its main font automatically. iTerm2's font is a
GUI setting — set it to JetBrainsMono Nerd Font (Settings → Profiles → Text →
Font) so the tmux statusline glyphs render instead of ?.
git
Pager is delta. commitizen is installed on every host; cz defaults to
Conventional Commits.
| Aliases | |
|---|---|
st co sw br ci |
status / checkout / switch / branch / commit |
last unstage |
last commit / unstage |
lg |
graph log, all branches |
cz cc |
git cz <sub> (e.g. git cz c) and git cc → commitizen prompt |
| Behaviour | |
|---|---|
| Pulls | rebase, with autostash + autosquash |
| Fetch | prune deleted remote branches |
| Conflicts | zdiff3 (shows the common ancestor) |
| Diffs | histogram algorithm, colour-moved |
rerere |
remembers + replays conflict resolutions |
| Commit editor | full diff shown (commit.verbose) |
| Misc | branches sorted by date, column.ui = auto, help.autocorrect = prompt, push.autoSetupRemote |
| Global ignores | result, result-*, .direnv, *.swp, .DS_Store |
| Signing | SSH commit + tag signing (mkDefault, so a host without the key in its agent can disable it). Personal email iam@emmathe.dev; the work box overrides email + signing. |
ssh
| Feature | Notes |
|---|---|
| ssh-agent | runs on Linux (launchd on macOS); keys added on first use so the passphrase is typed once per login session — this also feeds git commit signing |
| macOS | UseKeychain caches the passphrase in the login keychain (guarded by IgnoreUnknown, so a non-Apple ssh skips it instead of erroring) |
| Gitea remote | code.emmathe.dev → HostName 10.187.1.76 (DNS-override), Port 30009, user git, dedicated key, identitiesOnly |
| Defaults | the module's deprecated default block is opted out; equivalents kept under settings."*" |
The work box keeps its own ~/.ssh/config (home-manager's programs.ssh is
forced off there) but still runs the agent.
Maintenance behaviours
- zcompdump reset —
~/.zcompdump*is removed on every activation, so a stale dump (pointing at/nix/storepaths a rebuild or a manual GC removed) can't break completion with_git: function definition file not found. - GC — no scheduled timer; collect garbage deliberately (
nh clean all/nix-collect-garbage -d) when no important session is running.
Per-host differences
| Personal Linux (sway) | macOS | Work WSL (EDaaS) | |
|---|---|---|---|
| Auto-tmux | yes (foot/TTY) | yes (iTerm2) | yes (WSL shell) |
| git email | iam@emmathe.dev |
iam@emmathe.dev |
…@citrix.com (work) |
| ssh config managed | yes | yes | no (keeps corporate config) |
| ssh-agent | yes | launchd | yes (work module) |
| GUI / theming (desktop.nix) | yes | no | no |