I want to run an executable that blocks on stdin and when a key is pressed that same character is printed immediately without Enter having to be pressed.
You can also use termion, but you will have to enable the raw TTY mode which changes the behavior of stdout as well. See the example below (tested with Rust 1.34.0). Note that internally, it also wraps the termios UNIX API.
[dependencies]
termion = "1.5.2"
use std::io;
use std::io::Write;
use std::thread;
use std::time;
use termion;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
fn main() {
// Set terminal to raw mode to allow reading stdin one key at a time
let mut stdout = io::stdout().into_raw_mode().unwrap();
// Use asynchronous stdin
let mut stdin = termion::async_stdin().keys();
loop {
// Read input (if any)
let input = stdin.next();
// If a key was pressed
if let Some(Ok(key)) = input {
match key {
// Exit if 'q' is pressed
termion::event::Key::Char('q') => break,
// Else print the pressed key
_ => {
write!(
stdout,
"{}{}Key pressed: {:?}",
termion::clear::All,
termion::cursor::Goto(1, 1),
key
)
.unwrap();
stdout.lock().flush().unwrap();
}
}
}
thread::sleep(time::Duration::from_millis(50));
}
}