4

I'm using Emacs in a terminal and am finding that when the TERM environment variable is changed between screen-256color and xterm-256color, the default colors within Emacs are set differently.

Just to be clear, I'm getting full 256 bit color support in both situations (running with byobu/tmux and running with Gnome Terminal respectively), but Emacs is applying different colors such that when I look at the same Python file, the syntax highlighting uses differ colors in each. When I manually change the colors using color-theme-select to the same theme, they then use the same colors. The problem is that I have no idea how the colors are set to begin with, and more importantly, why they are set differently.

This behavior remains constant when I force byobu to use TERM=xterm-256color, so it doesn't seem like this is a problem with either of the terminal emulators.

How can I ensure that Emacs uses the same colors in each situation?

3 Answers 3

4

The problem is that I have no idea how the colors are set to begin with, and more importantly, why they are set differently.

Perhaps this discussion on StackOverflow is relevant - some detailed answers on what's going on.


My case was the way emacs detects background color. It has a fallback for xterm-*, but not screen-*, and was using black background whereas it's actually white (don't judge).

A workaround is given in the linked answer, too - setting the correct background color manually (as compared to telling emacs "lies" by changing TERM), by evaluating (Alt+x eval, or Alt+:) the following:

(let ((frame-background-mode 'light)) (frame-set-background-mode nil))
2

I'm hardly an expert on this, but I believe that this isn't necessarily related to Emacs but rather with the terminal capabilities.

E.g., you can see the various terminal capabilities with infocmp -I -r -T xterm-256color and infocmp -I -r -T screen-256color. I did a quick comparison between them and noted that xterm-256color has a significant amount of more capabilities.

After some guesswork, I believe that what happens is that Emacs finds the initc capabilitiy and uses it to provide more shades of a particular color for the default theme. See for instance this question:

https://stackoverflow.com/questions/2814478/how-can-i-output-different-shades-of-green-to-the-terminal

I'm not sure you can entirely control this behaviour from Emacs, but as you noted you can use color-theme-select to change the behaviour. A temporary fix could be to simply use (load-theme "theme" t) in your .emacs to force the theme you had in mind.

Another option could be to manually set the TERMINFO or TERMCAP environment variables to point to a file with the appropriate terminal capabilities.

E.g., you could do:

export TERMINFO="$HOME/.terminfo"
infocmp -I -r -T xterm-256color > $TERMINFO

or

export TERMCAP="$HOME/.termcap"
infocmp -C -r -T xterm-256color > $TERMCAP

This forces Emacs to use the terminal capabilities you had in mind. It may also have other side-effects but I haven't seen any yet.

I don't know why tmux/byobu seems to ignore forcing TERM as you describe. In tmux however, I know that you can use set-option -g xterm-256color to force the terminal to use. I don't know about byobu however.

4
  • Ah now that's interesting about xterm-256color having more capabilities. The strange this is that it doesn't really match what I'm seeing color-wise. When I play around with all the various color palettes in my terminal emulator (Guake), Emacs running with screen-256color responds much more dynamically than Emacs running under xterm-256color. There's just way less variation in the look of the palettes in the latter case. So much so that half of them look the same. So appearance wise, it almost looks like screen-256color yields more capabilities.
    – nedned
    Feb 24, 2016 at 13:38
  • Oh it wasn't that byobu was ignoring TERM. I was trying to say that when I set TERM to xterm-256color byobu does indeed honor it, and also displays the same colors I'm seeing for that value of TERM in other non-screen-like terminals. Which tells us it's not byobu doing something weird.
    – nedned
    Feb 24, 2016 at 13:45
  • One more addition: the colors are looking constant across the two for parts of the terminal that are not running Emacs. Perhaps, as you suggest, this has to do with how Emacs is initializing the colours when TERM is xterm-256color. Quite frankly, unless I have a weird setup, it looks like it's doing it wrong. I've loaded emacs without my init file and it still does it though.
    – nedned
    Feb 24, 2016 at 13:50
  • Afraid I can't give a complete answer. I had a (very) brief look in the Emacs source (src/term.c) and it seems to be doing different things depending on these capabilities, so that's probably what's happening.
    – Xaldew
    Feb 24, 2016 at 15:33
0

Emacs contains special code in lisp/term/xterm.el that runs when TERM starts with "xterm". This appears to be responsible for enabling the extra colours.

Emacs 26 and later have specific support for tmux, which builds on xterm.el to enable 256 colours correctly for me.

With Emacs 25.1, I was able to make 256 colour mode work in tmux even with TERM=tmux-256color if I added the following to my Emacs startup to run the xterm initialisation explicitly:

(if (version< emacs-version "26")                                                                                                                                                                                  
    (if (equal (getenv "TERM") "tmux-256color")                                                                                                                                                                    
        (progn (load-library "term/xterm")                                                                                                                                                                      
               (terminal-init-xterm))))    

The version check ensures that this code does nothing when running Emacs 26.1 or later.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.