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

feat(highlight): update default color scheme #26334

Merged
merged 1 commit into from
Dec 3, 2023

Conversation

echasnovski
Copy link
Member

@echasnovski echasnovski commented Nov 30, 2023

2023-12-16 Edit: #26540 introduced some tweaks to the default color scheme based on the feedback. In particular, screenshots, palettes, and contrast ratios listed in this PR are now not up to date.


This PR addresses a long standing issue of suboptimal default color scheme. Here is the outline of what it proposes.

Design

  • Be "Neovim branded", i.e. follow outlined example as main reference from defaults: improved default color scheme #14790. This generally means to mostly have "green-blue" feel plus one/two colors reserved for very occasional user attention.
  • Be extra minimal for notermguicolors (256 colors) while allowing a bit more shades for when termguicolors is set (true colors). I really hope that this compromise will allow to coexist extreme minimalism of reference colors and a bit more variety with true colors.
  • Be accessible, i.e. have enough contrast ratio. This means to have at least 7 for Normal highlight group and 4.5 for some common cases (Visual, Comment with set 'cursorline', colored syntax, Diff*, Search).
  • Be dark and light variants a simple exchange of dark and light palettes (as this is easier to implement and requires less colors introduced).
  • Be usable, i.e. provide enough visual feedback for common objects.

Palette

  • Introduce two separate palettes: dark (NvimDark*) and light (NvimLight*).
  • Dark/light palette is used for background in dark/light color scheme and for foreground in light/dark color scheme. This introduces recognizable visual system without too standing out.
  • Actual computation of palettes is done in a perceptually uniform Oklch color space. I highly recommend this interactive picker/converter.
  • Each palette has the following colors (descriptions are for dark background; reverse for light one):
    • Four shades of "colored" greys for general UI. In 256 colors they are exact greys; with termguicolors - shades of "cool" grey.
      • Dark ones (from darkest to lightest) are reserved as background for NormalFloat (considered as "black"), Normal (background), CursorLine, Visual.
      • Light ones (also from darkest to lightest) are reserved for Comment, StatusLine/TabLine, Normal (foreground), and color considered as "white".
    • Hues for green, cyan, and red are modelled after reference color scheme: #87FFAF, #00E6E6, #D96D6A. Result have very similar hue but slightly different lightness and chroma (to be consistent with UI and palette).
    • Hues for yellow, blue, and magenta are chosen such as to be visibly different.
  • Each palette color has the 256 colors variant with closest colors.

All colors are procedurally and objectively generated based on a handful of hyperparameters. Here is a link to the script (to run, it requires 'mini.colors' dependency).

Here is the data about palettes:

Hex palettes
Dark:
blue    = "#005078"
cyan    = "#007676"
green   = "#015825"
grey1   = "#0a0b10"
grey2   = "#1c1d23"
grey3   = "#2c2e33"
grey4   = "#4f5258"
magenta = "#4c0049"
red     = "#5e0009"
yellow  = "#6e5600"

Light:
blue    = "#9fd8ff"
cyan    = "#83efef"
green   = "#aaedb7"
grey1   = "#ebeef5"
grey2   = "#d7dae1"
grey3   = "#c4c6cd"
grey4   = "#9b9ea4"
magenta = "#ffc3fa"
red     = "#ffbcb5"
yellow  = "#f4d88c"
256 colors palettes
Dark:
blue    = 24
cyan    = 30
green   = 22
grey1   = 232
grey2   = 234
grey3   = 236
grey4   = 239
magenta = 53
red     = 52
yellow  = 58

Light:
blue    = 153
cyan    = 123
green   = 158
grey1   = 255
grey2   = 253
grey3   = 251
grey4   = 247
magenta = 189
red     = 217
yellow  = 222
Contrast ratios

dark_* are for dark color scheme, ligth_* - for light.

dark_blue         = 11
dark_comment      = 6.3
dark_comment_cur  = 5.1
dark_comment_vis  = 2.9
dark_cur_line     = 9.7
dark_cyan         = 12.5
dark_green        = 12.4
dark_magenta      = 11.6
dark_normal       = 12
dark_red          = 10.5
dark_visual       = 5.6
dark_yellow       = 12
light_blue        = 6.2
light_comment     = 5.6
light_comment_cur = 4.6
light_comment_vis = 2.9
light_cur_line    = 9.8
light_cyan        = 3.9
light_green       = 6.2
light_magenta     = 10.7
light_normal      = 12
light_red         = 10.1
light_visual      = 6.3
light_yellow      = 5

Highlight groups

  • Use greys for general UIs.
  • Use bold text for keywords (Statement highlight group). This is an important choice to increase accessibility for people with color deficiencies, as it doesn't rely on actual color.
  • Use green for strings, DiffAdd (as background), DiagnosticOK, and some minor text UI elements.
  • Use cyan as main syntax color, i.e. for function calls (Function), DiffText, DiagnosticInfo (and DiagnosticHint in 256 colors), and some minor text UI elements.
  • Use red to generally mean high user attention, i.e. errors. That is, ErrorMsg, DiffDelete, DiagnosticError.
  • Use (very sparingly) yellow only with true colors to mean mild user attention, i.e. warnings. That is, WarningMsg, and DiagnosticWarn. With 256 colors it falls back to red. One important exception to this is Search which has yellow background.
  • Use (very sparingly) blue as Identifier only with true colors. This gets used quite a lot, so it does not have fallback for 256 colors (to reduce noise).
  • Magenta is not used and here only for completeness to allow setting full 8 terminal colors (later).

Here are screenshots in many situations:

Screenshots

Dark, 256 colors:

default-cs_dark_notgc

Dark, 256 colors, diff:

default-cs_dark_notgc_diff

Dark, 256 colors, tree-sitter:

default-cs_dark_notgc_treesitter

Dark, 256 colors, tree-sitter + LSP:

default-cs_dark_notgc_treesitter_lsp

Dark, true colors:

default-cs_dark_tgc

Dark, true colors, diff:

default-cs_dark_tgc_diff

Dark, true colors, tree-sitter:

default-cs_dark_tgc_treesitter

Dark, true colors, tree-sitter+LSP:

default-cs_dark_tgc_treesitter_lsp

Light, 256 colors:

default-cs_light_notgc

Light, 256 colors, diff:

default-cs_light_notgc_diff

Light, 256 colors, tree-sitter:

default-cs_light_notgc_treesitter

Light, 256 colors, tree-sitter + LSP:

default-cs_light_notgc_treesitter_lsp

Light, true colors:

default-cs_light_tgc

Light, true colors, diff:

default-cs_light_tgc_diff

Light, true colors, tree-sitter:

default-cs_light_tgc_treesitter

Light, true colors, tree-sitter+LSP:

default-cs_light_tgc_treesitter_lsp


@justinmk, as you are the one making merging decision, I am mentioning you here. To be fully upfront, here are the changes which I think you might not like (yet I still ask you to try them and reconsider):

  • Search has yellow background. I tried various combinations, but having any other basic color (grey, green, cyan) as background will blend in more than it should. I tried reverse=true, but it looks not really good and has issue with not visible cursor (which is very often also reversed).
    • As yellow is not used anywhere in the syntax, having it as Search makes sense.
  • There are small number of yellow (Diagnostic*Warn, SpellCap) and blue colors added with termguicolors. See screenshots.
  • Diff* colors come from "background" palette. Those have similar lightness to background and stand out mostly via saturation (and not saturation + lightness). Reference examples in defaults: improved default color scheme #14790 didn't have such colors available, so I decided to try them here. They do look good.

I would like this to be a present to Neovim for its 10-th anniversary (which is in two months, according to 72cf89b). Hope to have a discussion with eventual green light on actual color scheme being mergeable. After that I'll fix (probably literal) hundreds of failing tests (I patched some hanging ones, but couldn't see the finish of make test due to timeout).


Fixes #14790.
Resolves #24253.

@clason clason linked an issue Nov 30, 2023 that may be closed by this pull request
src/nvim/highlight_group.c Outdated Show resolved Hide resolved
@justinmk
Copy link
Member

justinmk commented Dec 1, 2023

Let's move quickly on this, @echasnovski you've been a heroic custodian of this topic, and it's a 2-way door--this is a good foundation for future improvements. Thank you!

Some minor requests:

  • Most of your PR notes should be pasted into a new help file at doc/dev_theme.txt, so we can have guidelines as we develop the theme.
    • The "Highlight groups" notes especially are perfect.
    • Also in the commit message!
  • Hyperlinks should be underlined, as God intended (and github just noticed after 10 years 😂 ).
    • Probably also :help links, but can wait for now.

Be accessible, i.e. have enough contrast ratio.

Yes. We should also consider bg that is closer black/white.

Search has yellow background. I tried various combinations, but having any other basic color (grey, green, cyan) as background will blend in more than it should.

Definitely not a blocker, though I'll mention that years ago I had yellow Search and eventually found it wasn't needed (the block background stands out pretty well, to start with).

After that I'll fix (probably literal) hundreds of failing tests

We can ship the old Vim colors as a builtin vim theme. So we can force :colorscheme vim in the test runner, in order to unblock this first PR. Though I agree (in a followup PR) we should update mosts tests (except where there's an extreme amount of churn--then just do a local :colorscheme vim in before_each).

Copy link
Member

@justinmk justinmk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯 Let's do it

@justinmk justinmk added this to the 0.10 milestone Dec 1, 2023
@echasnovski
Copy link
Member Author

echasnovski commented Dec 1, 2023

Thanks for approving!

  * The "Highlight groups" notes especially are perfect.
  * Also in the commit message!

Will do!

* Hyperlinks should be underlined, as God intended (and github just noticed after 10 years 😂 ).

Not sure what to do extra here. There seems to be only one group related to linking (@text.uri) and it was already underlined.

Yes. We should also consider bg that is closer black/white.

I basically chose lightness 13 from the reference #1e1e1e. Although making background more extreme would allow addressing one small issue for light color scheme (there comments are a bit visually similar to normal text; all good for dark), it introduces another bigger issue.

Basically, it should be too dark because background for floating windows are darker than normal background. So to make them visually separable, it shouldn't be too black/white. Of course, floating windows can be made lighter than normal (essentially switch normal and floating backgrounds), but it would mean that PMenu and CursorLine would have high contrast ratio. Which is not really good, in my opinion.

That said, all colors already meet standards outlined at the beginning (except cyan text for light theme, but that is because there isn't really such thing as "dark saturated cyan").

We can ship the old Vim colors as a builtin vim theme. So we can force :colorscheme vim in the test runner, in order to unblock this first PR. Though I agree (in a followup PR) we should update mosts tests (except where there's an extreme amount of churn--then just do a local :colorscheme vim in before_each).

That certainly makes things easier! I am still committed to update all tests to make them proper if general core consensus decides so.

@glepnir
Copy link
Member

glepnir commented Dec 1, 2023

Here's the truecolor palette used in the screenshots for easy reference:

dark:

  • #005078 #005078
  • #007676 #007676
  • #015825 #015825
  • #0a0b10 #0a0b10
  • #1c1d23 #1c1d23
  • #2c2e33 #2c2e33
  • #4f5258 #4f5258
  • #4c0049 #4c0049
  • #5e0009 #5e0009
  • #6e5600 #6e5600

light:

  • #9fd8ff #9fd8ff
  • #83efef #83efef
  • #aaedb7 #aaedb7
  • #ebeef5 #ebeef5
  • #d7dae1 #d7dae1
  • #c4c6cd #c4c6cd
  • #9b9ea4 #9b9ea4
  • #ffc3fa #ffc3fa
  • #ffbcb5 #ffbcb5
  • #f4d88c #f4d88c

@bfredl
Copy link
Member

bfredl commented Dec 1, 2023

So we can force :colorscheme vim in the test runner, in order to unblock this first PR. Though I agree (in a followup PR) we should update mosts tests (except where there's an extreme amount of churn--then just do a local :colorscheme vim in before_each).

I agree with this plan. Updating the tests should be done eventually, but it will be a huge project, and it is better to unblock this PR by using :colorscheme vim generously (or globally) for most of test/functional for now.

@dundargoc
Copy link
Member

This seems like a controversial feature. Maybe we should wait for more approvals before moving forward with this?

@gpanders
Copy link
Member

gpanders commented Dec 1, 2023

Don’t forget a news.txt entry.

@echasnovski
Copy link
Member Author

Don’t forget a news.txt entry.

And 'vim_diff.txt', yes.

@echasnovski
Copy link
Member Author

I have force pushed the changes. In actual color scheme I only changed TermCursorNC to link to NONE instead of TermCursor (to make some tests pass).

There are still failing tests which I'd need help resolving, as they are somewhat too deep into source and test code. I'll try figuring something out.

Otherwise, documentation should be all which requested.

@zeertzjq
Copy link
Member

zeertzjq commented Dec 2, 2023

Also needs colorscheme vim in test/old/testdir/setup.vim, after the tlunmenu *.

runtime/doc/dev_theme.txt Outdated Show resolved Hide resolved
runtime/doc/vim_diff.txt Outdated Show resolved Hide resolved
runtime/doc/dev_theme.txt Outdated Show resolved Hide resolved
runtime/doc/dev_theme.txt Outdated Show resolved Hide resolved
runtime/doc/dev_theme.txt Outdated Show resolved Hide resolved
runtime/doc/dev_theme.txt Outdated Show resolved Hide resolved
runtime/doc/dev_theme.txt Outdated Show resolved Hide resolved
runtime/doc/dev_theme.txt Show resolved Hide resolved
runtime/doc/dev_theme.txt Outdated Show resolved Hide resolved
runtime/doc/dev_theme.txt Outdated Show resolved Hide resolved
runtime/doc/news.txt Outdated Show resolved Hide resolved
runtime/doc/vim_diff.txt Outdated Show resolved Hide resolved
@echasnovski
Copy link
Member Author

@clason, @zeertzjq: All review notes are addressed. Thanks for the pointers!

@zeertzjq zeertzjq changed the title Update default color scheme feat(highlight): update default color scheme Dec 3, 2023
@zeertzjq zeertzjq merged commit 0d88524 into neovim:master Dec 3, 2023
28 checks passed
@neovim neovim locked as resolved and limited conversation to collaborators Dec 3, 2023
@clason
Copy link
Member

clason commented Dec 3, 2023

Thank you, @echasnovski, for your hard work and patience in seeing this through! What a lovely (early) birthday present :)

@echasnovski echasnovski mentioned this pull request Dec 3, 2023
6 tasks

" This is the default color scheme. It doesn't define the Normal
" highlighting, it uses whatever the colors used to be.
" This is the default color scheme.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should mention something like

See :help dev_theme

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we mention the Nvim* colors at :help gui-colors ?

@neovim neovim unlocked this conversation Dec 3, 2023
@neovim neovim locked as resolved and limited conversation to collaborators Dec 8, 2023
@neovim neovim unlocked this conversation Dec 8, 2023
EdenEast added a commit to EdenEast/nightfox.nvim that referenced this pull request Dec 14, 2023
Relates to default colorscheme change in neovim [#26334](neovim/neovim#26334)
EdenEast added a commit to EdenEast/nightfox.nvim that referenced this pull request Dec 14, 2023
Relates to default colorscheme change in neovim [#26334](neovim/neovim#26334)
@mrcjkb
Copy link
Contributor

mrcjkb commented Dec 15, 2023

Update

The below comment appears to be specific to the colorscheme. I can't reproduce the behaviour with catppuccin.
Leaving it here in case someone else comes across this.


I've noticed some broken tree-sitter highlighting and git bisected it to this PR.

Specifically, Neovim used to highlight according to the last match in the highlights.scm file.
(I've been told this is the indended behaviour - and not to use priorities).

Before this PR:

Notice how spec matches @variable.haskell last and is highlighted accordingly

treesitter

After this PR:

Now spec is highlighted as @function.haskell

image

I'm not sure if this is known, and if there's already an issue for it (I couldn't find one).
I'm also not 100 % sure it's not an issue that's specific to the colorscheme I'm using (material.nvim).
Since it's caused by this change, I thought I'd comment here before opening an issue 😄

@clason
Copy link
Member

clason commented Dec 15, 2023

Yes, treesitter groups have yet to be adapted; that is ongoing work (please read the description and open issues and PRs)

Friendly reminder: master is not guaranteed to be usable, if greater changes need to be carried out across multiple PRs.

@neovim neovim locked as resolved and limited conversation to collaborators May 17, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
defaults issues or PRs involving changing the defaults highlight
Projects
None yet
Development

Successfully merging this pull request may close these issues.

defaults: improved default color scheme