17 KiB
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 |
| Neovim (nixvim) + LSP | 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
work.nix on top (work email, its own ssh config, extra packages,
and the C#/Helm language servers).
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; file stays at ~/.zsh_history |
| Dotfiles location | dotDir is ~/.config/zsh (XDG) — .zshrc/.zshenv/.zcompdump live there; ~/.zshenv only bootstraps $ZDOTDIR |
| 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 (Catppuccin-themed) |
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 (Catppuccin Mocha theme); behaves like cat when piped; also the MANPAGER |
ripgrep / fd |
fast search (rg) and find (fd); also back fzf |
jq / btop |
JSON processor; resource monitor |
gh / tea |
GitHub and Gitea (code.emmathe.dev) CLIs; gh uses SSH |
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 |
Theming: fzf, bat and git's delta pager are all Catppuccin Mocha,
driven from the shared ../catppuccin-mocha.nix palette / the catppuccin/bat
theme.
Env & defaults: xdg.enable on; PAGER/MANPAGER (bat) set in default.nix
(the editor owns $EDITOR/$VISUAL); xdg.mimeApps maps web→Firefox,
directories→nemo (desktop.nix).
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 ?.
Editor (Neovim)
nvim — aliased to vi/vim, and set as $EDITOR/$VISUAL — is configured
declaratively with nixvim, so the same plugins and config are baked in on
every host. Migrated from plain vim; the practical gain is a real LSP stack in
place of the old (inert) ALE.
| Feature | Notes |
|---|---|
| Colorscheme | Catppuccin Mocha (matches the terminal and the rest of the desktop) |
| File tree | nvim-tree, toggled with ,, (comma twice; was nerdtree) |
| Indent guides | indent-blankline, on by default (was vim-indent-guides) |
| Git | fugitive (:Git …) |
| Pane nav | vim-tmux-navigator — Ctrl+h/j/k/l moves across vim splits and tmux panes |
| Syntax | tree-sitter (nix, lua, bash, markdown, groovy) — replaces syntax enable |
| LSP | nvim-cmp completion + servers nil (Nix), lua_ls, pyright (Python), terraformls |
| Indentation | 2-wide hard tabs (noexpandtab, tabstop/shiftwidth = 2); line numbers on |
| Filetypes | *Jenkinsfile → groovy |
Leader is Space. LSP keymaps (gd, gr, K, <leader>rn, <leader>ca) and
the file-tree toggle are listed in
KEYBINDINGS.md. Add a universal language server by
enabling it under programs.nixvim.plugins.lsp.servers in editor.nix;
host-specific ones go in that host's module — the work box (work.nix) adds
omnisharp (C#) and helm_ls (Helm), kept off the personal machines.
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 —
~/.config/zsh/.zcompdump*(plus legacy~/.zcompdump*and the cache copy) 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 |