Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send stdin keystrokes to channel without newline required

Tags:

go

channel

I'd like to send the user's keystrokes to a channel directly after each individual keystroke is made to stdin.

I've attempted the code below, but this doesn't give the desired result because the reader.ReadByte() method blocks until newline is entered.

func chars() <-chan byte {
    ch := make(chan byte)
    reader := bufio.NewReader(os.Stdin)
    go func() {
        for {           
            char, err := reader.ReadByte()
            if err != nil {
                log.Fatal(err)
            }
            ch <- char
        }
    }()
    return ch
}

Thank you for any advice on how might I get each user input character to go immediately to the channel without the need for a newline character.

like image 942
Kim Avatar asked Sep 10 '12 23:09

Kim


2 Answers

Stdin is line-buffered by default. This means it will not yield any input to you, until a newline is encountered. This is not a Go specific thing.

Having it behave in a non-buffered way is highly platform specific. As Rami suggested, ncurses is a way to do it. Another option is the much lighter go-termbox package.

If you want to do it all manually (on Linux at least), you can look at writing C bindings for termios or do syscalls directly in Go.

How platforms like Windows handle this, I do not know. You can dig into the source code for ncurses or termbox to see how they did it.

like image 155
jimt Avatar answered Nov 04 '22 05:11

jimt


If you are on Linux, You might want to look at Goncurses package

http://code.google.com/p/goncurses/

It has the function: GetChar() which is what you want.

like image 5
Rami Jarrar Avatar answered Nov 04 '22 05:11

Rami Jarrar