-
Notifications
You must be signed in to change notification settings - Fork 0
/
spinner.go
99 lines (82 loc) · 1.54 KB
/
spinner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package main
import (
"bufio"
"fmt"
"log"
"os"
"time"
flag "github.com/spf13/pflag"
)
type spinner struct {
s []string
freq time.Duration
pos int
}
func (s *spinner) next() {
s.pos = (s.pos + 1) % len(s.s)
}
func (s spinner) curr() string {
return s.s[s.pos]
}
func spin(freq time.Duration, parts ...string) spinner {
return spinner{
s: parts,
freq: freq,
pos: 0,
}
}
var (
asciiSpinner = spin(100*time.Millisecond, `|`, `/`, `-`, `\`)
unicodeSpinner = spin(50*time.Millisecond, `⠋`, `⠙`, `⠹`, `⠸`, `⠼`, `⠴`, `⠦`, `⠧`, `⠇`, `⠏`)
)
var (
echo *bool = flag.BoolP("echo", "e", false, "echo lines read from stdin")
finalEcho *bool = flag.Bool("final-echo", false, "don't clear the last line displayed before exiting")
initialMessage *string = flag.StringP("message", "m", "", "initial text to display")
)
func main() {
flag.Parse()
scanner := bufio.NewScanner(os.Stdin)
ch := make(chan string, 10)
go func() {
for scanner.Scan() {
if *echo {
ch <- scanner.Text()
}
}
if scanner.Err() != nil {
log.Fatal(scanner.Err())
}
close(ch)
}()
var (
s = unicodeSpinner
line = *initialMessage
n = 0
)
clear := func() {
fmt.Printf("\r%-[2]*[1]s\r", "", n)
}
display := func() {
clear()
n, _ = fmt.Printf("%s %s", s.curr(), line)
}
L:
for {
select {
case <-time.Tick(s.freq):
s.next()
display()
case l, ok := <-ch:
if !ok {
break L
}
line = l
display()
}
}
clear()
if *finalEcho {
fmt.Printf(" %s\n", line)
}
}