prefer ratatui Stylized for constructing lines/spans (#3068)
no functional change, just simplifying ratatui styling and adding guidance in AGENTS.md for future.
This commit is contained in:
@@ -15,7 +15,6 @@ use ratatui::style::Modifier;
|
||||
use ratatui::style::Style;
|
||||
use ratatui::style::Stylize;
|
||||
use ratatui::text::Line;
|
||||
use ratatui::text::Span;
|
||||
use ratatui::widgets::Paragraph;
|
||||
use ratatui::widgets::WidgetRef;
|
||||
use ratatui::widgets::Wrap;
|
||||
@@ -120,20 +119,14 @@ impl AuthModeWidget {
|
||||
fn render_pick_mode(&self, area: Rect, buf: &mut Buffer) {
|
||||
let mut lines: Vec<Line> = vec![
|
||||
Line::from(vec![
|
||||
Span::raw("> "),
|
||||
Span::styled(
|
||||
"Sign in with ChatGPT to use Codex as part of your paid plan",
|
||||
Style::default().add_modifier(Modifier::BOLD),
|
||||
),
|
||||
"> ".into(),
|
||||
"Sign in with ChatGPT to use Codex as part of your paid plan".bold(),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::raw(" "),
|
||||
Span::styled(
|
||||
"or connect an API key for usage-based billing",
|
||||
Style::default().add_modifier(Modifier::BOLD),
|
||||
),
|
||||
" ".into(),
|
||||
"or connect an API key for usage-based billing".bold(),
|
||||
]),
|
||||
Line::from(""),
|
||||
"".into(),
|
||||
];
|
||||
|
||||
// If the user is already authenticated but the method differs from their
|
||||
@@ -150,8 +143,8 @@ impl AuthModeWidget {
|
||||
to_label(current),
|
||||
to_label(self.preferred_auth_method)
|
||||
);
|
||||
lines.push(Line::from(msg).style(Style::default()));
|
||||
lines.push(Line::from(""));
|
||||
lines.push(msg.into());
|
||||
lines.push("".into());
|
||||
}
|
||||
|
||||
let create_mode_item = |idx: usize,
|
||||
@@ -168,7 +161,7 @@ impl AuthModeWidget {
|
||||
text.to_string().cyan(),
|
||||
])
|
||||
} else {
|
||||
Line::from(format!(" {}. {text}", idx + 1))
|
||||
format!(" {}. {text}", idx + 1).into()
|
||||
};
|
||||
|
||||
let line2 = if is_selected {
|
||||
@@ -207,19 +200,15 @@ impl AuthModeWidget {
|
||||
api_key_label,
|
||||
"Pay for what you use",
|
||||
));
|
||||
lines.push(Line::from(""));
|
||||
lines.push("".into());
|
||||
lines.push(
|
||||
// AE: Following styles.md, this should probably be Cyan because it's a user input tip.
|
||||
// But leaving this for a future cleanup.
|
||||
Line::from(" Press Enter to continue")
|
||||
.style(Style::default().add_modifier(Modifier::DIM)),
|
||||
" Press Enter to continue".dim().into(),
|
||||
);
|
||||
if let Some(err) = &self.error {
|
||||
lines.push(Line::from(""));
|
||||
lines.push(Line::from(Span::styled(
|
||||
err.as_str(),
|
||||
Style::default().fg(Color::Red),
|
||||
)));
|
||||
lines.push("".into());
|
||||
lines.push(err.as_str().red().into());
|
||||
}
|
||||
|
||||
Paragraph::new(lines)
|
||||
@@ -228,28 +217,23 @@ impl AuthModeWidget {
|
||||
}
|
||||
|
||||
fn render_continue_in_browser(&self, area: Rect, buf: &mut Buffer) {
|
||||
let mut spans = vec![Span::from("> ")];
|
||||
let mut spans = vec!["> ".into()];
|
||||
// Schedule a follow-up frame to keep the shimmer animation going.
|
||||
self.request_frame
|
||||
.schedule_frame_in(std::time::Duration::from_millis(100));
|
||||
spans.extend(shimmer_spans("Finish signing in via your browser"));
|
||||
let mut lines = vec![Line::from(spans), Line::from("")];
|
||||
let mut lines = vec![spans.into(), "".into()];
|
||||
|
||||
let sign_in_state = self.sign_in_state.read().unwrap();
|
||||
if let SignInState::ChatGptContinueInBrowser(state) = &*sign_in_state
|
||||
&& !state.auth_url.is_empty()
|
||||
{
|
||||
lines.push(Line::from(" If the link doesn't open automatically, open the following link to authenticate:"));
|
||||
lines.push(Line::from(vec![
|
||||
Span::raw(" "),
|
||||
state.auth_url.as_str().cyan().underlined(),
|
||||
]));
|
||||
lines.push(Line::from(""));
|
||||
lines.push(" If the link doesn't open automatically, open the following link to authenticate:".into());
|
||||
lines.push(vec![" ".into(), state.auth_url.as_str().cyan().underlined()].into());
|
||||
lines.push("".into());
|
||||
}
|
||||
|
||||
lines.push(
|
||||
Line::from(" Press Esc to cancel").style(Style::default().add_modifier(Modifier::DIM)),
|
||||
);
|
||||
lines.push(" Press Esc to cancel".dim().into());
|
||||
Paragraph::new(lines)
|
||||
.wrap(Wrap { trim: false })
|
||||
.render(area, buf);
|
||||
@@ -257,35 +241,28 @@ impl AuthModeWidget {
|
||||
|
||||
fn render_chatgpt_success_message(&self, area: Rect, buf: &mut Buffer) {
|
||||
let lines = vec![
|
||||
Line::from("✓ Signed in with your ChatGPT account").fg(Color::Green),
|
||||
Line::from(""),
|
||||
Line::from("> Before you start:"),
|
||||
Line::from(""),
|
||||
Line::from(" Decide how much autonomy you want to grant Codex"),
|
||||
"✓ Signed in with your ChatGPT account".fg(Color::Green).into(),
|
||||
"".into(),
|
||||
"> Before you start:".into(),
|
||||
"".into(),
|
||||
" Decide how much autonomy you want to grant Codex".into(),
|
||||
Line::from(vec![
|
||||
Span::raw(" For more details see the "),
|
||||
Span::styled(
|
||||
"\u{1b}]8;;https://github.com/openai/codex\u{7}Codex docs\u{1b}]8;;\u{7}",
|
||||
Style::default().add_modifier(Modifier::UNDERLINED),
|
||||
),
|
||||
" For more details see the ".into(),
|
||||
"\u{1b}]8;;https://github.com/openai/codex\u{7}Codex docs\u{1b}]8;;\u{7}".underlined(),
|
||||
])
|
||||
.style(Style::default().add_modifier(Modifier::DIM)),
|
||||
Line::from(""),
|
||||
Line::from(" Codex can make mistakes"),
|
||||
Line::from(" Review the code it writes and commands it runs")
|
||||
.style(Style::default().add_modifier(Modifier::DIM)),
|
||||
Line::from(""),
|
||||
Line::from(" Powered by your ChatGPT account"),
|
||||
.dim(),
|
||||
"".into(),
|
||||
" Codex can make mistakes".into(),
|
||||
" Review the code it writes and commands it runs".dim().into(),
|
||||
"".into(),
|
||||
" Powered by your ChatGPT account".into(),
|
||||
Line::from(vec![
|
||||
Span::raw(" Uses your plan's rate limits and "),
|
||||
Span::styled(
|
||||
"\u{1b}]8;;https://chatgpt.com/#settings\u{7}training data preferences\u{1b}]8;;\u{7}",
|
||||
Style::default().add_modifier(Modifier::UNDERLINED),
|
||||
),
|
||||
" Uses your plan's rate limits and ".into(),
|
||||
"\u{1b}]8;;https://chatgpt.com/#settings\u{7}training data preferences\u{1b}]8;;\u{7}".underlined(),
|
||||
])
|
||||
.style(Style::default().add_modifier(Modifier::DIM)),
|
||||
Line::from(""),
|
||||
Line::from(" Press Enter to continue").fg(Color::Cyan),
|
||||
.dim(),
|
||||
"".into(),
|
||||
" Press Enter to continue".fg(Color::Cyan).into(),
|
||||
];
|
||||
|
||||
Paragraph::new(lines)
|
||||
@@ -294,7 +271,11 @@ impl AuthModeWidget {
|
||||
}
|
||||
|
||||
fn render_chatgpt_success(&self, area: Rect, buf: &mut Buffer) {
|
||||
let lines = vec![Line::from("✓ Signed in with your ChatGPT account").fg(Color::Green)];
|
||||
let lines = vec![
|
||||
"✓ Signed in with your ChatGPT account"
|
||||
.fg(Color::Green)
|
||||
.into(),
|
||||
];
|
||||
|
||||
Paragraph::new(lines)
|
||||
.wrap(Wrap { trim: false })
|
||||
@@ -302,7 +283,7 @@ impl AuthModeWidget {
|
||||
}
|
||||
|
||||
fn render_env_var_found(&self, area: Rect, buf: &mut Buffer) {
|
||||
let lines = vec![Line::from("✓ Using OPENAI_API_KEY").fg(Color::Green)];
|
||||
let lines = vec!["✓ Using OPENAI_API_KEY".fg(Color::Green).into()];
|
||||
|
||||
Paragraph::new(lines)
|
||||
.wrap(Wrap { trim: false })
|
||||
@@ -311,13 +292,11 @@ impl AuthModeWidget {
|
||||
|
||||
fn render_env_var_missing(&self, area: Rect, buf: &mut Buffer) {
|
||||
let lines = vec![
|
||||
Line::from(
|
||||
" To use Codex with the OpenAI API, set OPENAI_API_KEY in your environment",
|
||||
)
|
||||
.style(Style::default().fg(Color::Cyan)),
|
||||
Line::from(""),
|
||||
Line::from(" Press Enter to return")
|
||||
.style(Style::default().add_modifier(Modifier::DIM)),
|
||||
" To use Codex with the OpenAI API, set OPENAI_API_KEY in your environment"
|
||||
.fg(Color::Cyan)
|
||||
.into(),
|
||||
"".into(),
|
||||
" Press Enter to return".dim().into(),
|
||||
];
|
||||
|
||||
Paragraph::new(lines)
|
||||
|
||||
@@ -9,10 +9,8 @@ use ratatui::layout::Rect;
|
||||
use ratatui::prelude::Widget;
|
||||
use ratatui::style::Color;
|
||||
use ratatui::style::Modifier;
|
||||
use ratatui::style::Style;
|
||||
use ratatui::style::Stylize;
|
||||
use ratatui::text::Line;
|
||||
use ratatui::text::Span;
|
||||
use ratatui::widgets::Paragraph;
|
||||
use ratatui::widgets::WidgetRef;
|
||||
use ratatui::widgets::Wrap;
|
||||
@@ -41,30 +39,25 @@ impl WidgetRef for &TrustDirectoryWidget {
|
||||
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
|
||||
let mut lines: Vec<Line> = vec![
|
||||
Line::from(vec![
|
||||
Span::raw("> "),
|
||||
Span::styled(
|
||||
"You are running Codex in ",
|
||||
Style::default().add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(self.cwd.to_string_lossy().to_string()),
|
||||
"> ".into(),
|
||||
"You are running Codex in ".bold(),
|
||||
self.cwd.to_string_lossy().to_string().into(),
|
||||
]),
|
||||
Line::from(""),
|
||||
"".into(),
|
||||
];
|
||||
|
||||
if self.is_git_repo {
|
||||
lines.push(Line::from(
|
||||
" Since this folder is version controlled, you may wish to allow Codex",
|
||||
));
|
||||
lines.push(Line::from(
|
||||
" to work in this folder without asking for approval.",
|
||||
));
|
||||
lines.push(
|
||||
" Since this folder is version controlled, you may wish to allow Codex".into(),
|
||||
);
|
||||
lines.push(" to work in this folder without asking for approval.".into());
|
||||
} else {
|
||||
lines.push(Line::from(
|
||||
" Since this folder is not version controlled, we recommend requiring",
|
||||
));
|
||||
lines.push(Line::from(" approval of all edits and commands."));
|
||||
lines.push(
|
||||
" Since this folder is not version controlled, we recommend requiring".into(),
|
||||
);
|
||||
lines.push(" approval of all edits and commands.".into());
|
||||
}
|
||||
lines.push(Line::from(""));
|
||||
lines.push("".into());
|
||||
|
||||
let create_option =
|
||||
|idx: usize, option: TrustDirectorySelection, text: &str| -> Line<'static> {
|
||||
@@ -99,10 +92,10 @@ impl WidgetRef for &TrustDirectoryWidget {
|
||||
"Require approval of edits and commands",
|
||||
));
|
||||
}
|
||||
lines.push(Line::from(""));
|
||||
lines.push("".into());
|
||||
if let Some(error) = &self.error {
|
||||
lines.push(Line::from(format!(" {error}")).fg(Color::Red));
|
||||
lines.push(Line::from(""));
|
||||
lines.push("".into());
|
||||
}
|
||||
// AE: Following styles.md, this should probably be Cyan because it's a user input tip.
|
||||
// But leaving this for a future cleanup.
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::Rect;
|
||||
use ratatui::prelude::Widget;
|
||||
use ratatui::style::Modifier;
|
||||
use ratatui::style::Style;
|
||||
use ratatui::style::Stylize;
|
||||
use ratatui::text::Line;
|
||||
use ratatui::text::Span;
|
||||
use ratatui::widgets::WidgetRef;
|
||||
|
||||
use crate::onboarding::onboarding_screen::StepStateProvider;
|
||||
@@ -18,11 +16,8 @@ pub(crate) struct WelcomeWidget {
|
||||
impl WidgetRef for &WelcomeWidget {
|
||||
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
|
||||
let line = Line::from(vec![
|
||||
Span::raw(">_ "),
|
||||
Span::styled(
|
||||
"Welcome to Codex, OpenAI's command-line coding agent",
|
||||
Style::default().add_modifier(Modifier::BOLD),
|
||||
),
|
||||
">_ ".into(),
|
||||
"Welcome to Codex, OpenAI's command-line coding agent".bold(),
|
||||
]);
|
||||
line.render(area, buf);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user