all repos — dot @ b0714511e8557686cda9e0551324fd273a97e9b1

Shell, editor and terminal configuration, and the tools that go with them

profile: stop shadowing exit

`exit` was a function that ran `tmux detach` instead of exiting, whenever a
shell was interactive and inside tmux. What it bought was a keystroke: tmux
already binds detach to prefix-d, which this config does not touch.

What it cost was an afternoon. Claude Code captures shell functions into a
snapshot and sources it in every tool call, so agent shells inheriting $TMUX
ran the function too: terminal windows closed on their own for weeks before
anyone connected it to `exit`, and a poll loop that called `exit 0` detached a
client every minute instead of stopping, because the function detached and then
returned. The call-time guard added on 2026-07-16 fixed that case; it did not
make shadowing a POSIX builtin a good idea.

Nothing in either repo calls it and nothing documents the behaviour.
Igor Soarez igor@soarez.org
Fri, 25 Sep 2026 13:49:05 +0300
commit

b0714511e8557686cda9e0551324fd273a97e9b1

parent

ed21d1270007a8f9cbaa2ca7da0fee1eefeb405f

1 files changed, 0 insertions(+), 11 deletions(-)

jump to
M config/profile → config/profile

@@ -109,17 +109,6 @@ # SAVEHIST is read by zsh itself, which shellcheck can't lint for.

# shellcheck disable=SC2034 SAVEHIST=1000000 -# detach from tmux by default -# Guard at call time, not definition time. -# functions and sources them in non-interactive tool shells that inherit -# $TMUX, where a bare `exit` must really exit (not detach the terminal). -exit() { - if [[ -n "${TMUX:-}" ]] && [[ $- == *i* ]]; then - tmux detach - else - builtin exit "$@" - fi -} exists() { command -v "$1" >/dev/null 2>&1; } # Check if command exists (is in path). lspath() { echo "$PATH" | tr ':' '\n'; } # list PATH entries pathadd() { [[ -d "$1" ]] && PATH="$1"$(echo ":$PATH:" | sed "s|:$1:|:|" | sed 's|:$||'); }