Fix/input suppress output on windows (#9459)

this PR should close #9018

# Description
This PR aims to fix the `input` command with `--suppress-output` on
Windows
This fixes two separates issues : 
- Keypresses being duplicated in output due to "Release" event not being
ignored
- "Return" event from entering the `input -s "blah :"` still being in
the event buffer (need to be cleared before reading keypresses)

# Tests + Formatting

- `cargo fmt --all -- --check` ✔️ 
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect -A clippy::result_large_err` ✔️
- `cargo test --workspace` ✔️
- `cargo run -- crates/nu-std/tests/run.nu` ✔️
This commit is contained in:
Sygmei 2023-06-19 19:04:37 +02:00 committed by GitHub
parent d78e3c3b0d
commit d25fb3ad56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,4 +1,4 @@
use crossterm::event::{Event, KeyCode, KeyModifiers}; use crossterm::event::{Event, KeyCode, KeyEventKind, KeyModifiers};
use nu_engine::CallExt; use nu_engine::CallExt;
use nu_protocol::ast::Call; use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::engine::{Command, EngineState, Stack};
@ -7,6 +7,7 @@ use nu_protocol::{
Type, Value, Type, Value,
}; };
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::time::Duration;
#[derive(Clone)] #[derive(Clone)]
pub struct Input; pub struct Input;
@ -132,31 +133,46 @@ impl Command for Input {
if suppress_output || numchar_exists { if suppress_output || numchar_exists {
crossterm::terminal::enable_raw_mode()?; crossterm::terminal::enable_raw_mode()?;
// clear terminal events
while crossterm::event::poll(Duration::from_secs(0))? {
// If there's an event, read it to remove it from the queue
let _ = crossterm::event::read()?;
}
loop { loop {
if i64::try_from(buf.len()).unwrap_or(0) >= numchar.item { if i64::try_from(buf.len()).unwrap_or(0) >= numchar.item {
let _ = crossterm::terminal::disable_raw_mode(); let _ = crossterm::terminal::disable_raw_mode();
break; break;
} }
match crossterm::event::read() { match crossterm::event::read() {
Ok(Event::Key(k)) => match k.code { Ok(Event::Key(k)) => match k.kind {
// TODO: maintain keycode parity with existing command KeyEventKind::Press | KeyEventKind::Repeat => {
KeyCode::Char(c) => { match k.code {
if k.modifiers == KeyModifiers::ALT // TODO: maintain keycode parity with existing command
|| k.modifiers == KeyModifiers::CONTROL KeyCode::Char(c) => {
{ if k.modifiers == KeyModifiers::ALT
if k.modifiers == KeyModifiers::CONTROL && c == 'c' { || k.modifiers == KeyModifiers::CONTROL
crossterm::terminal::disable_raw_mode()?; {
return Err(ShellError::IOError("SIGINT".to_string())); if k.modifiers == KeyModifiers::CONTROL && c == 'c' {
} crossterm::terminal::disable_raw_mode()?;
continue; return Err(ShellError::IOError(
} "SIGINT".to_string(),
));
}
continue;
}
buf.push(c); buf.push(c);
}
KeyCode::Backspace => {
let _ = buf.pop();
}
KeyCode::Enter => {
break;
}
_ => continue,
}
} }
KeyCode::Backspace => {
let _ = buf.pop();
}
KeyCode::Enter => break,
_ => continue, _ => continue,
}, },
Ok(_) => continue, Ok(_) => continue,