feat: ctrl-d only exits when there is no user input (#1589)
While this does make it so that `ctrl-d` will not exit Codex when the composer is not empty, `ctrl-d` will still exit Codex if it is in the "working" state. Fixes https://github.com/openai/codex/issues/1443.
This commit is contained in:
@@ -199,7 +199,21 @@ impl<'a> App<'a> {
|
|||||||
modifiers: crossterm::event::KeyModifiers::CONTROL,
|
modifiers: crossterm::event::KeyModifiers::CONTROL,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
self.app_event_tx.send(AppEvent::ExitRequest);
|
match &mut self.app_state {
|
||||||
|
AppState::Chat { widget } => {
|
||||||
|
if widget.composer_is_empty() {
|
||||||
|
self.app_event_tx.send(AppEvent::ExitRequest);
|
||||||
|
} else {
|
||||||
|
// Treat Ctrl+D as a normal key event when the composer
|
||||||
|
// is not empty so that it doesn't quit the application
|
||||||
|
// prematurely.
|
||||||
|
self.dispatch_key_event(key_event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AppState::Login { .. } | AppState::GitWarning { .. } => {
|
||||||
|
self.app_event_tx.send(AppEvent::ExitRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.dispatch_key_event(key_event);
|
self.dispatch_key_event(key_event);
|
||||||
|
|||||||
@@ -76,6 +76,11 @@ impl ChatComposer<'_> {
|
|||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the composer currently contains no user input.
|
||||||
|
pub(crate) fn is_empty(&self) -> bool {
|
||||||
|
self.textarea.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
/// Update the cached *context-left* percentage and refresh the placeholder
|
/// Update the cached *context-left* percentage and refresh the placeholder
|
||||||
/// text. The UI relies on the placeholder to convey the remaining
|
/// text. The UI relies on the placeholder to convey the remaining
|
||||||
/// context when the composer is empty.
|
/// context when the composer is empty.
|
||||||
|
|||||||
@@ -72,8 +72,7 @@ impl ChatComposerHistory {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let lines = textarea.lines();
|
if textarea.is_empty() {
|
||||||
if lines.len() == 1 && lines[0].is_empty() {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,6 +84,7 @@ impl ChatComposerHistory {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lines = textarea.lines();
|
||||||
matches!(&self.last_history_text, Some(prev) if prev == &lines.join("\n"))
|
matches!(&self.last_history_text, Some(prev) if prev == &lines.join("\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -162,6 +162,10 @@ impl BottomPane<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn composer_is_empty(&self) -> bool {
|
||||||
|
self.composer.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn is_task_running(&self) -> bool {
|
pub(crate) fn is_task_running(&self) -> bool {
|
||||||
self.is_task_running
|
self.is_task_running
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -432,6 +432,10 @@ impl ChatWidget<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn composer_is_empty(&self) -> bool {
|
||||||
|
self.bottom_pane.composer_is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
/// Forward an `Op` directly to codex.
|
/// Forward an `Op` directly to codex.
|
||||||
pub(crate) fn submit_op(&self, op: Op) {
|
pub(crate) fn submit_op(&self, op: Op) {
|
||||||
if let Err(e) = self.codex_op_tx.send(op) {
|
if let Err(e) = self.codex_op_tx.send(op) {
|
||||||
|
|||||||
Reference in New Issue
Block a user