diff --git a/codex-rs/tui/src/bottom_pane/chat_composer.rs b/codex-rs/tui/src/bottom_pane/chat_composer.rs index 2574ded4..7aa6e669 100644 --- a/codex-rs/tui/src/bottom_pane/chat_composer.rs +++ b/codex-rs/tui/src/bottom_pane/chat_composer.rs @@ -149,7 +149,7 @@ impl ChatComposer { paste_burst: PasteBurst::default(), disable_paste_burst: false, custom_prompts: Vec::new(), - footer_mode: FooterMode::ShortcutPrompt, + footer_mode: FooterMode::ShortcutSummary, footer_hint_override: None, context_window_percent: None, }; @@ -1345,8 +1345,8 @@ impl ChatComposer { FooterMode::EscHint => FooterMode::EscHint, FooterMode::ShortcutOverlay => FooterMode::ShortcutOverlay, FooterMode::CtrlCReminder => FooterMode::CtrlCReminder, - FooterMode::ShortcutPrompt if self.ctrl_c_quit_hint => FooterMode::CtrlCReminder, - FooterMode::ShortcutPrompt if !self.is_empty() => FooterMode::Empty, + FooterMode::ShortcutSummary if self.ctrl_c_quit_hint => FooterMode::CtrlCReminder, + FooterMode::ShortcutSummary if !self.is_empty() => FooterMode::ContextOnly, other => other, } } @@ -1779,11 +1779,11 @@ mod tests { // Toggle back to prompt mode so subsequent typing captures characters. let _ = composer.handle_key_event(KeyEvent::new(KeyCode::Char('?'), KeyModifiers::NONE)); - assert_eq!(composer.footer_mode, FooterMode::ShortcutPrompt); + assert_eq!(composer.footer_mode, FooterMode::ShortcutSummary); type_chars_humanlike(&mut composer, &['h']); assert_eq!(composer.textarea.text(), "h"); - assert_eq!(composer.footer_mode(), FooterMode::Empty); + assert_eq!(composer.footer_mode(), FooterMode::ContextOnly); let (result, needs_redraw) = composer.handle_key_event(KeyEvent::new(KeyCode::Char('?'), KeyModifiers::NONE)); @@ -1792,8 +1792,8 @@ mod tests { std::thread::sleep(ChatComposer::recommended_paste_flush_delay()); let _ = composer.flush_paste_burst_if_due(); assert_eq!(composer.textarea.text(), "h?"); - assert_eq!(composer.footer_mode, FooterMode::ShortcutPrompt); - assert_eq!(composer.footer_mode(), FooterMode::Empty); + assert_eq!(composer.footer_mode, FooterMode::ShortcutSummary); + assert_eq!(composer.footer_mode(), FooterMode::ContextOnly); } #[test] diff --git a/codex-rs/tui/src/bottom_pane/footer.rs b/codex-rs/tui/src/bottom_pane/footer.rs index b4c5617d..6e92a0ce 100644 --- a/codex-rs/tui/src/bottom_pane/footer.rs +++ b/codex-rs/tui/src/bottom_pane/footer.rs @@ -23,10 +23,10 @@ pub(crate) struct FooterProps { #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub(crate) enum FooterMode { CtrlCReminder, - ShortcutPrompt, + ShortcutSummary, ShortcutOverlay, EscHint, - Empty, + ContextOnly, } pub(crate) fn toggle_shortcut_mode(current: FooterMode, ctrl_c_hint: bool) -> FooterMode { @@ -35,7 +35,7 @@ pub(crate) fn toggle_shortcut_mode(current: FooterMode, ctrl_c_hint: bool) -> Fo } match current { - FooterMode::ShortcutOverlay | FooterMode::CtrlCReminder => FooterMode::ShortcutPrompt, + FooterMode::ShortcutOverlay | FooterMode::CtrlCReminder => FooterMode::ShortcutSummary, _ => FooterMode::ShortcutOverlay, } } @@ -53,7 +53,7 @@ pub(crate) fn reset_mode_after_activity(current: FooterMode) -> FooterMode { FooterMode::EscHint | FooterMode::ShortcutOverlay | FooterMode::CtrlCReminder - | FooterMode::Empty => FooterMode::ShortcutPrompt, + | FooterMode::ContextOnly => FooterMode::ShortcutSummary, other => other, } } @@ -72,26 +72,29 @@ pub(crate) fn render_footer(area: Rect, buf: &mut Buffer, props: FooterProps) { } fn footer_lines(props: FooterProps) -> Vec> { + // Show the context indicator on the left, appended after the primary hint + // (e.g., "? for shortcuts"). Keep it visible even when typing (i.e., when + // the shortcut hint is hidden). Hide it only for the multi-line + // ShortcutOverlay. match props.mode { FooterMode::CtrlCReminder => vec![ctrl_c_reminder_line(CtrlCReminderState { is_task_running: props.is_task_running, })], - FooterMode::ShortcutPrompt => { - if props.is_task_running { - vec![context_window_line(props.context_window_percent)] - } else { - vec![Line::from(vec![ - key_hint::plain(KeyCode::Char('?')).into(), - " for shortcuts".dim(), - ])] - } + FooterMode::ShortcutSummary => { + let mut line = context_window_line(props.context_window_percent); + line.push_span(" · ".dim()); + line.extend(vec![ + key_hint::plain(KeyCode::Char('?')).into(), + " for shortcuts".dim(), + ]); + vec![line] } FooterMode::ShortcutOverlay => shortcut_overlay_lines(ShortcutsState { use_shift_enter_hint: props.use_shift_enter_hint, esc_backtrack_hint: props.esc_backtrack_hint, }), FooterMode::EscHint => vec![esc_hint_line(props.esc_backtrack_hint)], - FooterMode::Empty => Vec::new(), + FooterMode::ContextOnly => vec![context_window_line(props.context_window_percent)], } } @@ -219,18 +222,8 @@ fn build_columns(entries: Vec>) -> Vec> { } fn context_window_line(percent: Option) -> Line<'static> { - let mut spans: Vec> = Vec::new(); - match percent { - Some(percent) => { - spans.push(format!("{percent}%").dim()); - spans.push(" context left".dim()); - } - None => { - spans.push(key_hint::plain(KeyCode::Char('?')).into()); - spans.push(" for shortcuts".dim()); - } - } - Line::from(spans) + let percent = percent.unwrap_or(100); + Line::from(vec![Span::from(format!("{percent}% context left")).dim()]) } #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -402,7 +395,7 @@ mod tests { snapshot_footer( "footer_shortcuts_default", FooterProps { - mode: FooterMode::ShortcutPrompt, + mode: FooterMode::ShortcutSummary, esc_backtrack_hint: false, use_shift_enter_hint: false, is_task_running: false, @@ -468,7 +461,7 @@ mod tests { snapshot_footer( "footer_shortcuts_context_running", FooterProps { - mode: FooterMode::ShortcutPrompt, + mode: FooterMode::ShortcutSummary, esc_backtrack_hint: false, use_shift_enter_hint: false, is_task_running: true, diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__backspace_after_pastes.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__backspace_after_pastes.snap index adb764b6..e4cc9ffe 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__backspace_after_pastes.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__backspace_after_pastes.snap @@ -11,4 +11,4 @@ expression: terminal.backend() " " " " " " -" " +" 100% context left " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__empty.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__empty.snap index db924278..53e0aee4 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__empty.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__empty.snap @@ -1,6 +1,5 @@ --- source: tui/src/bottom_pane/chat_composer.rs -assertion_line: 1938 expression: terminal.backend() --- " " @@ -12,4 +11,4 @@ expression: terminal.backend() " " " " " " -" ? for shortcuts " +" 100% context left · ? for shortcuts " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_interrupt.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_interrupt.snap index a805fbf9..49ffb0d4 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_interrupt.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_interrupt.snap @@ -1,6 +1,5 @@ --- source: tui/src/bottom_pane/chat_composer.rs -assertion_line: 1497 expression: terminal.backend() --- " " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_quit.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_quit.snap index 750ba101..7ecc5bba 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_quit.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_quit.snap @@ -1,6 +1,5 @@ --- source: tui/src/bottom_pane/chat_composer.rs -assertion_line: 1497 expression: terminal.backend() --- " " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_then_esc_hint.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_then_esc_hint.snap index 8c2d2bfd..9cad17b8 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_then_esc_hint.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_then_esc_hint.snap @@ -1,6 +1,5 @@ --- source: tui/src/bottom_pane/chat_composer.rs -assertion_line: 1497 expression: terminal.backend() --- " " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_esc_hint_backtrack.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_esc_hint_backtrack.snap index 5ddf39e3..2fce42cc 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_esc_hint_backtrack.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_esc_hint_backtrack.snap @@ -1,6 +1,5 @@ --- source: tui/src/bottom_pane/chat_composer.rs -assertion_line: 1497 expression: terminal.backend() --- " " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_esc_hint_from_overlay.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_esc_hint_from_overlay.snap index 8c2d2bfd..9cad17b8 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_esc_hint_from_overlay.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_esc_hint_from_overlay.snap @@ -1,6 +1,5 @@ --- source: tui/src/bottom_pane/chat_composer.rs -assertion_line: 1497 expression: terminal.backend() --- " " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_hidden_while_typing.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_hidden_while_typing.snap index dfeb98d6..67e616e9 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_hidden_while_typing.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_hidden_while_typing.snap @@ -10,3 +10,4 @@ expression: terminal.backend() " " " " " " +" 100% context left " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_overlay_then_external_esc_hint.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_overlay_then_external_esc_hint.snap index 5ddf39e3..2fce42cc 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_overlay_then_external_esc_hint.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__footer_mode_overlay_then_external_esc_hint.snap @@ -1,6 +1,5 @@ --- source: tui/src/bottom_pane/chat_composer.rs -assertion_line: 1497 expression: terminal.backend() --- " " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__large.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__large.snap index 4237a17a..6b018021 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__large.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__large.snap @@ -11,4 +11,4 @@ expression: terminal.backend() " " " " " " -" " +" 100% context left " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__multiple_pastes.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__multiple_pastes.snap index 3edfc2ce..40098fae 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__multiple_pastes.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__multiple_pastes.snap @@ -11,4 +11,4 @@ expression: terminal.backend() " " " " " " -" " +" 100% context left " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__small.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__small.snap index 402740b8..498ed769 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__small.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__small.snap @@ -11,4 +11,4 @@ expression: terminal.backend() " " " " " " -" " +" 100% context left " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_ctrl_c_quit_idle.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_ctrl_c_quit_idle.snap index 817adb66..31a1b743 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_ctrl_c_quit_idle.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_ctrl_c_quit_idle.snap @@ -1,6 +1,5 @@ --- source: tui/src/bottom_pane/footer.rs -assertion_line: 389 expression: terminal.backend() --- " ctrl + c again to quit " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_ctrl_c_quit_running.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_ctrl_c_quit_running.snap index 50bf9b62..9979372a 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_ctrl_c_quit_running.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_ctrl_c_quit_running.snap @@ -1,6 +1,5 @@ --- source: tui/src/bottom_pane/footer.rs -assertion_line: 389 expression: terminal.backend() --- " ctrl + c again to interrupt " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_esc_hint_idle.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_esc_hint_idle.snap index 172432a3..b2333b02 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_esc_hint_idle.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_esc_hint_idle.snap @@ -1,6 +1,5 @@ --- source: tui/src/bottom_pane/footer.rs -assertion_line: 389 expression: terminal.backend() --- " esc esc to edit previous message " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_esc_hint_primed.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_esc_hint_primed.snap index 69d79d53..20f9b178 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_esc_hint_primed.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_esc_hint_primed.snap @@ -1,6 +1,5 @@ --- source: tui/src/bottom_pane/footer.rs -assertion_line: 389 expression: terminal.backend() --- " esc again to edit previous message " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_shortcuts_context_running.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_shortcuts_context_running.snap index 77b3796c..d05ac90a 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_shortcuts_context_running.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_shortcuts_context_running.snap @@ -2,4 +2,4 @@ source: tui/src/bottom_pane/footer.rs expression: terminal.backend() --- -" 72% context left " +" 72% context left · ? for shortcuts " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_shortcuts_default.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_shortcuts_default.snap index b2de2154..c95a5dc0 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_shortcuts_default.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__footer__tests__footer_shortcuts_default.snap @@ -1,6 +1,5 @@ --- source: tui/src/bottom_pane/footer.rs -assertion_line: 389 expression: terminal.backend() --- -" ? for shortcuts " +" 100% context left · ? for shortcuts " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__tests__status_and_composer_fill_height_without_bottom_padding.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__tests__status_and_composer_fill_height_without_bottom_padding.snap index ae96888f..ecf92583 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__tests__status_and_composer_fill_height_without_bottom_padding.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__tests__status_and_composer_fill_height_without_bottom_padding.snap @@ -8,4 +8,4 @@ expression: "render_snapshot(&pane, area)" › Ask Codex to do anything - ? for shortcuts + 100% context left · ? for sh diff --git a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__chatwidget_exec_and_status_layout_vt100_snapshot.snap b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__chatwidget_exec_and_status_layout_vt100_snapshot.snap index b83bf8a9..f913ce08 100644 --- a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__chatwidget_exec_and_status_layout_vt100_snapshot.snap +++ b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__chatwidget_exec_and_status_layout_vt100_snapshot.snap @@ -13,3 +13,4 @@ expression: term.backend().vt100().screen().contents() › Summarize recent commits + 100% context left diff --git a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_widget_active.snap b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_widget_active.snap index e288807b..9fbebfb5 100644 --- a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_widget_active.snap +++ b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_widget_active.snap @@ -9,4 +9,4 @@ expression: terminal.backend() " " "› Ask Codex to do anything " " " -" ? for shortcuts " +" 100% context left · ? for shortcuts "