-
Notifications
You must be signed in to change notification settings - Fork 1
/
boolean.go
123 lines (95 loc) · 2.3 KB
/
boolean.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package prompt
import (
editor "github.com/JosephNaberhaus/texteditor"
"strings"
)
type Boolean struct {
base
// The question to display to the user
Question string
// A function that will be called to determine if the user's input is equivalent to true.
// Defaults to defaultIsYes which returns true for "y" or "yes" (ignore capitalization).
IsTrueFunc func(string) bool
// Called when a key is pressed but before it is processed. Return `false` to cancel the event.
OnKeyFunc func(Prompt, Key) bool
editor *editor.TextEditor
}
// Show displays the prompt to the user and blocks the current Go routine until the user submits
func (b *Boolean) Show() error {
err := b.show()
if err != nil {
return err
}
b.editor = editor.NewEditor()
b.editor.SetWidth(b.output.outputWidth)
b.render(false)
for b.promptState == Showing {
nextKey, err := b.nextKey()
if err != nil {
b.finish()
return err
}
b.handleInput(nextKey)
}
return nil
}
func (b *Boolean) handleInput(input Key) {
if b.State() != Showing {
return
}
if b.OnKeyFunc != nil && !b.OnKeyFunc(b, input) {
return
}
if input == ControlEnter {
b.render(true)
b.finish()
return
}
applyKeyToEditor(input, b.editor)
if b.State() != Waiting {
b.render(false)
}
}
func (b *Boolean) render(isFinished bool) {
b.output.clear()
b.output.writeColor("? ", colorGreen)
b.output.write(b.Question)
if b.defaultResponse() {
b.output.writeColor("(Y/n) ", colorGreen)
} else {
b.output.writeColor(" (y/N) ", colorGreen)
}
b.editor.SetFirstLineIndent(b.output.cursorColumn)
if isFinished {
if b.Response() {
b.output.writeColor("Yes", colorCyan)
} else {
b.output.writeColor("No", colorCyan)
}
} else {
b.output.write(b.editor.String())
}
b.output.setCursor(b.editor.CursorRow(), b.editor.CursorColumn())
b.output.flush()
}
func (b *Boolean) defaultResponse() bool {
if b.IsTrueFunc != nil {
return b.IsTrueFunc("")
}
return defaultIsYes("")
}
// Response returns the input from the user.
func (b *Boolean) Response() bool {
input := ""
if b.editor != nil {
input = b.editor.String()
}
if b.IsTrueFunc != nil {
return b.IsTrueFunc(input)
}
return defaultIsYes(input)
}
func defaultIsYes(input string) bool {
lowercase := strings.ToLower(input)
return lowercase == "y" || lowercase == "Y"
}