#{client_tty} is what I needed, thanks.
I'm new to tmux and I'm experimenting with shell/terminal integration through shell functions and tmux hooks.
Some more background.
On the local host I configured iTerm2 with the "Compact" theme, which does not display the window title bar.
Then I set up the iTerm2 status bar with a couple of "Interpolated string" components set to "\(user.left_title) [Spring] \(user.right_title)".
On the remote host:
1. I defined a shell function iterm2_update_status in .bashrc in order to trigger the iTerm2 status bar update through the bash variable PROMPT_COMMAND.
if [[ -n "$SSH_TTY" ]]; then
_loc="🌍"
else
_loc="🖥️ "
fi
# cache to avoid useless updates
ITERM2_LAST_LEFT=""
ITERM2_LAST_RIGHT=""
iterm2_update_status() {
# Left title
local left="${_loc}CWD: ${PWD/$HOME/\~}"
# Right title: conda env and/or number of loaded modules
local right=""
[[ -n "${CONDA_DEFAULT_ENV}" ]] && right+="conda: ${CONDA_DEFAULT_ENV} "
[[ -n "${LOADEDMODULES}" ]] && right+="mods: $(echo ${LOADEDMODULES//:/" "} | wc -w) "
# number of jobs in background
local njobs
njobs=$(jobs -p 2>/dev/null | wc -l)
(( ${njobs} > 0 )) && right+="jobs: ${njobs}"
# final trim
right="${right%" "}"
# Update only when left OR right title change
[[ "${left}" == "${ITERM2_LAST_LEFT}" && "${right}" == "${ITERM2_LAST_RIGHT}" ]] && return
ITERM2_LAST_LEFT="${left}"
ITERM2_LAST_RIGHT="${right}"
# Encode for iTerm2
local left_encoded right_encoded
left_encoded=$(echo -n "${left}" | base64 -w0)
right_encoded=$(echo -n "${right}" | base64 -w0)
# Send OSC to the remote iTerm2, through tmux passthrough DCS if needed
if [[ -n "${TMUX}" ]]; then
local dcs
dcs="\033Ptmux;\033\033]1337;SetUserVar=left_title=${left_encoded}\a\033\033]1337;SetUserVar=right_title=${right_encoded}\a\033\\"
printf "%b" "${dcs}"
# Save the DCS to current pane status_bar variable
pane_id=$(tmux display-message -p '#{client_session}:#{window_id}.#{pane_id}')
tmux set-option -pq -t "${pane_id}" @status_bar "${dcs}"
else
local osc
osc="\033]1337;SetUserVar=left_title=${left_encoded}\a\033]1337;SetUserVar=right_title=${right_encoded}\a"
printf "%b" "${osc}"
fi
}
if [ "${REMOTE_TERM}" == "iTerm2" ]; then
PROMPT_COMMAND="${PROMPT_COMMAND};iterm2_update_status"
fi
2. Finally, I set up the following hooks in the remote .tmux.conf:
# Hooks to update the remote iTerm2 status bar whenever a pane/window switch occurs
set-hook -g after-select-window 'run-shell "printf '\''%b'\'' \"\$(tmux show-option -pqv -t #{pane_id} @status_bar)\" > #{client_tty}"'
set-hook -g after-select-pane 'run-shell "printf '\''%b'\'' \"\$(tmux show-option -pqv -t #{pane_id} @status_bar)\" > #{client_tty}"'
set-hook -g pane-focus-in 'run-shell "printf '\''%b'\'' \"\$(tmux show-option -pqv -t #{pane_id} @status_bar)\" > #{client_tty}"'
Now the local iTerm2 status bar is updated whenever I switch pane or window in the remote tmux session.
pgf