|
| 1 | +# 29. tmux local config overrides |
| 2 | + |
| 3 | +Date: 2026-04-03 |
| 4 | + |
| 5 | +## Status |
| 6 | + |
| 7 | +Accepted |
| 8 | + |
| 9 | +## Context |
| 10 | + |
| 11 | +The same dotfiles get deployed to multiple machines (personal laptop, work machines, remote servers), and sometimes tmux needs to look or behave differently depending on where it's running. The motivating case: using a different catppuccin flavor on a remote server so SSH tabs are visually distinct from local ones at a glance. |
| 12 | + |
| 13 | +Git config already solves this with `.gitconfig.local` (generated per-machine, never committed). SSH config uses `config.d/` fragments. tmux had no equivalent, so any per-machine customization meant either maintaining forks of `.tmux.conf` or just not doing it. |
| 14 | + |
| 15 | +## Decision |
| 16 | + |
| 17 | +Source `~/.tmux.local.conf` at the very end of `.tmux.conf`, guarded by an existence check: |
| 18 | + |
| 19 | +```tmux |
| 20 | +if-shell '[ -f ~/.tmux.local.conf ]' 'source-file ~/.tmux.local.conf' |
| 21 | +``` |
| 22 | + |
| 23 | +It loads last so it can override anything: theme flavor, status bar layout, keybindings, plugin options. |
| 24 | + |
| 25 | +The file is not committed to the dotfiles repo. Each machine creates its own (or doesn't, and gets the defaults). |
| 26 | + |
| 27 | +### Why at the end? |
| 28 | + |
| 29 | +Catppuccin's tmux plugin reads `@catppuccin_flavor` at plugin init time, but `source-file` after TPM init can still override computed styles and status bar config. For theme flavor changes to take full effect, a `tmux source ~/.tmux.conf` reload is needed (same as any config change). |
| 30 | + |
| 31 | +### Alternatives Considered |
| 32 | + |
| 33 | +1. **Conditional logic in .tmux.conf based on hostname** |
| 34 | + - `if-shell '[ "$(hostname)" = "myserver" ]' 'set ...'` |
| 35 | + - Rejected: puts machine-specific knowledge in the committed config. Grows into a mess. |
| 36 | + |
| 37 | +2. **Separate .tmux.conf per machine** |
| 38 | + - Rejected: duplication. The configs are 95% identical. |
| 39 | + |
| 40 | +3. **Environment variable toggles** |
| 41 | + - `if-shell '[ "$TMUX_THEME" = "frappe" ]' 'set ...'` |
| 42 | + - Not bad, but requires setting env vars in shell config, which is another layer of indirection. The local file is more self-contained. |
| 43 | + |
| 44 | +## Consequences |
| 45 | + |
| 46 | +### Positive |
| 47 | + |
| 48 | +- Per-machine tmux customization without forking or branching the config |
| 49 | +- Follows the same `.local` pattern as gitconfig, so it's a familiar convention |
| 50 | +- Zero impact on machines that don't create the file |
| 51 | + |
| 52 | +### Negative |
| 53 | + |
| 54 | +- The local file isn't tracked anywhere, so it's on you to remember what you set. (But that's true of `.gitconfig.local` too, and it's been fine.) |
| 55 | +- Theme flavor overrides after TPM init may not apply 100% cleanly without a reload. In practice this is fine since you reload after editing config anyway. |
0 commit comments