Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can we fix the default colorscheme ? #250

Open
neutaaaaan opened this issue Nov 17, 2023 · 13 comments
Open

Can we fix the default colorscheme ? #250

neutaaaaan opened this issue Nov 17, 2023 · 13 comments

Comments

@neutaaaaan
Copy link
Collaborator

This post is motivated by this now closed pull request from chrisbra.
I figured that if one of vim's core devs had such different expectations from vim's colorschemes than what they actually are, and have been for 2 decades, issues such as the one highlighted here are likely to have gone unnoticed.

What we currently call "the default colorscheme" is the byproduct of several things :

  • the various broken implementations of seemingly unrelated colorschemes that share the same name
  • vim failing to autodetect the user's terminal background color over ssh and defaulting to the light version
  • distro maintainers doing the usual distro maintainer shuffle to work around perceived issues with vim's default config

As I myself get to use "the default colorscheme" pretty much all day long at work, through various environments, versions of vim, and distributions, I've grown to absolutely abhor it.
Not because it's bad per se, but because the user experience is utterly inconsistent.

There's very little that could be done about the 24bit version without effectively breaking it. It's trash, and I don't even care.
The terminal versions, especially the 256c one, could use a lot of tweaking, to fix design decisions that only make sense within the context of the default xterm palette, or to restore functionalities that break over ssh.

The goal of this post is to figure out if a third colorscheme could be implemented within vim as a fallback when it fails to autodetect the background color. This colorscheme would be based upon the light version, which is the actual default colorscheme.

I believe it is viable, because this version of the colorscheme does so many things wrong that they right themselves.

I'll use screenshots from an xterm analogue, quiet (itself essentially a more legible xterm analogue), a gruvbox analogue, and because I think it's fair to acknowledge that there is no silver bullet, a solarized analogue.

All the makeshift modifications displayed in this post will use similar design rules to what I've used in quiet or sorbet :

  • I don't mind using different palettes for elements that I don't expect to stay on screen very long, or that are contextually different enough from the buffer being displayed.
  • There is no code highlighting within diffs, selections or searches, as this only creates issues

I use rxvt-unicode and tmux, both configured proprely to use the extended 256c palette.
Here are the aliases used to get vim into the same state it'd be over ssh without a config file:
vim -u NONE +"set nocp" +"syntax on" +"set background=light"
vimdiff -u NONE +"set nocp" +"syntax on" +"set background=light"

Most of the main highlighting palette uses ansi colors, except for spotfixes in places where I believe the default xterm ansi colors really didn't work out, such as the Statement group, and diffs.

Here's what the light version of default looks like, peering at a spot in a random file that contains a bunch of statements:
xterm256c
quiet256c
gruvbox256c
solarized256c

The fact that bad colors were picked 30 years ago for one terminal emulator's ansi palette shouldn't hinder vim users in 2023.
Remarkably, whoever made this tweak, effectively did what most colorscheme/theme authors seem to do : use orange as a proxy for yellow.
Here's what this looks like with Statement pointing to ansi3:
xterm256c_statement
quiet256c_statement
gruvbox256c_statement
solarized256c_statement

Diffs are plain broken.
They rely on the extended 256c palette but still use the ansi palette for DiffText, which ends up being completely illegible.
They also try to preserve syntax highlighting inside diffed elements, which simply cannot work in this context.
xterm256c_diff
quiet256c_diff
gruvbox256c_diff
solarized256c_diff

There's little point trying to move away from the 256c when it comes to diff. Having its ozn palette is fine, it's the behaviour that's busted and ought to be fixed:
xterm256c_diff_coherent
quiet256c_diff_coherent
gruvbox256c_diff_coherent
solarized256c_diff_coherent

Visual selections are broken. We can't rely on fg/bg being different, or even different enough from ansi7 to be legible.
This happens to me on a daily basis:
xterm256c_visual
quiet256c_visual
gruvbox256c_visual
solarized256c_visual

Fixing this requires bolting selections down to a single color:
xterm256c_visual_coherent
quiet256c_visual_coherent
gruvbox256c_visual_coherent
solarized256c_visual_coherent

Search results are kinda crap for similar reasons:
xterm256c_search
quiet256c_search
gruvbox256c_search
solarized256c_search

And the situation can be remedied somewhat by bolting the color down.
xterm256c_search_coherent
quiet256c_search_coherent
gruvbox256c_search_coherent
solarized256c_search_coherent

This is far from being complete and is just meant to get the ball rolling.

@romainl
Copy link
Collaborator

romainl commented Nov 17, 2023

Just to be clear, when you say "gruvbox256c", you mean

  • the terminal emulator's palette is gruvbox,
  • $TERM is set to xterm-256color,
  • and you are implicitly using :colorscheme default,

right?

@neutaaaaan
Copy link
Collaborator Author

@romainl

For all intents and purposes, yes.
The only strange thing I'm doing is forcing -u NONE to make sure I don't sideload a distrowide config on my own machine, and force background=light because vim is able to tell I'm using a dark or light background locally.
I've tested the same elements over ssh, without having to do any of that, and had similar results.

@romainl
Copy link
Collaborator

romainl commented Nov 18, 2023

Some of those issues have, I think, been demonstrably broken for a while. As a matter of fact, I've had various iterations of the following fixes in my portable minimal vimrcs practically since I started using Vim:

hi Search cterm=NONE ctermbg=yellow ctermfg=black
hi StatusLineNC cterm=bold ctermbg=darkgrey
hi Visual cterm=NONE ctermbg=white ctermfg=darkblue

I am not sure when, exactly, Visual became unusable with syntax on, but one would think it would have been noticed by someone… and fixed, by now. Oh well.

The relevant section of highlight.c is relatively readable so let's discuss which color combo makes the most sense for each of the problematic highlight group and make a PR.

@habamax
Copy link
Collaborator

habamax commented Dec 7, 2023

I think we should try to fix it in highlight.c bite by bite.

Visual indeed annoys me the most -- combined with quite unreliable dark/light detection, it is plain unreadable:

image

@chrisbra what do you think?

PS, even with set bg=dark it is quite bad:
image

@chrisbra
Copy link
Member

chrisbra commented Dec 8, 2023

Well, what exactly would you suggest to fix here? I had a similar issues with the Visual highlighting before: vim/vim#8247 But nobody saw this as an actual issue 🤷

@habamax
Copy link
Collaborator

habamax commented Dec 8, 2023

Well, what exactly would you suggest to fix here?

Make Visual non-transparent with bg and fg setup instead of using term=reverse (at least for TUI), we can try different variants of bg too.

@romainl
Copy link
Collaborator

romainl commented Dec 9, 2023

@chrisbra the direction we took with the remakes and the new colorschemes is to explicitly specify Visual's foreground color/style.

The upside is simply that the visual selection is readable in any context, with or without syntax highlighting.

The downside is of course that, the visually selected area loses its syntax highlighting, which some users might find discomforting in some cases.

From our point of view, that of people who dread using visual mode in default because it is so obviously broken, the upside dwarfs the downside by a few orders of magnitude.

FWIW, here are two screenshots of default, the first in 8c and the second in 16c, with the default xterm palette:

Capture d’écran 2023-12-09 à 11 35 06 Capture d’écran 2023-12-09 à 11 36 10

Visual is an abomination in 8c and plain unreadable for some of the foreground colors used in 16c. That is how Vim looks by default. No wonder there are literally thousands of third-party colorschemes available. Yes, you sort of see the syntax highlighting but come on.

Changing the style of Visual to some kind of black on white makes it a lot more usable:

Capture d’écran 2023-12-09 à 11 39 19 Capture d’écran 2023-12-09 à 11 37 26

Note that I haven't put a lot of effort into this so some other combination might work better.

For reference, here are some of the remakes, some of the new ones, and lastly one of mine, all with readable, working, Visual:

Delek:

Capture d’écran 2023-12-09 à 11 49 31

Ron:

Capture d’écran 2023-12-09 à 11 50 12

Zaibatsu:

Capture d’écran 2023-12-09 à 11 50 50

Habamax:

Capture d’écran 2023-12-09 à 11 50 35

Malotru:

Capture d’écran 2023-12-09 à 11 51 34

@chrisbra
Copy link
Member

chrisbra commented Dec 9, 2023

Okay, I guess I am too used to the current broken highlighting, I actually quite like, that the syntax highlighting is still visible in visual mode, but I can see why this causes problems. I am even used to Vim using light background with a default putty colorscheme (which means it is using black background).

So the following patch should remove the reverse stuff and set explicit background colors.

diff --git a/src/highlight.c b/src/highlight.c
index 31c3280e8..a29726865 100644
--- a/src/highlight.c
+++ b/src/highlight.c
@@ -220,8 +220,8 @@ static char *(highlight_init_light[]) = {
     CENT("SignColumn term=standout ctermbg=Grey ctermfg=DarkBlue",
         "SignColumn term=standout ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue"),
 #endif
-    CENT("Visual term=reverse",
-        "Visual term=reverse guibg=LightGrey"),
+    CENT("Visual ctermbg=DarkGrey ctermfg=White",
+        "Visual ctermbg=DarkGrey ctermfg=White guibg=Grey42 guifg=LightGrey"),
 #ifdef FEAT_DIFF
     CENT("DiffAdd term=bold ctermbg=LightBlue",
         "DiffAdd term=bold ctermbg=LightBlue guibg=LightBlue"),
@@ -309,8 +309,8 @@ static char *(highlight_init_dark[]) = {
     CENT("SignColumn term=standout ctermbg=DarkGrey ctermfg=Cyan",
         "SignColumn term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan"),
 #endif
-    CENT("Visual term=reverse",
-        "Visual term=reverse guibg=DarkGrey"),
+    CENT("Visual ctermbg=235 ctermfg=LightGrey",
+        "Visual ctermbg=235 ctermfg=LightGrey guifg=LightGrey guibg=Grey15"),
 #ifdef FEAT_DIFF
     CENT("DiffAdd term=bold ctermbg=DarkBlue",
         "DiffAdd term=bold ctermbg=DarkBlue guibg=DarkBlue"),
@@ -437,14 +437,8 @@ init_highlight(
     // With 8 colors brown is equal to yellow, need to use black for Search fg
     // to avoid Statement highlighted text disappears.
     // Clear the attributes, needed when changing the t_Co value.
-    if (t_colors > 8)
-       do_highlight((char_u *)(*p_bg == 'l'
-                   ? "Visual cterm=NONE ctermbg=LightGrey"
-                   : "Visual cterm=NONE ctermbg=DarkGrey"), FALSE, TRUE);
-    else
+    if (t_colors <= 8)
     {
-       do_highlight((char_u *)"Visual cterm=reverse ctermbg=NONE",
-                                                                FALSE, TRUE);
        if (*p_bg == 'l')
            do_highlight((char_u *)"Search ctermfg=black", FALSE, TRUE);
     }

It works okay with a dark and light putty terminal, only in 8 color mode, one cannot see the default background color, since it is black as the Normal one. Not sure if 8 color terminals still matter nowadays.

And then I am not good with visualizing, so don't know 🤷

@habamax
Copy link
Collaborator

habamax commented Dec 11, 2023

Thx, @chrisbra

I think it would be easier to create a PR and check results there.

We should target all kind of things (no color mode, 8 color mode, etc)

chrisbra added a commit to chrisbra/vim that referenced this issue Dec 11, 2023
The default visual highlighting currently is nice in that it overlays
the actual syntax highlighting by using a separate distinct background
color.

However, this can cause hard to read text, because the contrast
between the actual syntax element and the background color is way too
low. That is an issue, that has been bothering colorschemes authors for
quite some time so much, that they are defining the Visual highlighting
group to use a separate foreground and background color, so that the
syntax highlighting vanishes, but the text remains readable (ref:
vim/colorschemes#250)

So this is an attempt to perform the same fix for the default Visual
highlighting and just use a default foreground and background color
instead of using reverse.

Current issues:
- doesn't work well in 8 color mode, since the background and foreground
  colors used remain un-distinguishable.

I also removed the hard-coded changes to the Visual highlighting in
init_highlight. It's not quite clear to me, why those were there and not
added directly to the highlighting_init_<dark|light> struct.

I hope this makes kind of sense.

Signed-off-by: Christian Brabandt <cb@256bit.org>
@chrisbra
Copy link
Member

vim/vim#13663

@neutaaaaan
Copy link
Collaborator Author

I'm sorry I haven't been able to contribute much lately, work's been pretty hectic.

I think it's fairly obvious from my example screenshots that if I were to fix all versions of the light default colorscheme, I'd basically rebuild them on top of quiet. I do believe trying to preserve syntax highlighting within selections and diffs is not only unnecessary, but counterproductive as far as semantics go given the fairly limited color palette available.

As for 8c terminals, yes, they are relevant. Not only do most people not know anything about terminfo, anytime you use tmux or screen without a config file, they default to the 8c version of their terminfo. This is how most people use multiplexers, and this is not about to change.

@neutaaaaan
Copy link
Collaborator Author

There are 3 intertwined topics here:

  • things that are plain broken in all variants and need fixing, ie: visual selections.
  • implementation issues in the dark or light variants that are only relevant to their intended use case.
  • the default (light) colorscheme breaking down in contexts in which vim cannot figure out the user's background color.

If on paper the best course of action would be to tackle those issues in the order above, I'm afraid there is too much interplay between them to be able to do meaningful work on one item without impacting the others. We'd also introduce the possibility of having to reconsider or further tweak breaking changes after they've been pushed to vim proper, which I believe we'd all rather like to avoid.
For this reason, they all have to be worked on simultaneously.

Similarly, this is work that ought to be out by vim 9.1.0, to avoid having to bother distribution maintainers with implementing specific patches manually.
IF we find a way to work around the issue of vim defaulting to the light colorscheme or implement an agnostic colorscheme based on the current light default one, we will also have to warn distribution maintainers, as I do believe a lot of systemwide .vimrc that default to the dark background only do so to avoid issues such as the broken visual selections.

I should be able to work on a patch this week, so we can at least get the ball rolling.

@neutaaaaan
Copy link
Collaborator Author

I've been putting some work into this branch

This only addresses the issues mentionned in my original post, somewhat less intrusively overall.
The goal of my patch is to be background agnostic. I believe this is the best we can hope for, short of completely rehauling how vim handles its initial colorscheme selection.

The dark colorscheme has similar issues that we're also going to have to fix.

chrisbra added a commit to chrisbra/vim that referenced this issue Jan 25, 2024
The default visual highlighting currently is nice in that it overlays
the actual syntax highlighting by using a separate distinct background
color.

However, this can cause hard to read text, because the contrast
between the actual syntax element and the background color is way too
low. That is an issue, that has been bothering colorschemes authors for
quite some time so much, that they are defining the Visual highlighting
group to use a separate foreground and background color, so that the
syntax highlighting vanishes, but the text remains readable (ref:
vim/colorschemes#250)

So this is an attempt to perform the same fix for the default Visual
highlighting and just use a default foreground and background color
instead of using reverse.

I also removed the hard-coded changes to the Visual highlighting in
init_highlight. It's not quite clear to me, why those were there and not
added directly to the highlighting_init_<dark|light> struct.

Signed-off-by: Christian Brabandt <cb@256bit.org>
chrisbra added a commit to vim/vim that referenced this issue Jan 28, 2024
Problem:  UX of visual highlighting can be improved
Solution: Improve readibility of visual highlighting,
          by setting better foreground and background
          colors

The default visual highlighting currently is nice in that it overlays
the actual syntax highlighting by using a separate distinct background
color.

However, this can cause hard to read text, because the contrast
between the actual syntax element and the background color is way too
low. That is an issue, that has been bothering colorschemes authors for
quite some time so much, that they are defining the Visual highlighting
group to use a separate foreground and background color, so that the
syntax highlighting vanishes, but the text remains readable (ref:
vim/colorschemes#250)

So this is an attempt to perform the same fix for the default Visual
highlighting and just use a default foreground and background color
instead of using reverse.

I also removed the hard-coded changes to the Visual highlighting in
init_highlight. It's not quite clear to me, why those were there and not
added directly to the highlighting_init_<dark|light> struct.

closes: #13663
related: vim/colorschemes#250

Signed-off-by: Christian Brabandt <cb@256bit.org>
zeertzjq pushed a commit to neovim/neovim that referenced this issue Jan 29, 2024
Problem:  UX of visual highlighting can be improved
Solution: Improve readibility of visual highlighting,
          by setting better foreground and background
          colors

The default visual highlighting currently is nice in that it overlays
the actual syntax highlighting by using a separate distinct background
color.

However, this can cause hard to read text, because the contrast
between the actual syntax element and the background color is way too
low. That is an issue, that has been bothering colorschemes authors for
quite some time so much, that they are defining the Visual highlighting
group to use a separate foreground and background color, so that the
syntax highlighting vanishes, but the text remains readable (ref:
vim/colorschemesvim/vim#250)

So this is an attempt to perform the same fix for the default Visual
highlighting and just use a default foreground and background color
instead of using reverse.

I also removed the hard-coded changes to the Visual highlighting in
init_highlight. It's not quite clear to me, why those were there and not
added directly to the highlighting_init_<dark|light> struct.

closes: vim/vim#13663
related: vim/colorschemes#250

vim/vim@e6d8b46

Co-authored-by: Christian Brabandt <cb@256bit.org>
konosubakonoakua pushed a commit to konosubakonoakua/neovim that referenced this issue Feb 4, 2024
…#27256)

Problem:  UX of visual highlighting can be improved
Solution: Improve readibility of visual highlighting,
          by setting better foreground and background
          colors

The default visual highlighting currently is nice in that it overlays
the actual syntax highlighting by using a separate distinct background
color.

However, this can cause hard to read text, because the contrast
between the actual syntax element and the background color is way too
low. That is an issue, that has been bothering colorschemes authors for
quite some time so much, that they are defining the Visual highlighting
group to use a separate foreground and background color, so that the
syntax highlighting vanishes, but the text remains readable (ref:
vim/colorschemesvim/vim#250)

So this is an attempt to perform the same fix for the default Visual
highlighting and just use a default foreground and background color
instead of using reverse.

I also removed the hard-coded changes to the Visual highlighting in
init_highlight. It's not quite clear to me, why those were there and not
added directly to the highlighting_init_<dark|light> struct.

closes: vim/vim#13663
related: vim/colorschemes#250

vim/vim@e6d8b46

Co-authored-by: Christian Brabandt <cb@256bit.org>
glepnir pushed a commit to glepnir/neovim that referenced this issue Mar 31, 2024
…#27256)

Problem:  UX of visual highlighting can be improved
Solution: Improve readibility of visual highlighting,
          by setting better foreground and background
          colors

The default visual highlighting currently is nice in that it overlays
the actual syntax highlighting by using a separate distinct background
color.

However, this can cause hard to read text, because the contrast
between the actual syntax element and the background color is way too
low. That is an issue, that has been bothering colorschemes authors for
quite some time so much, that they are defining the Visual highlighting
group to use a separate foreground and background color, so that the
syntax highlighting vanishes, but the text remains readable (ref:
vim/colorschemesvim/vim#250)

So this is an attempt to perform the same fix for the default Visual
highlighting and just use a default foreground and background color
instead of using reverse.

I also removed the hard-coded changes to the Visual highlighting in
init_highlight. It's not quite clear to me, why those were there and not
added directly to the highlighting_init_<dark|light> struct.

closes: vim/vim#13663
related: vim/colorschemes#250

vim/vim@e6d8b46

Co-authored-by: Christian Brabandt <cb@256bit.org>
Smattr added a commit to Smattr/mattutils that referenced this issue May 21, 2024
Commit e6d8b4662ddf9356da53f56e363b67b524fd8825¹ of Vim made some changes to
how visual highlighting works that interact poorly with our tweaks. Their
change, when tweaked by us with `cterm=reverse` resulted in near-invisible
highlighting. Ironically, invisible highlighting seems to be one of the problems
the Vim developers are trying to avoid with this and other recent related
changes.

Vim PR #250² has some further commentary relevant to this, including the
puzzling statement:

  We can't rely on fg/bg being different…

I do not understand this because, if the foreground and background colours were
not different, your text would be invisible. In any useful colour scheme, it
seems to me you can rely on the foreground and background colour differing.

This commit does something close to reverting to the old behaviour. Visual
highlighting flips the foreground and background colours, which leads to
something that is both syntax highlighted and readable. Ironically, this is
similar to the screenshot of the 8c default highlighting posted in a PR #250
comment³ that user romainl describes as “an abomination.” I guess beauty is in
the eye of the beholder.

¹ vim/vim@e6d8b46
² vim/colorschemes#250
³ vim/colorschemes#250 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants