feat(tmux): auto-start in graphical terminals

Opening a terminal (foot) execs `tmux new-session -A -s main`, so every new
terminal lands in the multiplexer; panes run a plain non-login zsh. Guarded
to interactive, not-already-in-tmux, not-SSH, not-VS-Code, tmux-present --
preventing re-exec loops, hijacked scp/ssh shells, and lockout. Lives in the
graphical desktop layer, so the WSL work box keeps a plain shell.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Emma Thorpe
2026-06-10 11:08:49 +01:00
committed by lyrathorpe
parent 327c363232
commit 27fc7ae6d3
+22
View File
@@ -6,6 +6,7 @@
pkgs, pkgs,
config, config,
inputs, inputs,
lib,
username, username,
... ...
}: }:
@@ -95,4 +96,25 @@
}; };
}; };
}; };
# Auto-start tmux in graphical terminals (foot): opening a terminal drops
# straight into a session named "main" (attach if it exists, else create).
# Panes inside run a plain non-login zsh (tmux's default-command "${SHELL}").
# Order 200 runs this before oh-my-zsh/compinit so the exec replaces the shell
# before that setup is wasted. Guards (each prevents a real breakage):
# interactive only -> don't hijack scp/ssh-command/non-interactive shells
# $TMUX empty -> a pane's zsh won't re-exec tmux (infinite loop)
# not SSH -> don't force inbound SSH logins into a server tmux
# not VS Code -> its integrated terminal manages itself
# tmux on PATH -> exec failure would otherwise kill the login shell
# Lives here (graphical hosts only); the WSL work box never imports this.
programs.zsh.initContent = lib.mkOrder 200 ''
if [[ $- == *i* ]] \
&& [[ -z "$TMUX" ]] \
&& [[ -z "$SSH_CONNECTION" && -z "$SSH_TTY" ]] \
&& [[ "$TERM_PROGRAM" != "vscode" ]] \
&& command -v tmux >/dev/null 2>&1; then
exec tmux new-session -A -s main
fi
'';
} }