fix: update ctrl-z to suspend tui (#2113)
- Lean on ctrl-c and esc to interrupt. - (Only on unix.) https://github.com/user-attachments/assets/7ce6c57f-6ee2-40c2-8cd2-b31265f16c1c
This commit is contained in:
1
codex-rs/Cargo.lock
generated
1
codex-rs/Cargo.lock
generated
@@ -881,6 +881,7 @@ dependencies = [
|
|||||||
"image",
|
"image",
|
||||||
"insta",
|
"insta",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
"mcp-types",
|
"mcp-types",
|
||||||
"path-clean",
|
"path-clean",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ unicode-segmentation = "1.12.0"
|
|||||||
unicode-width = "0.1"
|
unicode-width = "0.1"
|
||||||
uuid = "1"
|
uuid = "1"
|
||||||
|
|
||||||
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
libc = "0.2"
|
||||||
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
|
|||||||
@@ -255,9 +255,11 @@ impl App<'_> {
|
|||||||
kind: KeyEventKind::Press,
|
kind: KeyEventKind::Press,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if let AppState::Chat { widget } = &mut self.app_state {
|
#[cfg(unix)]
|
||||||
widget.on_ctrl_z();
|
{
|
||||||
|
self.suspend(terminal)?;
|
||||||
}
|
}
|
||||||
|
// No-op on non-Unix platforms.
|
||||||
}
|
}
|
||||||
KeyEvent {
|
KeyEvent {
|
||||||
code: KeyCode::Char('d'),
|
code: KeyCode::Char('d'),
|
||||||
@@ -459,6 +461,23 @@ impl App<'_> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn suspend(&mut self, terminal: &mut tui::Tui) -> Result<()> {
|
||||||
|
tui::restore()?;
|
||||||
|
// SAFETY: Unix-only code path. We intentionally send SIGTSTP to the
|
||||||
|
// current process group (pid 0) to trigger standard job-control
|
||||||
|
// suspension semantics. This FFI does not involve any raw pointers,
|
||||||
|
// is not called from a signal handler, and uses a constant signal.
|
||||||
|
// Errors from kill are acceptable (e.g., if already stopped) — the
|
||||||
|
// subsequent re-init path will still leave the terminal in a good state.
|
||||||
|
// We considered `nix`, but didn't think it was worth pulling in for this one call.
|
||||||
|
unsafe { libc::kill(0, libc::SIGTSTP) };
|
||||||
|
*terminal = tui::init(&self.config)?;
|
||||||
|
terminal.clear()?;
|
||||||
|
self.app_event_tx.send(AppEvent::RequestRedraw);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn token_usage(&self) -> codex_core::protocol::TokenUsage {
|
pub(crate) fn token_usage(&self) -> codex_core::protocol::TokenUsage {
|
||||||
match &self.app_state {
|
match &self.app_state {
|
||||||
AppState::Chat { widget } => widget.token_usage().clone(),
|
AppState::Chat { widget } => widget.token_usage().clone(),
|
||||||
|
|||||||
@@ -652,10 +652,6 @@ impl ChatWidget<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn on_ctrl_z(&mut self) {
|
|
||||||
self.interrupt_running_task();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn composer_is_empty(&self) -> bool {
|
pub(crate) fn composer_is_empty(&self) -> bool {
|
||||||
self.bottom_pane.composer_is_empty()
|
self.bottom_pane.composer_is_empty()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user