mirror of
https://github.com/openai/codex.git
synced 2026-10-26 18:38:47 +00:00
Show hidden output line counts in compact terminal activity (#48761)
## What changed Replace generic output disclosure labels with counts such as `+ 5 lines (ctrl+t to expand)` for compact command activity, both live and in history. Count retained output lines hidden or clipped by the preview, excluding output discarded by storage limits. Use the configured `open_transcript` shortcut and omit the hint when it does not fit or the action is unbound. Invalidate cached layouts when keybindings change. Keep generic `Show details` labels for other hidden details and keep disclosure controls outside copyable and searchable text. ## Testing Add regression tests for live/history consistency, remapped and disabled shortcuts, and exclusion of hints from source text. Add snapshot coverage for fully visible output, hidden and clipped lines, command-only details, and storage-truncated output. GitOrigin-RevId: c468be9b88b69dc3ca1abdb6b7be023244d32a57
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
use super::model::ExecCell;
|
||||
use crate::exec_command::strip_bash_lc_and_escape;
|
||||
use crate::history_cell::ActivityDisclosure;
|
||||
use crate::history_cell::HistoryRenderMode;
|
||||
use crate::history_cell::activity_preview::DETAIL_PREVIEW_LINES;
|
||||
use crate::history_cell::activity_preview::clipped_line;
|
||||
@@ -16,17 +17,33 @@ use ratatui::style::Stylize;
|
||||
use ratatui::text::Line;
|
||||
|
||||
impl ExecCell {
|
||||
pub(super) fn command_has_hidden_details(&self, width: u16) -> bool {
|
||||
pub(super) fn command_disclosure(&self, width: u16) -> Option<ActivityDisclosure> {
|
||||
let [call] = self.group.calls.as_slice() else {
|
||||
return false;
|
||||
return None;
|
||||
};
|
||||
// Interaction output is intentionally absent from the expanded transcript.
|
||||
if !call.is_unified_exec_interaction()
|
||||
&& let Some(output) = &call.output
|
||||
{
|
||||
let retained = output.line_counts().1;
|
||||
let clipped = output
|
||||
.lines()
|
||||
.rev()
|
||||
.take(DETAIL_PREVIEW_LINES)
|
||||
.filter(|raw| ansi_escape_line(raw.as_ref()).width() + 4 > usize::from(width))
|
||||
.count();
|
||||
let hidden = retained.saturating_sub(DETAIL_PREVIEW_LINES) + clipped;
|
||||
if hidden > 0 {
|
||||
return Some(ActivityDisclosure::OutputLines(hidden));
|
||||
}
|
||||
}
|
||||
if !self
|
||||
.group
|
||||
.details
|
||||
.lines_after(/*after_calls*/ 1, width, HistoryRenderMode::Rich)
|
||||
.is_empty()
|
||||
{
|
||||
return true;
|
||||
return Some(ActivityDisclosure::Generic);
|
||||
}
|
||||
let script = strip_bash_lc_and_escape(&call.command);
|
||||
if script.lines().nth(/*n*/ 1).is_some()
|
||||
@@ -35,14 +52,17 @@ impl ExecCell {
|
||||
.first()
|
||||
.is_some_and(|header| header.width() > usize::from(width))
|
||||
{
|
||||
return true;
|
||||
return Some(ActivityDisclosure::Generic);
|
||||
}
|
||||
call.output.as_ref().is_some_and(|output| {
|
||||
output.line_counts().1 > DETAIL_PREVIEW_LINES
|
||||
|| output
|
||||
.transcript_lines()
|
||||
.any(|line| ansi_escape_line(line.as_ref()).width() + 4 > usize::from(width))
|
||||
})
|
||||
call.output
|
||||
.as_ref()
|
||||
.is_some_and(|output| {
|
||||
output.line_counts().1 > DETAIL_PREVIEW_LINES
|
||||
|| output.transcript_lines().any(|line| {
|
||||
ansi_escape_line(line.as_ref()).width() + 4 > usize::from(width)
|
||||
})
|
||||
})
|
||||
.then_some(ActivityDisclosure::Generic)
|
||||
}
|
||||
|
||||
pub(super) fn compact_command_lines(&self, width: u16) -> Vec<HyperlinkLine> {
|
||||
|
||||
@@ -6,6 +6,7 @@ use super::model::CommandOutput;
|
||||
use super::model::ExecCall;
|
||||
use super::model::ExecCell;
|
||||
use crate::exec_command::strip_bash_lc_and_escape;
|
||||
use crate::history_cell::ActivityDisclosure;
|
||||
use crate::history_cell::HistoryCell;
|
||||
use crate::history_cell::HistoryRenderMode;
|
||||
use crate::history_cell::plain_lines;
|
||||
@@ -218,18 +219,19 @@ impl HistoryCell for ExecCell {
|
||||
}
|
||||
}
|
||||
|
||||
fn has_hidden_activity_details(&self, width: u16) -> bool {
|
||||
fn activity_disclosure(&self, width: u16) -> Option<ActivityDisclosure> {
|
||||
if self.is_exploring_cell() {
|
||||
return true;
|
||||
return Some(ActivityDisclosure::Generic);
|
||||
}
|
||||
if self.group.calls.iter().any(ExecCall::is_user_shell_command) {
|
||||
// User-shell previews already retain wrapped commands and up to fifty output rows.
|
||||
// Reuse its actual truncation decision instead of comparing differently styled text.
|
||||
return self
|
||||
.command_display_lines_with_hidden_details(width)
|
||||
.hidden_details;
|
||||
.hidden_details
|
||||
.then_some(ActivityDisclosure::Generic);
|
||||
}
|
||||
self.command_has_hidden_details(width)
|
||||
self.command_disclosure(width)
|
||||
}
|
||||
|
||||
fn compact_hyperlink_lines(&self, width: u16) -> Vec<HyperlinkLine> {
|
||||
|
||||
Reference in New Issue
Block a user