Light terminal themes: use the terminal's text color too

On a light background (Catppuccin Latte in Ghostty on macOS) the panes
kept palette color 0, a dark grey slab with white text. The probe now also
asks for the text color (OSC 10). Light backgrounds are used as well, with
text, borders and titles in the terminal's text color, input fields and
buttons in a light shade of it, and the active tab drawn in it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019reK4DUGYqDUjniWYJvwUW
This commit is contained in:
2026-10-21 11:59:44 +02:00
co-authored by Claude Opus 5.5
parent d2e868293f
commit 08d3417b05
6 changed files with 114 additions and 50 deletions
+27 -4
View File
@@ -18,6 +18,7 @@ func TestParseTerminalAnswers(t *testing.T) {
hasBG bool
}{
{"ghostty", "\x1b_Gi=31;OK\x1b\\\x1b]11;rgb:1e1e/1e1e/2e2e\x1b\\\x1b[?62;22c", true, color.RGBA{30, 30, 46, 255}, true},
{"text color too", "\x1b]10;rgb:4c4c/4f4f/6969\x1b\\\x1b]11;rgb:efef/f1f1/f5f5\x1b\\\x1b[?62c", false, color.RGBA{239, 241, 245, 255}, true},
{"bel and two digits", "\x1b]11;rgb:ff/80/00\a\x1b[?1;2c", false, color.RGBA{255, 128, 0, 255}, true},
{"one digit", "\x1b]11;rgb:f/0/8\x1b\\\x1b[?6c", false, color.RGBA{255, 0, 136, 255}, true},
{"only device attributes", "\x1b[?1;2c", false, color.RGBA{}, false},
@@ -37,10 +38,10 @@ func TestUseTerminalBackground(t *testing.T) {
// a terminal nothing else looks up).
t.Setenv("COLORTERM", "")
t.Setenv("TCELL_TRUECOLOR", "")
defer func(old tcell.Color) { tview.Styles.PrimitiveBackgroundColor = old }(tview.Styles.PrimitiveBackgroundColor)
defer func(old tview.Theme, tab string) { tview.Styles, activeTabTag = old, tab }(tview.Styles, activeTabTag)
env := func(m map[string]string) func(string) string { return func(k string) string { return m[k] } }
dark := terminalInfo{bg: color.RGBA{30, 30, 46, 255}, hasBG: true}
light := terminalInfo{bg: color.RGBA{239, 241, 245, 255}, hasBG: true}
light := terminalInfo{bg: color.RGBA{239, 241, 245, 255}, hasBG: true, fg: color.RGBA{76, 79, 105, 255}, hasFG: true}
truecolor := env(map[string]string{"COLORTERM": "truecolor"})
for _, tc := range []struct {
@@ -53,7 +54,7 @@ func TestUseTerminalBackground(t *testing.T) {
{"no true color", dark, env(map[string]string{"TERM": "vt100"}), false},
{"ghostty without COLORTERM", dark, env(map[string]string{"TERM": "xterm-ghostty"}), true},
{"true color disabled for tcell", dark, env(map[string]string{"TERM": "xterm-ghostty", "TCELL_TRUECOLOR": "disable"}), false},
{"light background keeps the default", light, truecolor, false},
{"light background", light, truecolor, true},
{"no answer", terminalInfo{}, truecolor, false},
} {
tview.Styles.PrimitiveBackgroundColor = tcell.ColorBlack
@@ -63,10 +64,32 @@ func TestUseTerminalBackground(t *testing.T) {
}
want := tcell.ColorBlack
if tc.want {
want = tcell.NewRGBColor(30, 30, 46)
want = rgb(tc.info.bg)
}
if tview.Styles.PrimitiveBackgroundColor != want {
t.Errorf("%s: background %v", tc.name, tview.Styles.PrimitiveBackgroundColor)
}
}
}
func TestLightBackgroundUsesTheTextColor(t *testing.T) {
defer func(old tview.Theme, tab string) { tview.Styles, activeTabTag = old, tab }(tview.Styles, activeTabTag)
latte := terminalInfo{bg: color.RGBA{239, 241, 245, 255}, hasBG: true, fg: color.RGBA{76, 79, 105, 255}, hasFG: true}
useTerminalBackground(latte, func(k string) string { return map[string]string{"COLORTERM": "truecolor"}[k] })
st := tview.Styles
if st.PrimaryTextColor != tcell.NewRGBColor(76, 79, 105) || st.BorderColor != st.PrimaryTextColor {
t.Errorf("text %v, borders %v", st.PrimaryTextColor, st.BorderColor)
}
if st.ContrastBackgroundColor == tcell.ColorBlue {
t.Error("input fields should not stay palette blue on a light background")
}
if activeTabTag != "[#eff1f5:#4c4f69]" {
t.Errorf("active tab %s", activeTabTag)
}
// Without a text color answer the text is black.
tview.Styles = st
useTerminalBackground(terminalInfo{bg: latte.bg, hasBG: true}, func(k string) string { return map[string]string{"COLORTERM": "truecolor"}[k] })
if tview.Styles.PrimaryTextColor != tcell.NewRGBColor(0, 0, 0) {
t.Errorf("fallback text %v", tview.Styles.PrimitiveBackgroundColor)
}
}