mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +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:
@@ -414,7 +414,7 @@ fn activity_focus_keeps_controls_without_passive_hints() {
|
||||
cell.compact_hyperlink_lines(width)
|
||||
},
|
||||
auxiliary: Vec::new(),
|
||||
has_hidden_details: true,
|
||||
disclosure: cell.activity_disclosure(width),
|
||||
})
|
||||
});
|
||||
render(view, &[])
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
//! Mutable cells refresh each frame, then share that frame's layout across measurement and paint.
|
||||
//! Stable cells also invalidate when animation ticks, syntax themes, or terminal colors change.
|
||||
|
||||
use crate::history_cell::ActivityDisclosure;
|
||||
use crate::key_hint::ShortcutHint;
|
||||
use crate::keymap::KeymapContext;
|
||||
use std::sync::Weak;
|
||||
|
||||
use super::*;
|
||||
@@ -14,7 +17,7 @@ const MAX_CACHED_TEXT_BYTES: usize = 8 * 1024 * 1024;
|
||||
pub(crate) struct ActivityTranscriptLines {
|
||||
pub(crate) activity: Vec<HyperlinkLine>,
|
||||
pub(crate) auxiliary: Vec<HyperlinkLine>,
|
||||
pub(crate) has_hidden_details: bool,
|
||||
pub(crate) disclosure: Option<ActivityDisclosure>,
|
||||
}
|
||||
|
||||
/// Keep disclosure controls outside selectable source without rendering hidden details.
|
||||
@@ -22,8 +25,9 @@ pub(super) fn activity_layout(
|
||||
mut lines: ActivityTranscriptLines,
|
||||
width: u16,
|
||||
expanded: bool,
|
||||
shortcut: Option<ShortcutHint>,
|
||||
) -> TextLayout {
|
||||
let has_details = !lines.activity.is_empty() && (expanded || lines.has_hidden_details);
|
||||
let has_details = !lines.activity.is_empty() && (expanded || lines.disclosure.is_some());
|
||||
let source_offset = (!lines.auxiliary.is_empty())
|
||||
.then(|| TextLayout::new(lines.activity.clone(), width).text().len());
|
||||
lines.activity.extend(lines.auxiliary);
|
||||
@@ -31,12 +35,22 @@ pub(super) fn activity_layout(
|
||||
if !has_details {
|
||||
return layout;
|
||||
}
|
||||
let label = if expanded {
|
||||
"− Show less"
|
||||
} else {
|
||||
"+ Show details"
|
||||
}
|
||||
.to_owned();
|
||||
let label = match (expanded, lines.disclosure) {
|
||||
(true, _) => "− Show less".to_owned(),
|
||||
(false, Some(ActivityDisclosure::OutputLines(count))) => {
|
||||
let noun = if count == 1 { "line" } else { "lines" };
|
||||
let mut label = format!("+ {count} {noun}");
|
||||
if let Some(shortcut) = shortcut {
|
||||
let hint = format!(" ({} to expand)", shortcut.display_label());
|
||||
let indent = usize::from(width / 4).min(/*other*/ 4);
|
||||
if Line::from(format!("{label}{hint}")).width() + indent <= usize::from(width) {
|
||||
label.push_str(&hint);
|
||||
}
|
||||
}
|
||||
label
|
||||
}
|
||||
(false, Some(ActivityDisclosure::Generic) | None) => "+ Show details".to_owned(),
|
||||
};
|
||||
match source_offset {
|
||||
Some(offset) => layout.with_disclosure_control_at(label, offset),
|
||||
None => layout.with_disclosure_control(label),
|
||||
@@ -141,6 +155,10 @@ impl TranscriptView {
|
||||
expanded,
|
||||
disclosure,
|
||||
};
|
||||
let shortcut = self
|
||||
.disclosure
|
||||
.keymap
|
||||
.primary_hint(KeymapContext::Global, "open_transcript");
|
||||
Some(self.cache.get(cell, width, presentation, || {
|
||||
if disclosure {
|
||||
activity_layout(
|
||||
@@ -151,10 +169,11 @@ impl TranscriptView {
|
||||
cell.compact_hyperlink_lines(width)
|
||||
},
|
||||
auxiliary: Vec::new(),
|
||||
has_hidden_details: cell.has_hidden_activity_details(width),
|
||||
disclosure: cell.activity_disclosure(width),
|
||||
},
|
||||
width,
|
||||
expanded,
|
||||
shortcut,
|
||||
)
|
||||
} else {
|
||||
TextLayout::new(
|
||||
|
||||
@@ -111,6 +111,8 @@ impl TranscriptView {
|
||||
}
|
||||
self.search.editor.set_keymap_bindings(keymap);
|
||||
self.disclosure.keymap = keymap.clone();
|
||||
self.cache.clear();
|
||||
self.live_key = None;
|
||||
}
|
||||
|
||||
pub(crate) fn is_search_active(&self) -> bool {
|
||||
|
||||
Reference in New Issue
Block a user