...
1 package watch
2
3 import (
4 "context"
5 "fmt"
6 "io"
7 "os"
8
9 "golang.org/x/term"
10 )
11
12
13
14 func getKeyWatcher(ctx context.Context, out io.Writer) <-chan byte {
15
16 keyInput := make(chan byte)
17
18 go func() {
19 stdinfd := int(os.Stdin.Fd())
20 if !term.IsTerminal(stdinfd) {
21 return
22 }
23
24
25
26
27
28 oldState, err := term.GetState(stdinfd)
29 if err != nil {
30 fmt.Fprintln(out, fmt.Errorf("getstate: %w", err))
31 return
32 }
33 err = enableCharInput(stdinfd)
34 if err != nil {
35 fmt.Fprintln(out, fmt.Errorf("enableCharInput: %w", err))
36 return
37 }
38 defer func() {
39 _ = term.Restore(stdinfd, oldState)
40 }()
41
42
43
44 for {
45 select {
46 case <-ctx.Done():
47 return
48 case b := <-getKey(out):
49 keyInput <- b
50 }
51 }
52 }()
53
54 return keyInput
55 }
56
57
58
59 func getKey(out io.Writer) <-chan byte {
60
61 ch := make(chan byte)
62
63 go func() {
64 b := make([]byte, 1)
65 _, err := os.Stdin.Read(b)
66 if err != nil {
67 fmt.Fprintln(out, fmt.Errorf("read: %w", err))
68 return
69 }
70 ch <- b[0]
71 }()
72
73 return ch
74 }
75
View as plain text