Why does the `AlternateScreen` require pressing Enter when reading an input key?
11:05 31 Oct 2023

I have created a simple command line tool using the termion crate in Rust. It prints a "Hello world!" message when a key is pressed. It quits the program only if the input is the q character. Here is the code that uses the AlternateScreen struct to write on the terminal:

use std::io::{stdin, stdout, Write};
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
use termion::screen::IntoAlternateScreen;

fn main() {
    // Initialize stdout and stind
    let stdin = stdin();
    let mut stdout = stdout().into_alternate_screen().unwrap();

    // Print a message indicating what to do
    write!(
        stdout,
        "{}{}Press any key to print 'Hello world!', or press 'q' to quit.{}",
        termion::clear::All,
        termion::cursor::Goto(1, 1),
        termion::cursor::Hide
    )
    .unwrap();
    stdout.flush().unwrap();

    // Create an input reader for key events
    let mut row = 2;
    for c in stdin.keys() {
        let key = c.unwrap();
        if key == Key::Char('q') {
            break;
        }

        write!(
            stdout,
            "{}{}Hello world!",
            termion::cursor::Goto(1, row),
            termion::clear::CurrentLine
        )
        .unwrap();
        stdout.flush().unwrap();
        row += 1;
    }

    // Enable back the cursor
    write!(stdout, "{}", termion::cursor::Show).unwrap();
}

I write the message to a new line by going to the next row and the first column. The row variable tracks where to write the next message.

The problem is that I have to press Enter to register the characters in the standard input. However, an additional "Hello world!" text is appearing because of the extra Enter key. I would like to write the text immediately after any input key, without the need to press the Enter button.

Note that if the standard output is replaced with the RawTerminal struct, everything is working as expected.

let mut stdout = stdout().into_raw_mode().unwrap();

In this case, it is not necessary to press Enter on the input character.

Why does the AlternateScreen require pressing Enter when reading an input key?

rust terminal