Better implementation of interrupt on Esc (#2111)
Use existing abstractions
This commit is contained in:
@@ -235,20 +235,6 @@ impl App<'_> {
|
|||||||
self.app_event_tx.send(AppEvent::ExitRequest);
|
self.app_event_tx.send(AppEvent::ExitRequest);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
KeyEvent {
|
|
||||||
code: KeyCode::Esc,
|
|
||||||
kind: KeyEventKind::Press,
|
|
||||||
..
|
|
||||||
} => match &mut self.app_state {
|
|
||||||
AppState::Chat { widget } => {
|
|
||||||
if !widget.on_esc() {
|
|
||||||
self.dispatch_key_event(key_event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AppState::Onboarding { .. } => {
|
|
||||||
self.dispatch_key_event(key_event);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
KeyEvent {
|
KeyEvent {
|
||||||
code: KeyCode::Char('z'),
|
code: KeyCode::Char('z'),
|
||||||
modifiers: crossterm::event::KeyModifiers::CONTROL,
|
modifiers: crossterm::event::KeyModifiers::CONTROL,
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
use crossterm::event::KeyCode;
|
||||||
|
use crossterm::event::KeyEvent;
|
||||||
use ratatui::buffer::Buffer;
|
use ratatui::buffer::Buffer;
|
||||||
use ratatui::widgets::WidgetRef;
|
use ratatui::widgets::WidgetRef;
|
||||||
|
|
||||||
use crate::app_event_sender::AppEventSender;
|
use crate::app_event_sender::AppEventSender;
|
||||||
|
use crate::bottom_pane::BottomPane;
|
||||||
use crate::status_indicator_widget::StatusIndicatorWidget;
|
use crate::status_indicator_widget::StatusIndicatorWidget;
|
||||||
|
|
||||||
use super::BottomPaneView;
|
use super::BottomPaneView;
|
||||||
@@ -40,4 +43,10 @@ impl BottomPaneView<'_> for StatusIndicatorView {
|
|||||||
fn render(&self, area: ratatui::layout::Rect, buf: &mut Buffer) {
|
fn render(&self, area: ratatui::layout::Rect, buf: &mut Buffer) {
|
||||||
self.view.render_ref(area, buf);
|
self.view.render_ref(area, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_key_event(&mut self, _pane: &mut BottomPane<'_>, key_event: KeyEvent) {
|
||||||
|
if key_event.code == KeyCode::Esc {
|
||||||
|
self.view.interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -624,14 +624,6 @@ impl ChatWidget<'_> {
|
|||||||
self.bottom_pane.on_file_search_result(query, matches);
|
self.bottom_pane.on_file_search_result(query, matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn on_esc(&mut self) -> bool {
|
|
||||||
if self.bottom_pane.is_task_running() {
|
|
||||||
self.interrupt_running_task();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Handle Ctrl-C key press.
|
/// Handle Ctrl-C key press.
|
||||||
/// Returns CancellationEvent::Handled if the event was consumed by the UI, or
|
/// Returns CancellationEvent::Handled if the event was consumed by the UI, or
|
||||||
/// CancellationEvent::Ignored if the caller should handle it (e.g. exit).
|
/// CancellationEvent::Ignored if the caller should handle it (e.g. exit).
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use std::thread;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
|
use codex_core::protocol::Op;
|
||||||
use ratatui::buffer::Buffer;
|
use ratatui::buffer::Buffer;
|
||||||
use ratatui::layout::Rect;
|
use ratatui::layout::Rect;
|
||||||
use ratatui::style::Color;
|
use ratatui::style::Color;
|
||||||
@@ -44,11 +45,7 @@ pub(crate) struct StatusIndicatorWidget {
|
|||||||
frame_idx: Arc<AtomicUsize>,
|
frame_idx: Arc<AtomicUsize>,
|
||||||
running: Arc<AtomicBool>,
|
running: Arc<AtomicBool>,
|
||||||
start_time: Instant,
|
start_time: Instant,
|
||||||
// Keep one sender alive to prevent the channel from closing while the
|
app_event_tx: AppEventSender,
|
||||||
// animation thread is still running. The field itself is currently not
|
|
||||||
// accessed anywhere, therefore the leading underscore silences the
|
|
||||||
// `dead_code` warning without affecting behavior.
|
|
||||||
_app_event_tx: AppEventSender,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StatusIndicatorWidget {
|
impl StatusIndicatorWidget {
|
||||||
@@ -82,7 +79,7 @@ impl StatusIndicatorWidget {
|
|||||||
running,
|
running,
|
||||||
start_time: Instant::now(),
|
start_time: Instant::now(),
|
||||||
|
|
||||||
_app_event_tx: app_event_tx,
|
app_event_tx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,6 +117,10 @@ impl StatusIndicatorWidget {
|
|||||||
self.reveal_len_at_base = shown_now.min(new_len);
|
self.reveal_len_at_base = shown_now.min(new_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn interrupt(&self) {
|
||||||
|
self.app_event_tx.send(AppEvent::CodexOp(Op::Interrupt));
|
||||||
|
}
|
||||||
|
|
||||||
/// Reset the animation and start revealing `text` from the beginning.
|
/// Reset the animation and start revealing `text` from the beginning.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) fn restart_with_text(&mut self, text: String) {
|
pub(crate) fn restart_with_text(&mut self, text: String) {
|
||||||
|
|||||||
Reference in New Issue
Block a user