forked from abiosoft/ishell
-
Notifications
You must be signed in to change notification settings - Fork 0
/
actions.go
176 lines (154 loc) · 5.3 KB
/
actions.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
package ishell
import (
"bytes"
"fmt"
"os/exec"
"runtime"
"strings"
)
// Actions are actions that can be performed by a shell.
type Actions interface {
// ReadLine reads a line from standard input.
ReadLine() string
// ReadLineErr is ReadLine but returns error as well
ReadLineErr() (string, error)
// ReadPassword reads password from standard input without echoing the characters.
// Note that this only works as expected when the standard input is a terminal.
ReadPassword() string
// ReadPasswordErr is ReadPassword but returns error as well
ReadPasswordErr() (string, error)
// ReadMultiLinesFunc reads multiple lines from standard input. It passes each read line to
// f and stops reading when f returns false.
ReadMultiLinesFunc(f func(string) bool) string
// ReadMultiLines reads multiple lines from standard input. It stops reading when terminator
// is encountered at the end of the line. It returns the lines read including terminator.
// For more control, use ReadMultiLinesFunc.
ReadMultiLines(terminator string) string
// Println prints to output and ends with newline character.
Println(val ...interface{})
// Print prints to output.
Print(val ...interface{})
// Printf prints to output using string format.
Printf(format string, val ...interface{})
// ShowPaged shows a paged text that is scrollable.
// This leverages on "less" for unix and "more" for windows.
ShowPaged(text string) error
// MultiChoice presents options to the user.
// returns the index of the selection or -1 if nothing is
// selected.
// text is displayed before the options.
MultiChoice(options []string, text string) int
// Checklist is similar to MultiChoice but user can choose multiple variants using Space.
// init is initially selected options.
Checklist(options []string, text string, init []int) []int
// SetPrompt sets the prompt string. The string to be displayed before the cursor.
SetPrompt(prompt string)
// SetMultiPrompt sets the prompt string used for multiple lines. The string to be displayed before
// the cursor; starting from the second line of input.
SetMultiPrompt(prompt string)
// ShowPrompt sets whether prompt should show when requesting input for ReadLine and ReadPassword.
// Defaults to true.
ShowPrompt(show bool)
// Cmds returns all the commands added to the shell.
Cmds() []*Cmd
// HelpText returns the computed help of top level commands.
HelpText() string
// ClearScreen clears the screen. Same behaviour as running 'clear' in unix terminal or 'cls' in windows cmd.
ClearScreen() error
// Stop stops the shell. This will stop the shell from auto reading inputs and calling
// registered functions. A stopped shell is only inactive but totally functional.
// Its functions can still be called and can be restarted.
Stop()
}
type shellActionsImpl struct {
*Shell
}
// ReadLine reads a line from standard input.
func (s *shellActionsImpl) ReadLine() string {
line, _ := s.readLine()
return line
}
func (s *shellActionsImpl) ReadLineErr() (string, error) {
return s.readLine()
}
func (s *shellActionsImpl) ReadPassword() string {
return s.reader.readPassword()
}
func (s *shellActionsImpl) ReadPasswordErr() (string, error) {
return s.reader.readPasswordErr()
}
func (s *shellActionsImpl) ReadMultiLinesFunc(f func(string) bool) string {
lines, _ := s.readMultiLinesFunc(f)
return lines
}
func (s *shellActionsImpl) ReadMultiLines(terminator string) string {
return s.ReadMultiLinesFunc(func(line string) bool {
if strings.HasSuffix(strings.TrimSpace(line), terminator) {
return false
}
return true
})
}
func (s *shellActionsImpl) Println(val ...interface{}) {
s.reader.buf.Truncate(0)
fmt.Fprintln(s.writer, val...)
}
func (s *shellActionsImpl) Print(val ...interface{}) {
s.reader.buf.Truncate(0)
fmt.Fprint(s.reader.buf, val...)
fmt.Fprint(s.writer, val...)
}
func (s *shellActionsImpl) Printf(format string, val ...interface{}) {
s.reader.buf.Truncate(0)
fmt.Fprintf(s.reader.buf, format, val...)
fmt.Fprintf(s.writer, format, val...)
}
func (s *shellActionsImpl) MultiChoice(options []string, text string) int {
choice := s.multiChoice(options, text, nil, false)
return choice[0]
}
func (s *shellActionsImpl) Checklist(options []string, text string, init []int) []int {
return s.multiChoice(options, text, init, true)
}
func (s *shellActionsImpl) SetPrompt(prompt string) {
s.reader.prompt = prompt
s.reader.scanner.SetPrompt(s.reader.rlPrompt())
}
func (s *shellActionsImpl) SetMultiPrompt(prompt string) {
s.reader.multiPrompt = prompt
}
func (s *shellActionsImpl) ShowPrompt(show bool) {
s.reader.showPrompt = show
s.reader.scanner.SetPrompt(s.reader.rlPrompt())
}
func (s *shellActionsImpl) Cmds() []*Cmd {
var cmds []*Cmd
for _, cmd := range s.rootCmd.children {
cmds = append(cmds, cmd)
}
return cmds
}
func (s *shellActionsImpl) ClearScreen() error {
return clearScreen(s.Shell)
}
func (s *shellActionsImpl) ShowPaged(text string) error {
return showPaged(s.Shell, text)
}
func (s *shellActionsImpl) Stop() {
s.stop()
}
func (s *shellActionsImpl) HelpText() string {
return s.rootCmd.HelpText()
}
func showPaged(s *Shell, text string) error {
var cmd *exec.Cmd
if runtime.GOOS == "windows" {
cmd = exec.Command("more")
} else {
cmd = exec.Command("less")
}
cmd.Stdout = s.writer
cmd.Stderr = s.writer
cmd.Stdin = bytes.NewBufferString(text)
return cmd.Run()
}