10

I am looking for a good way to have 24 bit color in emacs when using a graphical terminal emulator. Konsole, for example, does support escape codes for true color, as documented here: https://github.com/robertknight/konsole/blob/master/user-doc/README.moreColors

My problem is that I do not understand how emacs translates face information into escape sequences for the terminal. I also did not manage whether support for 24 bit color is present somewhere, or whether it is at all possible to implement it with emacs lisp. What I am asking for is a pointer to the relevant Emacs documentation or an informed opinion on whether having true color in terminal-emacs is feasible at the moment.

grep
  • 726
  • 7
  • 13

5 Answers5

19

This was recently included in emacs 26.1 (28 May 2018),

With this file: terminfo-24bit.src

# Use colon separators.
xterm-24bit|xterm with 24-bit direct color mode,
  use=xterm-256color,
  setb24=\E[48:2:%p1%{65536}%/%d:%p1%{256}%/%{255}%&%d:%p1%{255}%&%dm,
  setf24=\E[38:2:%p1%{65536}%/%d:%p1%{256}%/%{255}%&%d:%p1%{255}%&%dm,
# Use semicolon separators.
xterm-24bits|xterm with 24-bit direct color mode,
  use=xterm-256color,
  setb24=\E[48;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%d;%p1%{255}%&%dm,
  setf24=\E[38;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%d;%p1%{255}%&%dm,

Run:

tic -x -o ~/.terminfo terminfo-24bit.src

Now you can start emacs with truecolor.

TERM=xterm-24bit emacs -nw

See the faq: https://www.gnu.org/software/emacs/manual/html_node/efaq/Colors-on-a-TTY.html

Pridkett
  • 4,883
  • 4
  • 30
  • 47
ideasman42
  • 42,413
  • 44
  • 197
  • 320
3

AFAIK there is no built-in support for this, as 24bit color space in terminal is quite uncommon(!?). However, given that Emacs is open for you to add your own terminal support, you can try write a package similar to xterm-frobs.el.

BTW, if you only need good color theme in terminal, you can try my package https://github.com/tungd/color-theme-approximate that translates GUI color theme to terminal.

Community
  • 1
  • 1
tungd
  • 14,467
  • 5
  • 41
  • 45
  • 1
    Indeed, as far as I am aware of, only Konsole and (the Konsole-based) Yakuake support 24 bit colors. However this is not a big problem for me, as it is available on most machins on which I work. – grep Feb 04 '13 at 21:47
  • My original problem was that the reduction of the emacs colors to terminal colors (16 or 256 color) makes some faces extremely hard to read. And because I want to use a light and a dark color theme, manually tweaking the offending colors gets tricky. Your package looks promising, I will check it with my setup. – grep Feb 04 '13 at 21:55
1

There are 3 ways to enable 24-bit color in emacs:
(code is from emacs's term.c)

(Note: a simple way to test if colors are working is by checking M-x list-colors-display)

The correct method is to set TERM to a value which supports direct color (via the RGB terminfo capability), if one is available for your terminal (or just try xterm-direct).
These are generally named "(terminalName)-direct" (xterm-direct, vte-direct, etc.)
ex: TERM=xterm-direct emacs, or set TERM properly by configuring your terminal.

Edit: There is a flaw in the implementation of xterm-direct (and related). Certain shades of blue are treated as indexed colors (due to it using the same sequences for rgb and indexed color), and won't render correctly. I recommend using the second method.

/* Standard support for 24-bit colors.  */
else if (tigetflag ("RGB") > 0)
  {
    /* ...  */
    tty->TN_max_colors = 16777216;
  }

Another option is to use a terminfo file with the nonstandard terminfo capabilities setf24 and setb24 (see answer https://stackoverflow.com/a/50577683/6232794). It's possible that this method is supported in older versions of emacs than the other two

const char *fg = tigetstr ("setf24");
const char *bg = tigetstr ("setb24");
/* Non-standard support for 24-bit colors. */
if (fg && bg
    && fg != (char *) (intptr_t) -1
    && bg != (char *) (intptr_t) -1)
  {
    tty->TS_set_foreground = fg;
    tty->TS_set_background = bg;
    tty->TN_max_colors = 16777216;
  }

As a last resort hack, you can set the environment variable COLORTERM to "truecolor", which might work with your terminal.

/* Fall back to xterm+direct (semicolon version) if requested
   by the COLORTERM environment variable.  */
else if ((bg = getenv("COLORTERM")) != NULL
         && strcasecmp(bg, "truecolor") == 0)
  {
    tty->TS_set_foreground = "\033[%?%p1%{8}%<%t3%p1%d%e38;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%d;%p1%{255}%&%d%;m";
    tty->TS_set_background = "\033[%?%p1%{8}%<%t4%p1%d%e48;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%d;%p1%{255}%&%d%;m";
    tty->TN_max_colors = 16777216;
  }                                                                                                                  
12Me21
  • 992
  • 10
  • 22
0

It's feasible, but it can't be done in ELisp alone.

Here's a lovely list of patches to various versions of emacs and tmux to make trucolor life possible:

https://gist.github.com/choppsv1

djsadinoff
  • 5,519
  • 6
  • 33
  • 40
-1

I use xterm-frobs.el to get 256 color term support (in xterm compatible terminals, like konsole). i use the TERM setting "xterm-256color". 256 color support has generally been more than sufficient for me, as i don't use that many colors in my color scheme. the aforementioned file attempts to interrogate the terminal to find out how many colors it supports. i don't know if it should (or could be adapted to) be able to do true color support in konsole.

UPDATE: Note that as of version 26.1, emacs now has support for true color terminals. Please see the answer below for more details.

jtahlborn
  • 52,909
  • 5
  • 76
  • 118