mirror of
https://github.com/openai/codex.git
synced 2026-11-10 21:00:47 +00:00
Improve TUI contrast, keyboard hints, and picker layouts (#46680)
## Why Theme colors and dimmed text can lose contrast against terminal and shaded backgrounds. Pickers also need to keep controls and the selected result visible when space is limited. ## What changed - Add shared blue accents and contrast-aware foregrounds that account for painted backgrounds and terminal color depth, with terminal-default fallbacks for limited palettes. - Apply readable colors to footer text, status lines, prompt attachment labels, and diff content. Remove dimming from syntax-highlighted diff text so it does not undo contrast correction. - Use compact shortcut labels such as `ctrl+c`, emphasize complete key combinations, and separate composer footer actions with ` · `. - Add an opt-in picker presentation with full-width selection, filled tabs, separate overflow indicators, and navigation based on visible rows. Enable it for `/keymap`, reserving result space to keep controls stable across filtering and tab changes. ## Testing Add regression tests and snapshots for contrast after palette conversion, shaded diff backgrounds, shortcut typography, picker resizing and pagination, Unicode tab truncation, and stable `/keymap` geometry. GitOrigin-RevId: f3c71879d3bcc4e3b29d70e63cf377dea5914916
This commit is contained in:
@@ -71,7 +71,25 @@ fn mermaid_styles_follow_the_supplied_theme() {
|
||||
("light", themes.get(EmbeddedThemeName::SolarizedLight)),
|
||||
("fallback", &fallback),
|
||||
] {
|
||||
let lines = super::render("flowchart LR; A[请求] --> B[Reply]", Some(40), theme).unwrap();
|
||||
let colors = if name == "light" {
|
||||
crate::terminal_probe::DefaultColors {
|
||||
fg: (30, 30, 30),
|
||||
bg: (255, 255, 255),
|
||||
}
|
||||
} else {
|
||||
crate::terminal_probe::DefaultColors {
|
||||
fg: (220, 220, 220),
|
||||
bg: (20, 20, 20),
|
||||
}
|
||||
};
|
||||
let lines = crate::terminal_palette::with_test_default_colors(colors, || {
|
||||
super::render(
|
||||
"flowchart LR; A[请求] --> B[Reply]",
|
||||
/*width*/ Some(40),
|
||||
theme,
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
let styled = lines
|
||||
.into_iter()
|
||||
.map(|line| {
|
||||
|
||||
-1
@@ -1,6 +1,5 @@
|
||||
---
|
||||
source: tui/src/markdown_render/mermaid_tests.rs
|
||||
assertion_line: 88
|
||||
expression: "cases.join(\"\\n\\n\")"
|
||||
---
|
||||
dark
|
||||
|
||||
+9
-9
@@ -6,11 +6,11 @@ expression: presentations
|
||||
Text::from_iter([
|
||||
Line::from_iter([
|
||||
Span::from("plain "),
|
||||
Span::from("plain").cyan().underlined(),
|
||||
Span::from("plain").fg(Color::Reset).underlined(),
|
||||
Span::from(" "),
|
||||
Span::from("code").fg(Color::Rgb(166, 227, 161)),
|
||||
Span::from(" "),
|
||||
Span::from("code").cyan().underlined(),
|
||||
Span::from("code").fg(Color::Reset).underlined(),
|
||||
]),
|
||||
Line::default(),
|
||||
Line::from_iter([
|
||||
@@ -20,23 +20,23 @@ expression: presentations
|
||||
Line::from(Span::from("━━━━━━━━━━").dim()),
|
||||
Line::from_iter([
|
||||
Span::from(" "),
|
||||
Span::from("docs").cyan().underlined(),
|
||||
Span::from("docs").fg(Color::Reset).underlined(),
|
||||
]),
|
||||
]),
|
||||
Text::from_iter([
|
||||
Line::from_iter([
|
||||
Span::from("plain "),
|
||||
Span::from("plain").cyan().underlined(),
|
||||
Span::from("plain").fg(Color::Reset).underlined(),
|
||||
Span::from(" ("),
|
||||
Span::from("https://example.com").cyan().underlined(),
|
||||
Span::from("https://example.com").fg(Color::Reset).underlined(),
|
||||
Span::from(")"),
|
||||
Span::from(" "),
|
||||
Span::from("code").fg(Color::Rgb(166, 227, 161)),
|
||||
]),
|
||||
Line::from_iter([
|
||||
Span::from("code").cyan().underlined(),
|
||||
Span::from("code").fg(Color::Reset).underlined(),
|
||||
Span::from(" ("),
|
||||
Span::from("https://example.com").cyan().underlined(),
|
||||
Span::from("https://example.com").fg(Color::Reset).underlined(),
|
||||
Span::from(")"),
|
||||
]),
|
||||
Line::default(),
|
||||
@@ -47,9 +47,9 @@ expression: presentations
|
||||
Line::from(Span::from("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━").dim()),
|
||||
Line::from_iter([
|
||||
Span::from(" "),
|
||||
Span::from("docs").cyan().underlined(),
|
||||
Span::from("docs").fg(Color::Reset).underlined(),
|
||||
Span::from(" ("),
|
||||
Span::from("https://example.com/docs").cyan().underlined(),
|
||||
Span::from("https://example.com/docs").fg(Color::Reset).underlined(),
|
||||
Span::from(")"),
|
||||
]),
|
||||
]),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use super::WebLinkDisplay;
|
||||
use crate::markdown_render::render_markdown_lines_with_width_cwd_and_hidden_link_destinations;
|
||||
use crate::markdown_render::render_streaming_markdown_lines_with_width_and_cwd;
|
||||
use crate::style::accent_color;
|
||||
use crate::terminal_hyperlinks::HyperlinkLine;
|
||||
use crate::terminal_hyperlinks::TerminalHyperlink;
|
||||
use crate::terminal_hyperlinks::visible_lines;
|
||||
@@ -49,23 +50,29 @@ fn supporting_terminals_render_only_the_styled_label_and_keep_its_target() {
|
||||
] {
|
||||
let display = WebLinkDisplay::for_terminal(&terminal(name), /*term*/ None);
|
||||
for (markdown, label) in [
|
||||
("[label](https://example.com)", "label".cyan().underlined()),
|
||||
(
|
||||
"[label](https://example.com)",
|
||||
"label".fg(accent_color()).underlined(),
|
||||
),
|
||||
(
|
||||
"[`label`](https://example.com)",
|
||||
"label".cyan().underlined(),
|
||||
"label".fg(accent_color()).underlined(),
|
||||
),
|
||||
(
|
||||
"[**label**](https://example.com)",
|
||||
"label".cyan().bold().underlined(),
|
||||
"label".fg(accent_color()).bold().underlined(),
|
||||
),
|
||||
(
|
||||
"[*label*](https://example.com)",
|
||||
"label".cyan().italic().underlined(),
|
||||
"label".fg(accent_color()).italic().underlined(),
|
||||
),
|
||||
(
|
||||
"[<b>](https://example.com)",
|
||||
"<b>".fg(accent_color()).underlined(),
|
||||
),
|
||||
("[<b>](https://example.com)", "<b>".cyan().underlined()),
|
||||
(
|
||||
"[https://example.com](https://example.com)",
|
||||
"https://example.com".cyan().underlined(),
|
||||
"https://example.com".fg(accent_color()).underlined(),
|
||||
),
|
||||
] {
|
||||
let label_width = label.width();
|
||||
|
||||
Reference in New Issue
Block a user