mirror of
https://github.com/openai/codex.git
synced 2026-05-04 05:11:37 +03:00
tui: allow forward navigation in backtrack preview (#9059)
Fixes #9058 ## Summary When the transcript backtrack preview is armed (press `Esc`), allow navigating to newer user messages with the `→` arrow, in addition to navigating backwards with `Esc`/`←`, before confirming with `Enter`. ## Changes - Backtrack preview navigation: `Esc`/`←` steps to older user messages, `→` steps to newer ones, `Enter` edits the selected message (clamped at bounds, no wrap-around). - Transcript overlay footer hints updated to advertise `esc/←`, `→`, and `enter` when a message is highlighted. ## Related - WSL shortcut-overlay snapshot determinism: #9359 ## Testing - `just fmt` - `just fix -p codex-tui` - `just fix -p codex-tui2` - `cargo test -p codex-tui app_backtrack::` - `cargo test -p codex-tui pager_overlay::` - `cargo test -p codex-tui2 app_backtrack::` - `cargo test -p codex-tui2 pager_overlay::` --------- Co-authored-by: Josh McKinney <joshka@openai.com>
This commit is contained in:
@@ -93,8 +93,9 @@ pub(crate) struct PendingBacktrackRollback {
|
||||
impl App {
|
||||
/// Route overlay events while the transcript overlay is active.
|
||||
///
|
||||
/// If backtrack preview is active, Esc steps the selection and Enter confirms it.
|
||||
/// Otherwise, Esc begins preview mode and all other events are forwarded to the overlay.
|
||||
/// If backtrack preview is active, Esc / Left steps selection, Right steps forward, Enter
|
||||
/// confirms. Otherwise, Esc begins preview mode and all other events are forwarded to the
|
||||
/// overlay.
|
||||
pub(crate) async fn handle_backtrack_overlay_event(
|
||||
&mut self,
|
||||
tui: &mut tui::Tui,
|
||||
@@ -110,6 +111,22 @@ impl App {
|
||||
self.overlay_step_backtrack(tui, event)?;
|
||||
Ok(true)
|
||||
}
|
||||
TuiEvent::Key(KeyEvent {
|
||||
code: KeyCode::Left,
|
||||
kind: KeyEventKind::Press | KeyEventKind::Repeat,
|
||||
..
|
||||
}) => {
|
||||
self.overlay_step_backtrack(tui, event)?;
|
||||
Ok(true)
|
||||
}
|
||||
TuiEvent::Key(KeyEvent {
|
||||
code: KeyCode::Right,
|
||||
kind: KeyEventKind::Press | KeyEventKind::Repeat,
|
||||
..
|
||||
}) => {
|
||||
self.overlay_step_backtrack_forward(tui, event)?;
|
||||
Ok(true)
|
||||
}
|
||||
TuiEvent::Key(KeyEvent {
|
||||
code: KeyCode::Enter,
|
||||
kind: KeyEventKind::Press,
|
||||
@@ -277,6 +294,27 @@ impl App {
|
||||
tui.frame_requester().schedule_frame();
|
||||
}
|
||||
|
||||
/// Step selection to the next newer user message and update overlay.
|
||||
fn step_forward_backtrack_and_highlight(&mut self, tui: &mut tui::Tui) {
|
||||
let count = user_count(&self.transcript_cells);
|
||||
if count == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let last_index = count.saturating_sub(1);
|
||||
let next_selection = if self.backtrack.nth_user_message == usize::MAX {
|
||||
last_index
|
||||
} else {
|
||||
self.backtrack
|
||||
.nth_user_message
|
||||
.saturating_add(1)
|
||||
.min(last_index)
|
||||
};
|
||||
|
||||
self.apply_backtrack_selection_internal(next_selection);
|
||||
tui.frame_requester().schedule_frame();
|
||||
}
|
||||
|
||||
/// Apply a computed backtrack selection to the overlay and internal counter.
|
||||
fn apply_backtrack_selection_internal(&mut self, nth_user_message: usize) {
|
||||
if let Some(cell_idx) = nth_user_position(&self.transcript_cells, nth_user_message) {
|
||||
@@ -364,6 +402,20 @@ impl App {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Handle Right in overlay backtrack preview: step selection forward if armed, else forward.
|
||||
fn overlay_step_backtrack_forward(
|
||||
&mut self,
|
||||
tui: &mut tui::Tui,
|
||||
event: TuiEvent,
|
||||
) -> Result<()> {
|
||||
if self.backtrack.base_id.is_some() {
|
||||
self.step_forward_backtrack_and_highlight(tui);
|
||||
} else {
|
||||
self.overlay_forward_event(tui, event)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Confirm a primed backtrack from the main view (no overlay visible).
|
||||
/// Computes the prefill from the selected user message for rollback.
|
||||
pub(crate) fn confirm_backtrack_from_main(&mut self) -> Option<BacktrackSelection> {
|
||||
|
||||
Reference in New Issue
Block a user