Clear startup draft protection when discarded

This commit is contained in:
Charlie Marsh
2026-07-05 21:08:17 -04:00
parent 3abb31758b
commit 7aa75d2fec
3 changed files with 45 additions and 1 deletions

View File

@@ -36,7 +36,12 @@ impl ChatWidget {
.as_ref()
.is_some_and(HashSet::is_empty);
if startup_ready {
self.startup_draft_pending_mcp_servers = None;
self.clear_startup_draft_protection();
}
}
pub(super) fn clear_startup_draft_protection(&mut self) {
if self.startup_draft_pending_mcp_servers.take().is_some() {
self.bottom_pane
.set_startup_draft_submission_blocked(/*blocked*/ false);
}

View File

@@ -373,6 +373,7 @@ impl ChatWidget {
fn on_ctrl_c(&mut self) {
let key = key_hint::ctrl(KeyCode::Char('c'));
let modal_or_popup_active = !self.bottom_pane.no_modal_or_popup_active();
let composer_had_input = !self.bottom_pane.composer_is_empty();
let should_pause_active_goal = self
.bottom_pane
.active_view_will_interrupt_turn_on_key_event(KeyEvent::new(
@@ -380,6 +381,9 @@ impl ChatWidget {
KeyModifiers::CONTROL,
));
if self.bottom_pane.on_ctrl_c() == CancellationEvent::Handled {
if composer_had_input && self.bottom_pane.composer_is_empty() {
self.clear_startup_draft_protection();
}
if DOUBLE_PRESS_QUIT_SHORTCUT_ENABLED {
if modal_or_popup_active {
self.quit_shortcut_expires_at = None;

View File

@@ -1035,6 +1035,41 @@ async fn ctrl_c_cleared_prompt_is_recoverable_via_history() {
assert_eq!(vec![PathBuf::from("/tmp/preview.png")], images);
}
#[tokio::test]
async fn ctrl_c_clears_startup_draft_protection_only_with_the_composer() {
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
chat.restore_startup_draft("captured during startup");
chat.open_review_popup();
chat.handle_key_event(KeyEvent::new(KeyCode::Char('c'), KeyModifiers::CONTROL));
assert_eq!(chat.bottom_pane.composer_text(), "captured during startup");
assert!(chat.startup_draft_pending_mcp_servers.is_some());
chat.handle_key_event(KeyEvent::new(KeyCode::Char('r'), KeyModifiers::CONTROL));
assert!(!chat.bottom_pane.no_modal_or_popup_active());
chat.handle_key_event(KeyEvent::new(KeyCode::Char('c'), KeyModifiers::CONTROL));
assert_eq!(chat.bottom_pane.composer_text(), "captured during startup");
assert!(chat.startup_draft_pending_mcp_servers.is_some());
assert_eq!(
chat.bottom_pane
.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE)),
InputResult::None
);
chat.handle_key_event(KeyEvent::new(KeyCode::Char('c'), KeyModifiers::CONTROL));
assert!(chat.bottom_pane.composer_is_empty());
assert!(chat.startup_draft_pending_mcp_servers.is_none());
chat.bottom_pane.insert_str("replacement draft");
assert_matches!(
chat.bottom_pane
.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE)),
InputResult::Submitted { .. }
);
}
/// Selecting the custom prompt option from the review popup sends
/// OpenReviewCustomPrompt to the app event channel.
#[tokio::test]