zsh: set TERM=screen-256color in tmux, but xterm-256color without tmux

48,848

Solution 1

The TERM environment variable should be set by the application that is acting as your terminal. This is the whole point of the thing: letting programs running inside them know what terminal is being used and hence what sort of features it supports.

Zsh is not a terminal. It is a shell. It might care what your TERM is set to if it wants to do special things, but it should not be responsible for setting it. Instead it is responsible for setting variables such as ZSH_VERSION which can be used by scripts or other child processes to understand what behavior to expect from their parent shell.

Instead, you need to check the configuration for whatever terminal application you are using and ask it to report itself properly. For example you can do this for xterm by adding this line to the ~/.Xdefaults file it uses for configuration values:

xterm*termName: xterm-256color

It appears gnome-terminal does the idiotic thing of reading what your xterm configuration would be instead of having it's own. This might get you by in some cases but is should more properly be set to vte-256color. This appears to be a long standing gripe against it (and some other VTE based terminal emulators). A common way to hack around this is exploit another value it does set:

if [ "$COLORTERM" = "gnome-terminal" ]; then
    export TERM=vte-256color
fi 

But this brings you back around to your problem with tmux, so you would have to account for that by not resetting TERM if it is already something like "screen-256color" or "screen":

if [ "$COLORTERM" = "gnome-terminal" -a "$TERM" =~ xterm.* ]; then
    export TERM=vte-256color
fi

For other terminals you will need to lookup their proper configuration routines.

Solution 2

Inside your .zshrc, put

[[ -n $TMUX ]] && export TERM="xterm-256color"

And, inside your .tmux.conf

set -g default-terminal "screen-256color"
Share:
48,848

Related videos on Youtube

Dmitry Frank
Author by

Dmitry Frank

I'm a passionate software engineer with strong background in low-level parts (MCU real-time kernels, C, Assembler), and experienced in higher-level technologies as well: Go, C++, JavaScript, and many others. Author of the well-formed and carefully tested real-time kernel for 16- and 32-bit MCUs: TNeo, which is now used by several companies. One of my hobby projects is a geeky bookmarking service written in Go and PostgreSQL: Geekmarks. Some of my articles: How I ended up writing a new real-time kernel How do JavaScript closures work under the hood Unit-testing (embedded) C applications with Ceedling Object-oriented techniques in C See more at dmitryfrank.com

Updated on September 18, 2022

Comments

  • Dmitry Frank
    Dmitry Frank over 1 year

    I need my $TERM to be xterm-256color outside of tmux (in "plain" terminal with zsh), but screen-256color inside tmux.

    First I tried:

    • add export TERM='xterm-256color' to my ~/.zshrc.
    • add set -g default-terminal "screen-256color" to my ~/.tmux.conf

    Now, when I open terminal (say, xterm), TERM is xterm-256color, which is correct. But when I run tmux, TERM is again xterm-256color!

    Then I tried to comment out line in my ~/.zshrc. Now, when I open terminal, TERM is xterm, and when I run tmux, TERM is screen-256color. So it seems if I set TERM in the .zshrc, tmux firstly sets TERM to screen-256color, runs shell (which is zsh), and zsh reads .zshrc and resets TERM to xterm-256color.

    So, how to make TERM to be xterm-256color in "plain" terminal, and screen-256color in tmux?

    • Stéphane Chazelas
      Stéphane Chazelas almost 10 years
      Set the TERM for xterm in the xterm configuration (X resources) and that for tmux in the tmux configuration. There's no reason you should do any of that in zsh.
    • Dmitry Frank
      Dmitry Frank almost 10 years
      Hmm, but I also use other terminal emulators: say, gnome-terminal and quake-style drop-down console "altyo" github.com/linvinus/AltYo , still can't find the way to set correct TERM in these terminals
    • Stéphane Chazelas
      Stéphane Chazelas almost 10 years
      Well those applications are responsible to set their TERM properly. For gnome-terminal, that should probably be gnome-256color... So it's those applications you need to configure properly, not zsh. The reason they use xterm is probably to avoid problems when sshing to machines that don't have the more specific terminfo entries. If you know you're only sshing to machines with an exhaustive terminfo database, then you can and should change that in the applications themselves.
    • Stéphane Chazelas
      Stéphane Chazelas almost 10 years
      And if you need to add a .zshrc kludge, IMO, that should be on machines that have incomplete terminfo databases (to replace xterm-256color with xterm if xterm-256color s not supported, though it would be even better to add those entries in our own ~/.terminfo database).
    • jdhao
      jdhao over 5 years
      We should set term in the terminal emulator, not in .zshrc. It is not the correct way.
    • Tom Hale
      Tom Hale over 5 years
      Note that screen-256color doesn't support italics, but xterm-256color does, so you won't be using the entire capabilities of your terminal. Why do you want to do this?
  • Stéphane Chazelas
    Stéphane Chazelas almost 10 years
    zsh is not responsible for setting $SHELL. login is responsible for setting it, and you are responsible to change that to something else if you want to tell applications (xterm, vi...) which shell you want as your prefered shell. zsh is responsible for setting $ZSH_VERSION and a few documented special shell variables, but it doesn't touch $SHELL.
  • tcoolspy
    tcoolspy almost 10 years
    @StéphaneChazelas That was sloppy of me, thanks for the correction.
  • Titou
    Titou about 7 years
    Or [[ $TMUX != "" ]] && export TERM="screen-256color" This way zsh will set TERM only if called within a tmux session
  • Mike Lippert
    Mike Lippert over 5 years
    Thanks for this, it made me look for how konsole set TERM rather than putting it in my bashrc. Found it set in the profile's General tab, Environment, changed it from xterm to xterm-256color
  • Elijah
    Elijah over 4 years
    worth noting that under my vanilla deb10 install GNOME Terminal reports truecolor instead of gnome-terminal for $COLORTERM and so the above detection mechanism may not work. XTERM does not appear to set this value at all, it may be valid to check for any value. this term type is partially discussed in this gist possibly elsewhere: gist.github.com/XVilka/8346728#true-color-detection