package main import ( "os" "golang.org/x/sys/unix" ) // Delivers a value every time space is pressed. Puts the terminal in // non-canonical mode so the keypress arrives without waiting for a newline, // and returns a function that restores the original settings. func watchSpace() (<-chan struct{}, func()) { ch := make(chan struct{}, 1) restore := func() {} fd := int(os.Stdin.Fd()) if orig, err := unix.IoctlGetTermios(fd, unix.TCGETS); err == nil { saved := *orig raw := *orig raw.Lflag &^= unix.ICANON | unix.ECHO raw.Cc[unix.VMIN] = 1 raw.Cc[unix.VTIME] = 0 if unix.IoctlSetTermios(fd, unix.TCSETS, &raw) == nil { restore = func() { unix.IoctlSetTermios(fd, unix.TCSETS, &saved) } } } go func() { buf := make([]byte, 64) for { n, err := os.Stdin.Read(buf) if err != nil { return } for _, b := range buf[:n] { if b != ' ' { continue } select { case ch <- struct{}{}: default: } } } }() return ch, restore }