diff --git a/codex-rs/tui/src/history_cell.rs b/codex-rs/tui/src/history_cell.rs index 0e9f25332..c2aafdd52 100644 --- a/codex-rs/tui/src/history_cell.rs +++ b/codex-rs/tui/src/history_cell.rs @@ -545,24 +545,17 @@ impl HistoryCell { } else { for (idx, PlanItemArg { step, status }) in plan.into_iter().enumerate() { let num = idx + 1; - let (icon, style): (&str, Style) = match status { - StepStatus::Completed => ("✓", Style::default().fg(Color::Green)), - StepStatus::InProgress => ( - "▶", - Style::default() - .fg(Color::Yellow) - .add_modifier(Modifier::BOLD), - ), - StepStatus::Pending => ("○", Style::default().fg(Color::Gray)), + let icon_span: Span = match status { + StepStatus::Completed => Span::from("✓").fg(Color::Green), + StepStatus::InProgress => Span::from("▶").fg(Color::Yellow).bold(), + StepStatus::Pending => Span::from("○").fg(Color::Gray), }; - let prefix = vec![ - Span::raw(format!("{num:>2}. [")), - Span::styled(icon.to_string(), style), - Span::raw("] "), - ]; - let mut spans = prefix; - spans.push(Span::raw(step)); - lines.push(Line::from(spans)); + lines.push(Line::from(vec![ + format!("{num:>2}. [").into(), + icon_span, + "] ".into(), + step.into(), + ])); } } diff --git a/codex-rs/tui/src/insert_history.rs b/codex-rs/tui/src/insert_history.rs index efd08a71c..87d88b7f0 100644 --- a/codex-rs/tui/src/insert_history.rs +++ b/codex-rs/tui/src/insert_history.rs @@ -216,18 +216,18 @@ where { let mut fg = Color::Reset; let mut bg = Color::Reset; - let mut modifier = Modifier::empty(); + let mut last_modifier = Modifier::empty(); for span in content { - let mut next_modifier = modifier; - next_modifier.insert(span.style.add_modifier); - next_modifier.remove(span.style.sub_modifier); - if next_modifier != modifier { + let mut modifier = Modifier::empty(); + modifier.insert(span.style.add_modifier); + modifier.remove(span.style.sub_modifier); + if modifier != last_modifier { let diff = ModifierDiff { - from: modifier, - to: next_modifier, + from: last_modifier, + to: modifier, }; diff.queue(&mut writer)?; - modifier = next_modifier; + last_modifier = modifier; } let next_fg = span.style.fg.unwrap_or(Color::Reset); let next_bg = span.style.bg.unwrap_or(Color::Reset); @@ -250,3 +250,37 @@ where SetAttribute(crossterm::style::Attribute::Reset), ) } + +#[cfg(test)] +mod tests { + #![allow(clippy::unwrap_used)] + use super::*; + + #[test] + fn writes_bold_then_regular_spans() { + use ratatui::style::Stylize; + + let spans = ["A".bold(), "B".into()]; + + let mut actual: Vec = Vec::new(); + write_spans(&mut actual, spans.iter()).unwrap(); + + let mut expected: Vec = Vec::new(); + queue!( + expected, + SetAttribute(crossterm::style::Attribute::Bold), + Print("A"), + SetAttribute(crossterm::style::Attribute::NormalIntensity), + Print("B"), + SetForegroundColor(CColor::Reset), + SetBackgroundColor(CColor::Reset), + SetAttribute(crossterm::style::Attribute::Reset), + ) + .unwrap(); + + assert_eq!( + String::from_utf8(actual).unwrap(), + String::from_utf8(expected).unwrap() + ); + } +}