mawww / kakoune

mawww's experiment for a better code editor
http://kakoune.org
The Unlicense
9.8k stars 710 forks source link

Solarized color schemes break text markup #2842

Open Crote opened 5 years ago

Crote commented 5 years ago

This is a very subtle bug, but it's been bothering me for a while now.

Basically, when using any of the Solarized color schemes (so either dark or light, either termcolors or rgb colors), and only when using a Solarized one, the combination of a white foreground with a bright-cyan background is displayed as a bright-white foreground with a bright-cyan background.

Steps

:colorscheme solarized-light echo -markup "{white,bright-cyan}{bright-cyan,white}"

Outcome

The colors are subtly different, as shown here with the solarized-light color scheme and the Tango palette. Screenshot from 2019-04-06 22-36-34

Expected

The foreground color of the left arrow should have the same color as the background of the right arrow, as seen with the default color scheme Screenshot from 2019-04-06 22-36-44

Screwtapello commented 5 years ago

What terminal are you using, and what is your $TERM set to?

I don't have any Powerline stuff installed, so I tried to reproduce with:

echo -markup "{white,bright-cyan}▋{bright-cyan,white}▋"

However, I got the same shade of white both times, using xterm and gnome-terminal, and using the "default", "solarized-dark" and "solarized-dark-termcolors" colour schemes.

Crote commented 5 years ago

Those screenshots were made using gnome-terminal, $TERM is xterm-256color. Powerline is not required, it also happens when that plugin is disabled. I can reproduce this with the default kakrc. That's just how I initially noticed it. Be careful with the Solarized terminal palette, though: it will show a difference, but it will be extremely subtle and it's quite easy to miss even when you know it's there. With gnome-terminal, it is painfully obvious with the "Linux console" palette.

Screwtapello commented 5 years ago

I mean, I don't have a font that supports the chevron glyphs used in your example.

I started gnome-terminal version 3.30.2, I changed the terminal colour scheme to "Linux console", I launched Kakoune and changed the Kakoune colour-scheme to "solarized-dark-termcolors", and then I ran the command from my previous comment. That produced the following result:

image

So far as I can tell, the white colour (light grey) is the same for both echoed characters.

andreyorst commented 5 years ago

:colorscheme solarized-light echo -markup "{white,bright-cyan}{bright-cyan,white}"

My terminal colorscheme is Grubvox, so termcolors version doesn't looks like solarized at all, and colors are bit different but:

Now if I set my GNOME Terminal to builtin Solarized variants:

With these results I suspect that terminal configuration is an issue here, because there's no problem with my custom Gruvbox theme, but builtin Solarized causes an issue. Colors №15 №7 are bit different. If I set those to equal color: image image

The problem disappear.

But this indeed strange because colors used were non-bright and therefore color №7 only should be used

Screwtapello commented 5 years ago

These are the settings I'm using for gnome-terminal:

image

In particular, I don't have an override colour for bold, and I don't have "show bold text in bright colors" ticked. However, I don't remember if those are the defaults. Is it the same for you, @Crote and @andreyorst ?

andreyorst commented 5 years ago

I use show bold in bright, but in my colorscheme bright colors are defined as non-bright.

mawww commented 5 years ago

That is a strange behaviour, my understanding is that gnome-terminal, through a recent enough vte, should support color palette setting by Kakoune. Additionally, if that was a color palette setting issue, it should not cause any troubles with the termcolor variants as they do use the terminal palette directly.

Crote commented 5 years ago

@Screwtapello it's ticked by default, as far as I can tell. If I understand that setting correctly, having it unticked would render bright as non-bright, so you'd indeed be unable to see the difference.

@andreyorst if bright and non-bright colors are the same in your color scheme, there would also be no difference as the whole issue is that non-bright is being rendered as bright.

It's also not exclusive to gnome-terminal, the same thing happens with Konsole.

andreyorst commented 5 years ago

if bright and non-bright colors are the same in your color scheme, there would also be no difference as the whole issue is that non-bright is being rendered as bright.

Yes I've admitted this in the last line. Maybe I wasn't clear, but I've meant that because I use the same colors for normal and bright, I can't see the issue.

Screwtapello commented 5 years ago

@Crote Actually, "bold" and "bright colour" can/should be completely independent:

image

The whole bright/bold thing is a holdover from the days when most terminals only supported 8 colours. At any rate, I can't reproduce the problem with or without that setting enabled, so I don't think it's relevant. Do all the other settings in my screenshot match your system?

Crote commented 5 years ago

If I disable "Show bold text in bright colours", both are the same. If I enable it, they are different. I don't have your text and background colour scheme, so that's obviously different, but that shouldn't matter. The rest looks the same.

Bold and bright are supposed to be independent on modern systems, but they're not guaranteed to be. In fact, I'm starting to get a feeling that that's what causing this. Look at the color numbers at https://github.com/mawww/kakoune/blob/master/src/ncurses_ui.cc#L232 , those are the traditional 3-bit colors, with bright/bold flag. But as far as I can tell, only the 3-bit, non-bright variants are defined as ncurses constants? So passing the bright variants to ncurses seems to be wrong. It seems like NCursesUI::set_face is doing something weird, but I can't quite figure out what is going wrong, and why it seems to work on some occasions.

Screwtapello commented 5 years ago

Ohhh, right, I see what's going on. The Solarized themes say:

face global StatusLine         bright-cyan,black+b

...so the status-line text is bold. I can reproduce the problem like this:

kak -n -e 'set-face global StatusLine +b; echo -markup {white,bright-cyan}#{bright-cyan,white}#'

With the "Linux console" colour scheme and "show bold as bright" disabled, everything looks as intended:

image

...but if I tick "show bold as bright", the white # on the left is obviously a different colour:

image

Instead of swapping the foreground and background colours, you could also use them the ordinary way around and add the +r ("reverse video") attribute:

kak -n -e 'set-face global StatusLine +b; echo -markup {white,bright-cyan}#{white,bright-cyan+r}#'

Now with "show bold as bright" ticked, both # characters are "wrong" (they're bright-white instead of regular white), but at least they're consistent with each other:

image

I think as long as Powerline wants to control what colours appear next to each other, Solarized wants to use bold text, and the terminal emulator wants to mess with colours when bold is used, at least one of them will be disappointed.

But as far as I can tell, only the 3-bit, non-bright variants are defined as ncurses constants?

terminfo(5) mentions that although almost all terminals share that classic 3-bit palette, some are little-endian, so the palette goes black, red, green, yellow, etc. and some are big-endian, so the palette goes black, blue, green, cyan, etc. Ncurses provides those constants so an application can ask for "red" and get it, without having to worry about whether that's colour 1 or 4.

These days, every terminal you'll ever use supports a full 256-color palette (or more) with the bottom 8 colours in ANSI order (black, red, green, yellow, ...) so it's quite reasonable to hard-code that colour 5 is dark magenta, colour 10 is bright green, and colour 229 is a pale yellow.

andreyorst commented 5 years ago

Ohhh, right, I see what's going on. The Solarized themes say:

face global StatusLine         bright-cyan,black+b

Now that you've mentioned it, I've remembered that when I was making themes for powerline.kak, I've not used any of the attributes because I'm composing faces from two separate options:

image

And composition is done within the poweline.kak module: image

This way it is impossible for me to define bright-cyan,black+b color for specific module and a specific theme, because there's no way to track this per theme and this setting should be defined by the module, and I don't have any attribute mechanism currently. I'll address this problem, but perhaps, as a workaround for now this theme could set StatusLine face to non-bold, which I've tried to avoid.

I think I'll add something like attribute variable to theme later on.