49 lines
998 B
Go
49 lines
998 B
Go
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
|
||
|
|
}
|