From 6b25fe5c95d4b22cc6a1656a4445f04be3e68455 Mon Sep 17 00:00:00 2001 From: Christopher Gambrell Date: Mon, 27 Oct 2025 22:02:24 -0400 Subject: [PATCH] 5539 - CTRL+Z then Enter will now close shell on Windows. (#6223) * CTRL+Z then Enter will now close shell on Windows. * Additional comment. * Use EOF const * Add cfg(windows) for EOF_CHAR --------- Co-authored-by: Jeong, YunWon <69878+youknowone@users.noreply.github.com> --- vm/src/readline.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/vm/src/readline.rs b/vm/src/readline.rs index 839ac9800..77402dc68 100644 --- a/vm/src/readline.rs +++ b/vm/src/readline.rs @@ -76,6 +76,9 @@ mod rustyline_readline { repl: rustyline::Editor, } + #[cfg(windows)] + const EOF_CHAR: &str = "\u{001A}"; + impl Readline { pub fn new(helper: H) -> Self { use rustyline::*; @@ -88,6 +91,16 @@ mod rustyline_readline { ) .expect("failed to initialize line editor"); repl.set_helper(Some(helper)); + + // Bind CTRL + Z to insert EOF character on Windows + #[cfg(windows)] + { + repl.bind_sequence( + KeyEvent::new('z', Modifiers::CTRL), + EventHandler::Simple(Cmd::Insert(1, EOF_CHAR.into())), + ); + } + Self { repl } } @@ -115,7 +128,19 @@ mod rustyline_readline { use rustyline::error::ReadlineError; loop { break match self.repl.readline(prompt) { - Ok(line) => ReadlineResult::Line(line), + Ok(line) => { + // Check for CTRL + Z on Windows + #[cfg(windows)] + { + use std::io::IsTerminal; + + let trimmed = line.trim_end_matches(&['\r', '\n'][..]); + if trimmed == EOF_CHAR && io::stdin().is_terminal() { + return ReadlineResult::Eof; + } + } + ReadlineResult::Line(line) + } Err(ReadlineError::Interrupted) => ReadlineResult::Interrupt, Err(ReadlineError::Eof) => ReadlineResult::Eof, Err(ReadlineError::Io(e)) => ReadlineResult::Io(e),