mirror of
https://github.com/openai/codex.git
synced 2026-11-05 20:10:33 +00:00
Preserve typeahead from process start
This commit is contained in:
@@ -884,7 +884,7 @@ pub async fn run_main(
|
||||
Ok(v) => v,
|
||||
#[allow(clippy::print_stderr)]
|
||||
Err(e) => {
|
||||
tui::discard_terminal_input();
|
||||
tui::abandon_prepared_terminal();
|
||||
eprintln!("Error parsing -c overrides: {e}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
@@ -895,7 +895,7 @@ pub async fn run_main(
|
||||
let codex_home = match find_codex_home() {
|
||||
Ok(codex_home) => codex_home.to_path_buf(),
|
||||
Err(err) => {
|
||||
tui::discard_terminal_input();
|
||||
tui::abandon_prepared_terminal();
|
||||
eprintln!("Error finding codex home: {err}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
@@ -1018,6 +1018,7 @@ pub async fn run_main(
|
||||
Some(provider)
|
||||
} else {
|
||||
// No provider configured, prompt the user
|
||||
tui::discard_terminal_input();
|
||||
let selection = oss_selection::select_oss_provider().await?;
|
||||
let provider = selection.provider;
|
||||
if provider == "__CANCELLED__" {
|
||||
@@ -1148,7 +1149,7 @@ pub async fn run_main(
|
||||
match check_execpolicy_for_warnings(&config.config_layer_stack).await {
|
||||
Ok(None) => {}
|
||||
Ok(Some(err)) | Err(err) => {
|
||||
tui::discard_terminal_input();
|
||||
tui::abandon_prepared_terminal();
|
||||
eprintln!(
|
||||
"Error loading rules:\n{}",
|
||||
format_exec_policy_error_with_source(&err)
|
||||
@@ -1166,7 +1167,7 @@ pub async fn run_main(
|
||||
) {
|
||||
#[allow(clippy::print_stderr)]
|
||||
{
|
||||
tui::discard_terminal_input();
|
||||
tui::abandon_prepared_terminal();
|
||||
eprintln!("Error adding directories: {warning}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
@@ -1186,7 +1187,7 @@ pub async fn run_main(
|
||||
})
|
||||
.await
|
||||
{
|
||||
tui::discard_terminal_input();
|
||||
tui::abandon_prepared_terminal();
|
||||
eprintln!("{err}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
@@ -1946,7 +1947,7 @@ async fn load_config_or_exit_with_fallback_cwd(
|
||||
{
|
||||
Ok(config) => config,
|
||||
Err(err) => {
|
||||
tui::discard_terminal_input();
|
||||
tui::abandon_prepared_terminal();
|
||||
eprintln!("Error loading configuration: {err}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
@@ -1976,7 +1977,7 @@ async fn load_bootstrap_config_or_exit(
|
||||
{
|
||||
Ok(config_toml) => config_toml,
|
||||
Err(err) => {
|
||||
tui::discard_terminal_input();
|
||||
tui::abandon_prepared_terminal();
|
||||
let config_error = err
|
||||
.get_ref()
|
||||
.and_then(|err| err.downcast_ref::<ConfigLoadError>())
|
||||
|
||||
@@ -77,6 +77,7 @@ pub(crate) struct InitializedTerminal {
|
||||
|
||||
pub(crate) use startup::PreparedTerminal;
|
||||
use startup::StartupInputBuffer;
|
||||
pub(crate) use startup::abandon_prepared_terminal;
|
||||
use startup::capture_startup_input;
|
||||
pub(crate) use startup::discard_terminal_input;
|
||||
|
||||
|
||||
@@ -4,11 +4,14 @@ use std::io::stdin;
|
||||
use std::io::stdout;
|
||||
use std::time::Duration;
|
||||
|
||||
use crossterm::event::DisableBracketedPaste;
|
||||
use crossterm::event::EnableBracketedPaste;
|
||||
use crossterm::event::Event;
|
||||
use crossterm::event::KeyCode;
|
||||
use crossterm::event::KeyEvent;
|
||||
use crossterm::event::KeyEventKind;
|
||||
use crossterm::event::KeyModifiers;
|
||||
use crossterm::execute;
|
||||
use ratatui::backend::CrosstermBackend;
|
||||
use ratatui::layout::Position;
|
||||
|
||||
@@ -30,6 +33,8 @@ impl Drop for PreparedTerminal {
|
||||
discard_terminal_input();
|
||||
if self.terminal_modes_active {
|
||||
let _ = super::restore_after_exit();
|
||||
} else {
|
||||
let _ = disable_startup_paste_capture();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -145,6 +150,15 @@ pub(crate) fn discard_terminal_input() {
|
||||
flush_terminal_input_buffer();
|
||||
}
|
||||
|
||||
pub(crate) fn abandon_prepared_terminal() {
|
||||
discard_terminal_input();
|
||||
let _ = disable_startup_paste_capture();
|
||||
}
|
||||
|
||||
fn disable_startup_paste_capture() -> Result<()> {
|
||||
execute!(stdout(), DisableBracketedPaste)
|
||||
}
|
||||
|
||||
pub(super) fn capture_startup_input(input: &mut StartupInputBuffer) -> Result<()> {
|
||||
while crossterm::event::poll(Duration::ZERO)? {
|
||||
input.handle_event(crossterm::event::read()?);
|
||||
@@ -153,7 +167,7 @@ pub(super) fn capture_startup_input(input: &mut StartupInputBuffer) -> Result<()
|
||||
}
|
||||
|
||||
impl PreparedTerminal {
|
||||
/// Clear stale shell input before slower startup work begins.
|
||||
/// Start preserving terminal paste boundaries before slower startup work begins.
|
||||
pub(crate) fn prepare() -> Result<Self> {
|
||||
if !stdin().is_terminal() {
|
||||
return Err(std::io::Error::other("stdin is not a terminal"));
|
||||
@@ -161,7 +175,9 @@ impl PreparedTerminal {
|
||||
if !stdout().is_terminal() {
|
||||
return Err(std::io::Error::other("stdout is not a terminal"));
|
||||
}
|
||||
discard_terminal_input();
|
||||
super::ensure_virtual_terminal_processing()?;
|
||||
super::set_panic_hook();
|
||||
execute!(stdout(), EnableBracketedPaste)?;
|
||||
Ok(Self {
|
||||
active: true,
|
||||
terminal_modes_active: false,
|
||||
@@ -174,7 +190,6 @@ impl PreparedTerminal {
|
||||
super::set_base_modes()?;
|
||||
let mut startup_input = StartupInputBuffer::default();
|
||||
capture_startup_input(&mut startup_input)?;
|
||||
super::set_panic_hook();
|
||||
|
||||
#[cfg(unix)]
|
||||
let backend = CrosstermBackend::new(stdout());
|
||||
|
||||
Reference in New Issue
Block a user