this is just so impressively ugly i wanted to share this with you guys.
you know how vim can determine background color under any properly functioning terminal, so it can set bg=dark
automatically? well, this doesn’t work out of the box under tmux, but luckily it’s an easy fix:
if exists("$TMUX")
let &t_RB = "\ePtmux;\e\e]11;?\007\e\\"
endif
this means we wrap the query into a DCS passthrough sequence \ePtmux;PAYLOAD\e\\
, so tmux would pass it to the outer terminal. this is documented everywhere and it old news. now, what if we have nested tmuxes? this is where things get ugly:
if exists("$TMUX")
if exists("$SSH_CONNECTION")
let &t_RB = "\ePtmux;\e\ePtmux;\e\e\e\e]11;?\007\e\e\\\\\e\\"
else
let &t_RB = "\ePtmux;\e\e]11;?\007\e\\"
endif
endif
note double-escaping of all \e
s in the encapsulated escaped sequence. this took me a while to figure out. try to imagine how this would look under three tmuxes.
i’m assuming here for simplicity that all ssh connections are going from under tmux, i guess we could also SendEnv/AcceptEnv
a custom environment variable or something if host terminal has tmux running, but it’s too much effort.
now, what about bash and setting window title with prompt command? the horrors never cease:
case "$TERM" in
screen*)
if [ -n "$TMUX" ]; then
if [ -n "$SSH_CONNECTION" ]; then
PROMPT_COMMAND='echo -ne "\ePtmux;\e\ePtmux;\e\e\e\e]0;${USER}@${HOSTNAME}: ${PWD}\007\e\e\\\\\e\\"'
else
PROMPT_COMMAND='echo -ne "\ePtmux;\e\e]0;${USER}@${HOSTNAME}: ${PWD}\007\e\\"'
fi
else
PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'
fi
;;
xterm*|rxvt*)
PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'
;;
esac
again, imagine how this would look under three tmuxes, what with quadruple-escaped \e
s in the payload.
anyway, this was one way shell communication to the outer terminal, where we don’t need to wait for a reply, but what if we wanted to?
not only we can do it, we can also not rely on assumptions about ssh connections - at a cost of a slight delay while multiple terminal queries are being sent - while doing so, like this:
oldstty=$(stty -g)
stty raw -echo min 0 time 0
if [ -n "$TMUX" ]; then
printf "\ePtmux;\e\e]11;?\007\e\\"
sleep 0.05
read -r answer
result=${answer#*;}
# nested tmux
if [ -z $result ]; then
printf "\ePtmux;\e\ePtmux;\e\e\e\e]11;?\007\e\e\\\\\e\\"
sleep 0.05
read -r answer
result=${answer#*;}
fi
else
printf "\e]11;?\007"
sleep 0.01
read -r answer
result=${answer#*;}
fi
stty $oldstty
if [ -n "$result" ]; then
RGBVAL=$(( 0x$(echo $result | sed 's/[^rgb:0-9a-f/]\+$//' | cut -c 15-16) ))
# the threshold here is arbitrary i guess, and this method won't work on all background colors
if [ $RGBVAL -le 100 ]; then
echo terminal background is dark
else
echo terminal background is light
fi
fi