Add dark and light color themes - #6065
Merged
Merged
Conversation
stefanhaller
added this pull request to stack #6064
September 26, 2026 17:28
This was referenced Sep 26, 2026
stefanhaller
force-pushed
the
dark-and-light-themes
branch
2 times, most recently
from
September 27, 2026 06:09
9ac3853 to
00c87c0
Compare
gui.branchColors has been deprecated in favor of gui.branchColorPatterns since 0.44.0. We are about to move gui.branchColorPatterns into gui.theme, and the deprecated key would have to move along with it. Migrate it instead, so that we can remove it. gui.branchColors matched its keys against the part of a branch name before the first slash. The pattern ^<key>(/|$), with the key escaped, matches the same branches. If gui.branchColorPatterns is set, gui.branchColors has no effect; in that case the migration removes it. This check is done per file. So if the global config sets gui.branchColorPatterns and a repo config sets only gui.branchColors, the repo's colors were ignored so far, and now they apply. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The next commit needs it for a single color. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
If several patterns in gui.branchColorPatterns match a branch, the color it gets is picked at random, and it can change from one render to the next. The patterns are kept in a Go map, and Go randomizes the order in which a map is iterated. Keep the patterns in a list instead, in the order in which they are written, and let the first match win. If a repo's config file has patterns too, put them in front of those of the global config file, because they are more specific. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
We are about to add overrides of gui.theme for dark and light backgrounds. Author and branch colors need them too, because a color that reads well on a dark background may be hard to read on a light one. Move them into gui.theme, so that the overrides cover them without a mechanism of their own. The migration of gui.branchColors creates gui.branchColorPatterns, so it now has to run before the moves. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Since gui.colorScheme exists, the name reads as if the function set that config. That gets more confusing once gui.colorScheme decides which theme the function applies. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
We are about to add gui.darkTheme and gui.lightTheme, with the same type as gui.theme. The schema generator stores a struct type as one definition that all its properties refer to, and setDefaultVals writes the defaults of each path into that definition. The overrides would then claim the defaults of gui.theme, both in the schema and in Config.md. Give each property whose struct definition is shared a copy of its own. In Config.md, print only the description of every copy after the first, so that the fields aren't listed several times. Nothing in the config shares a struct definition yet, so the generated files don't change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A color that reads well on a dark background can be hard to read on a light one, and the other way round. If you switch your terminal between dark and light, there is often no single set of theme colors that works for both (#4366). Add two overrides of gui.theme, one for each kind of background. gui.colorScheme, or else what the terminal tells us, decides which one applies. A field that is set in the override replaces the one in gui.theme. Author colors and branch color patterns are merged by entry instead, so that an override doesn't have to repeat the entries it doesn't change. When the terminal's background changes, re-apply the theme and re-render all views, not only the ones that show author colors. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A later commit shows the hashes of commits outside the bisect range in a dimmer variant of the default text color. A darker shade of a terminal palette color can't be derived, because we don't know what the palette is, so leave the shading to the terminal and use its faint attribute, SGR 2. In gookit/color that attribute is called OpFuzzy. Terminals that don't implement SGR 2 render the text in its normal color. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Config.md lists strikethrough as a modifier for theme colors, but only GetTextStyle knows it. GetGocuiStyle turns an unknown name into white, and white OR-ed with a palette color is white. So if you set a border color to [red, strikethrough], you get a white border without strikethrough. The same goes for the parts of the selected line, options text and default text colors that gocui draws. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The faint attribute makes text recede on dark and light backgrounds alike, without having to pick a gray for each. Let users use it in the theme. Some theme colors go through both GetTextStyle and GetGocuiStyle, so both have to know it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
While bisecting, the hashes of the commits outside the bisect range are black. On a dark gray background this makes them recede, but on a black one they are invisible, and on a light one they stand out more than any other hash. Draw them in faint text instead. The terminal shades faint text toward its background, whatever that is. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Some theme colors can't have one default that suits both dark and light backgrounds. A gray background for the selected line of an inactive view has to be lighter than the terminal's background if that is dark, and darker if it is light. Give such fields a default for each kind of background. Derive it from the terminal's background color if the terminal tells us, so that it keeps the same distance from the background however dark or light that is, and takes on its tint. Otherwise, assume a black or white background. These defaults can't be the defaults of gui.theme. We would then have to tell whether a value there came from the user or from the built-in defaults, because only the user's value should win over a background default. Keep them apart from the user config instead, and leave these fields empty in the defaults of gui.theme, so that a value there always comes from the user. Tests ensure that no field has both kinds of defaults, and that both kinds of background set the same fields. Start with inactiveViewSelectedLineBgColor: the background mixed with 30% white if it is dark (#4d4d4d on black), or with 15% black if it is light (#d9d9d9 on white). A gray background shows where the selection is in a view without the focus more clearly than the bold text we used so far. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The borders of inactive windows are drawn in the terminal's default text color, so they are as prominent as the text inside the windows. Draw them in faint text instead. The terminal shades faint text toward its background, so this works on dark and light backgrounds alike, and also on backgrounds that are neither black nor white. The titles of inactive windows use the same color, so they are dimmed too. Terminals that don't support faint text draw the borders in the default color, as before. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
On a light background, the selected line is black text on the palette's blue. With most palettes, this is hard to read. Light palettes make all their colors dark enough to read as text on the light background, so none of them works well as a background for text. On a light background, mix 25% of #0064ff into the terminal's background instead. On white, this gives #bfd8ff. The colored text on the selected line then stays as readable as it is elsewhere. On a dark background, keep the palette's blue. Dark palettes make it dark enough to work as a background, and it keeps working on terminals with only 8 colors. There, a color mixed from a dark background would turn into black. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
gocui draws the palette colors 0 to 7 on the selected line in their bright variants. This was meant for the blue highlight on a dark background, but in most dark palettes the bright variants are so close to the normal ones that it's barely visible. Elsewhere it makes the text harder to read. In many palettes, the bright variants are lighter, and they don't work on the light highlight of a light background. Solarized maps most of its bright colors to its grays, so colored text on the selected line turns gray. Draw the text of the selected line in the same colors as on the other lines. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The text of the selected line is always bold. Some users don't like this (#2304), but there is no way to turn it off. Setting selectedLineBgColor doesn't help. Its attributes apply to the text too, so it can add bold, but it can't take it away. Add gui.theme.selectedLineFgColor for the text of the selected line, in focused and unfocused views alike. Its attributes are added to those of the text, and a color replaces the colors of the text. It is [bold] by default, so nothing changes unless you set it; 'default' leaves the text as it is. Putting bold into the default of selectedLineBgColor instead wouldn't work well. To turn it off, you would have to replace the whole list, and lose the color that is computed from the terminal's background. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
stefanhaller
force-pushed
the
dark-and-light-themes
branch
from
September 27, 2026 06:16
00c87c0 to
5196c4f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Make it possible to override
gui.themecolors for light or dark backgrounds, by setting them ingui.darkThemeorgui.lightTheme, respectively; this is often necessary when there isn't a single color that looks good in both.Use this to provide better defaults for the background color of a selected line, and to add a color for the background of an inactive selected line (used in unfocused views), which didn't have one by default.
Also, provide a way to turn off the "bold" highlighting of the selected line, which was hard-coded and couldn't be changed; there's a new config setting
gui.theme.selectedLineFgColorthat is[bold]by default (so existing behavior is unchanged), but can be set to[default]to remove the bold. This addresses #2304.