Skip to content

Commit e896db1

Browse files
tui: hardcode xterm palette, shimmer blends between fg and bg (#4957)
Instead of querying all 256 terminal colors on startup, which was slow in some terminals, hardcode the default xterm palette. Additionally, tweak the shimmer so that it blends between default_fg and default_bg, instead of "dark gray" (according to the terminal) and pure white (regardless of terminal theme).
1 parent 96acb8a commit e896db1

File tree

4 files changed

+300
-268
lines changed

4 files changed

+300
-268
lines changed

codex-rs/tui/src/shimmer.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@ use ratatui::style::Style;
88
use ratatui::text::Span;
99

1010
use crate::color::blend;
11+
use crate::terminal_palette::default_bg;
1112
use crate::terminal_palette::default_fg;
12-
use crate::terminal_palette::terminal_palette;
13-
14-
const FALLBACK_DARK_GRAY: (u8, u8, u8) = (103, 103, 103);
1513

1614
static PROCESS_START: OnceLock<Instant> = OnceLock::new();
1715

@@ -35,11 +33,11 @@ pub(crate) fn shimmer_spans(text: &str) -> Vec<Span<'static>> {
3533
let has_true_color = supports_color::on_cached(supports_color::Stream::Stdout)
3634
.map(|level| level.has_16m)
3735
.unwrap_or(false);
38-
let band_half_width = 3.0;
36+
let band_half_width = 5.0;
3937

4038
let mut spans: Vec<Span<'static>> = Vec::with_capacity(chars.len());
41-
let default_fg = default_fg();
42-
let palette_dark_gray = terminal_palette().map(|palette| palette[8]);
39+
let base_color = default_fg().unwrap_or((128, 128, 128));
40+
let highlight_color = default_bg().unwrap_or((255, 255, 255));
4341
for (i, ch) in chars.iter().enumerate() {
4442
let i_pos = i as isize + padding as isize;
4543
let pos = pos as isize;
@@ -52,11 +50,8 @@ pub(crate) fn shimmer_spans(text: &str) -> Vec<Span<'static>> {
5250
0.0
5351
};
5452
let style = if has_true_color {
55-
let base = palette_dark_gray
56-
.or(default_fg)
57-
.unwrap_or(FALLBACK_DARK_GRAY);
5853
let highlight = t.clamp(0.0, 1.0);
59-
let (r, g, b) = blend((255, 255, 255), base, highlight);
54+
let (r, g, b) = blend(highlight_color, base_color, highlight * 0.9);
6055
// Allow custom RGB colors, as the implementation is thoughtfully
6156
// adjusting the level of the default foreground color.
6257
#[allow(clippy::disallowed_methods)]

codex-rs/tui/src/style.rs

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use crate::color::blend;
22
use crate::color::is_light;
3-
use crate::color::perceptual_distance;
3+
use crate::terminal_palette::best_color;
44
use crate::terminal_palette::default_bg;
5-
use crate::terminal_palette::terminal_palette;
65
use ratatui::style::Color;
76
use ratatui::style::Style;
87

@@ -25,25 +24,5 @@ pub fn user_message_bg(terminal_bg: (u8, u8, u8)) -> Color {
2524
} else {
2625
(255, 255, 255)
2726
};
28-
let bottom = terminal_bg;
29-
let Some(color_level) = supports_color::on_cached(supports_color::Stream::Stdout) else {
30-
return Color::default();
31-
};
32-
33-
let target = blend(top, bottom, 0.1);
34-
if color_level.has_16m {
35-
let (r, g, b) = target;
36-
Color::Rgb(r, g, b)
37-
} else if color_level.has_256
38-
&& let Some(palette) = terminal_palette()
39-
&& let Some((i, _)) = palette.into_iter().enumerate().min_by(|(_, a), (_, b)| {
40-
perceptual_distance(*a, target)
41-
.partial_cmp(&perceptual_distance(*b, target))
42-
.unwrap_or(std::cmp::Ordering::Equal)
43-
})
44-
{
45-
Color::Indexed(i as u8)
46-
} else {
47-
Color::default()
48-
}
27+
best_color(blend(top, terminal_bg, 0.1))
4928
}

0 commit comments

Comments
 (0)