Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/tui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ rmcp = { version = "2.2.0", default-features = false, features = ["auth", "clien
rustls.workspace = true
qrcode = { version = "0.14", default-features = false }
similar = "3"
ansi-to-tui = { version = "8.0.1", default-features = false }
syntect = { version = "5.2", default-features = false, features = ["default-fancy"] }
serde.workspace = true
serde_json = { workspace = true, features = ["preserve_order"] }
Expand Down
66 changes: 66 additions & 0 deletions crates/tui/src/tui/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2662,6 +2662,72 @@ fn render_card_detail_line(
lines
}

/// `render_card_detail_line` for a row whose text carries its own SGR
/// colours: every segment's style is patched over `value_style`, so the
/// tool's colour wins where it set one and the cell's own ink (dim, state,
/// file:line emphasis) shows through where it did not. `text` is the row's
/// plain text (what the segments concatenate to); wrapping follows the same
/// boundaries as the plain path.
fn render_card_detail_line_styled(
label: Option<&str>,
text: &str,
segments: &[tool_output::StyledSegment],
value_style: Style,
width: u16,
) -> Vec<Line<'static>> {
let label_text = label.map(|text| format!("{text}:"));
let prefix_width = UnicodeWidthStr::width(TRANSCRIPT_RAIL)
+ label_text.as_deref().map_or(0, UnicodeWidthStr::width)
+ usize::from(label.is_some());
let content_width = usize::from(width).saturating_sub(prefix_width).max(1);

let parts = wrap_text(text, content_width);
let split = tool_output::split_segments(segments, &parts);

let mut lines = Vec::new();
for (idx, part) in split.into_iter().enumerate() {
let mut spans = vec![Span::styled(
TRANSCRIPT_RAIL.to_string(),
Style::default().fg(palette::TEXT_DIM),
)];
if idx == 0 {
if let Some(label_text) = label_text.as_deref() {
spans.push(Span::styled(
label_text.to_string(),
tool_detail_label_style(),
));
spans.push(Span::raw(" "));
}
} else if let Some(label_text) = label_text.as_deref() {
spans.push(Span::raw(
" ".repeat(UnicodeWidthStr::width(label_text) + 1),
));
}
for (text, style) in part {
spans.push(Span::styled(text, value_style.patch(style)));
}
lines.push(Line::from(spans));
}
lines
}

/// `render_card_detail_line_single` for a coloured row: one line, never
/// wrapped, so an intact path or URL keeps the same hitbox with or without
/// colour.
fn render_card_detail_line_single_styled(
label: Option<&str>,
segments: &[tool_output::StyledSegment],
value_style: Style,
) -> Line<'static> {
let mut line = render_card_detail_line_single(label, "", value_style);
line.spans.pop();
for (text, style) in segments {
line.spans
.push(Span::styled(text.clone(), value_style.patch(*style)));
}
line
}

fn render_card_detail_line_single(
label: Option<&str>,
value: &str,
Expand Down
Loading
Loading