mirror of
https://github.com/openai/codex.git
synced 2026-05-02 20:32:04 +03:00
tui: exit session on Ctrl+C in cwd change prompt (#12040)
## Summary - change the cwd-change prompt (shown when resuming/forking across different directories) so `Ctrl+C`/`Ctrl+D` exits the session instead of implicitly selecting "Use session directory" - introduce explicit prompt and resolver exit outcomes so this intent is propagated cleanly through both startup resume/fork and in-app `/resume` flows - add a unit test that verifies `Ctrl+C` exits rather than selecting an option ## Why Previously, pressing `Ctrl+C` on this prompt silently picked one of the options, which made it hard to abort. This aligns the prompt with the expected quit behavior. ## Codex author `codex resume 019c6d39-bbfb-7dc3-8008-1388a054e86d`
This commit is contained in:
committed by
GitHub
parent
c4bb7db159
commit
709e2133bb
@@ -51,6 +51,12 @@ pub(crate) enum CwdSelection {
|
||||
Session,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub(crate) enum CwdPromptOutcome {
|
||||
Selection(CwdSelection),
|
||||
Exit,
|
||||
}
|
||||
|
||||
impl CwdSelection {
|
||||
fn next(self) -> Self {
|
||||
match self {
|
||||
@@ -72,7 +78,7 @@ pub(crate) async fn run_cwd_selection_prompt(
|
||||
action: CwdPromptAction,
|
||||
current_cwd: &Path,
|
||||
session_cwd: &Path,
|
||||
) -> Result<CwdSelection> {
|
||||
) -> Result<CwdPromptOutcome> {
|
||||
let mut screen = CwdPromptScreen::new(
|
||||
tui.frame_requester(),
|
||||
action,
|
||||
@@ -102,7 +108,13 @@ pub(crate) async fn run_cwd_selection_prompt(
|
||||
}
|
||||
}
|
||||
|
||||
Ok(screen.selection().unwrap_or(CwdSelection::Session))
|
||||
if screen.should_exit {
|
||||
Ok(CwdPromptOutcome::Exit)
|
||||
} else {
|
||||
Ok(CwdPromptOutcome::Selection(
|
||||
screen.selection().unwrap_or(CwdSelection::Session),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
struct CwdPromptScreen {
|
||||
@@ -112,6 +124,7 @@ struct CwdPromptScreen {
|
||||
session_cwd: String,
|
||||
highlighted: CwdSelection,
|
||||
selection: Option<CwdSelection>,
|
||||
should_exit: bool,
|
||||
}
|
||||
|
||||
impl CwdPromptScreen {
|
||||
@@ -128,6 +141,7 @@ impl CwdPromptScreen {
|
||||
session_cwd,
|
||||
highlighted: CwdSelection::Session,
|
||||
selection: None,
|
||||
should_exit: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +152,9 @@ impl CwdPromptScreen {
|
||||
if key_event.modifiers.contains(KeyModifiers::CONTROL)
|
||||
&& matches!(key_event.code, KeyCode::Char('c') | KeyCode::Char('d'))
|
||||
{
|
||||
self.select(CwdSelection::Session);
|
||||
self.selection = None;
|
||||
self.should_exit = true;
|
||||
self.request_frame.schedule_frame();
|
||||
return;
|
||||
}
|
||||
match key_event.code {
|
||||
@@ -166,7 +182,7 @@ impl CwdPromptScreen {
|
||||
}
|
||||
|
||||
fn is_done(&self) -> bool {
|
||||
self.selection.is_some()
|
||||
self.should_exit || self.selection.is_some()
|
||||
}
|
||||
|
||||
fn selection(&self) -> Option<CwdSelection> {
|
||||
@@ -283,4 +299,12 @@ mod tests {
|
||||
screen.handle_key(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE));
|
||||
assert_eq!(screen.selection(), Some(CwdSelection::Current));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cwd_prompt_ctrl_c_exits_instead_of_selecting() {
|
||||
let mut screen = new_prompt();
|
||||
screen.handle_key(KeyEvent::new(KeyCode::Char('c'), KeyModifiers::CONTROL));
|
||||
assert_eq!(screen.selection(), None);
|
||||
assert!(screen.is_done());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user