diff --git a/codex-rs/tui/src/app.rs b/codex-rs/tui/src/app.rs index 47e20287..2ac550b0 100644 --- a/codex-rs/tui/src/app.rs +++ b/codex-rs/tui/src/app.rs @@ -238,6 +238,16 @@ impl App<'_> { } } } + KeyEvent { + code: KeyCode::Char('z'), + modifiers: crossterm::event::KeyModifiers::CONTROL, + kind: KeyEventKind::Press, + .. + } => { + if let AppState::Chat { widget } = &mut self.app_state { + widget.on_ctrl_z(); + } + } KeyEvent { code: KeyCode::Char('d'), modifiers: crossterm::event::KeyModifiers::CONTROL, diff --git a/codex-rs/tui/src/chatwidget.rs b/codex-rs/tui/src/chatwidget.rs index 69f1600c..128e1ae8 100644 --- a/codex-rs/tui/src/chatwidget.rs +++ b/codex-rs/tui/src/chatwidget.rs @@ -110,6 +110,22 @@ fn create_initial_user_message(text: String, image_paths: Vec) -> Optio } impl ChatWidget<'_> { + fn interrupt_running_task(&mut self) { + if self.bottom_pane.is_task_running() { + self.active_history_cell = None; + self.bottom_pane.clear_ctrl_c_quit_hint(); + self.submit_op(Op::Interrupt); + self.bottom_pane.set_task_running(false); + self.bottom_pane.clear_live_ring(); + self.live_builder = RowBuilder::new(self.live_builder.width()); + self.current_stream = None; + self.stream_header_emitted = false; + self.answer_buffer.clear(); + self.reasoning_buffer.clear(); + self.content_buffer.clear(); + self.request_redraw(); + } + } fn layout_areas(&self, area: Rect) -> [Rect; 2] { Layout::vertical([ Constraint::Max( @@ -569,18 +585,7 @@ impl ChatWidget<'_> { CancellationEvent::Ignored => {} } if self.bottom_pane.is_task_running() { - self.active_history_cell = None; - self.bottom_pane.clear_ctrl_c_quit_hint(); - self.submit_op(Op::Interrupt); - self.bottom_pane.set_task_running(false); - self.bottom_pane.clear_live_ring(); - self.live_builder = RowBuilder::new(self.live_builder.width()); - self.current_stream = None; - self.stream_header_emitted = false; - self.answer_buffer.clear(); - self.reasoning_buffer.clear(); - self.content_buffer.clear(); - self.request_redraw(); + self.interrupt_running_task(); CancellationEvent::Ignored } else if self.bottom_pane.ctrl_c_quit_hint_visible() { self.submit_op(Op::Shutdown); @@ -591,6 +596,10 @@ impl ChatWidget<'_> { } } + pub(crate) fn on_ctrl_z(&mut self) { + self.interrupt_running_task(); + } + pub(crate) fn composer_is_empty(&self) -> bool { self.bottom_pane.composer_is_empty() }