-
Notifications
You must be signed in to change notification settings - Fork 741
Description
Kakoune has (deliberately) limited support for applying colour-schemes with it's default ncurses-based UI. On one hand, ncurses really wants applications to use colour-indexes into the terminal's standard palette; on the other hand, every other modern display API wants 8-bits-per-channel RGB triples in the sRGB colour-space, and mawww is uncomfortable with designing Kakoune's colour-scheme API around the limitations of ncurses.
The current compromise is that Kakoune supports a few named colours that happen to map to the standard 8 terminal colours in the ncurses UI, arbitrary #rrggbb colours are passed to init_color(3N)
, modifying the entries in the terminal's 256-colour palette. This has it's downsides; as well as being impolite (the user might have configured those palette entries themselves, and Kakoune stomps on them) there are terminals that don't support modifying the 256-colour palette at all (the Qt terminal widget being a notable example).
Some terminals have added a 24-bit or "direct colour" mode so an application can set an arbitrary colour at any time without having to declare it beforehand; in particular, libvte (used by gnome-terminal
), tmux
and xterm
(since version 331). People have previously suggested using this with Kakoune, but nothing has ever come of it because there was no way to ask or trick ncurses into taking advantage of this mode. However, support is being added to ncurses 6.1 libraries, I've spent some time trying to figure out how it's all supposed to work, and I wanted to write that information down somewhere before I forgot.
terminfo and ncurses
A new fragment has been added to the terminfo database, named xterm+direct, along with an entry named xterm-direct
that layers the +direct
fragment on top of the standard xterm
entry.
This fragment rewrites the setab
(set ANSI background) and setaf
(set ANSI foreground) rules to directly accept a 24-bit colour rather than a palette index. Actually, it's a bit more complex than that: if I understand correctly, the darkest 8 shades of blue (i.e. #000000
through #000007
) are taken to mean the standard 8 terminal colours rather than indistinguishable shades of black, so programs that blindly send setaf 2
will get the traditional green text instead of effectively-black. It also sets the RGB
flag to signal that setab
and setaf
do not follow the traditional behaviour.
applications
Since most classic curses APIs take colour values as shorts
, they can't be used with direct colour. You'll have to use ncurses extended APIs instead. For example, init_extended_pair(3N)
instead of init_pair(3N)
.
Looking at the changes in xterm+direct
, I'm guessing most palette-related ncurses functions like init_color(3N)
and init_extended_color(3N)
will just break. extended_color_content(3N)
is a notable exception: if the terminfo RGB
flag is set, it can get the RGB fields of a colour through masking and shifting instead of consulting the palette.
I'm not sure if there's a good way for an application to detect whether init_extended_pair(3N)
wants palette-indexes or raw colours. Perhaps if calling tigetflag(3N)
with "RGB" returns anything other than 0 (that is, if it's boolean true, or if it's present but not a boolean), that's the best heuristic?
users
This ncurses direct-colour mode is only available if $TERM
is set to the name of a terminal-entry that contains the appropriate configuration. Right now, that's only true if $TERM
is set to xterm-direct
on a machine with a sufficiently-modern copy of ncurses installed (and by "sufficiently-modern" I mean "newer than January 2018"). Even on machines that have the xterm-direct
entry in the terminfo database, users might not want to use it, since it will probably break applications designed to work with 256-colour support, and it deliberately excludes a bunch of other useful fragments like xterm+tmux
(which declares extra xterm features tmux uses) and xterm+sl
(declares a sequence for setting xterm's title text). Therefore, it will probably be a while before this mode is widely available, let alone the default.