-
-
Notifications
You must be signed in to change notification settings - Fork 19
/
cmd_choose_stdin.go
128 lines (99 loc) · 2.34 KB
/
cmd_choose_stdin.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
package main
import (
"bufio"
"flag"
"fmt"
"os"
"os/exec"
"strings"
"github.com/skx/sysbox/chooseui"
"github.com/skx/sysbox/templatedcmd"
)
// Structure for our options and state.
type chooseSTDINCommand struct {
// Command to execute
exec string
// Filenames we'll let the user choose between
stdin []string
}
// Arguments adds per-command args to the object.
func (cs *chooseSTDINCommand) Arguments(f *flag.FlagSet) {
f.StringVar(&cs.exec, "execute", "", "Command to execute once a selection has been made")
}
// Info returns the name of this subcommand.
func (cs *chooseSTDINCommand) Info() (string, string) {
return "choose-stdin", `Choose an item from STDIN, interactively.
Details:
This command presents a simple UI, showing all the lines read from STDIN.
You can navigate with the keyboard, and press RETURN to select an entry.
Optionally you can press TAB to filter the list via an input field.
Uses:
This is ideal for choosing videos, roms, etc. For example launch the
given video file:
$ find . -name '*.avi' -print | sysbox choose-stdin -exec 'xine "{}"'
See also 'sysbox help choose-file'.`
}
// Execute is invoked if the user specifies `choose-stdin` as the subcommand.
func (cs *chooseSTDINCommand) Execute(args []string) int {
//
// Prepare to read line-by-line
//
scanner := bufio.NewReader(os.Stdin)
//
// Read a line
//
line, err := scanner.ReadString(byte('\n'))
for err == nil && line != "" {
//
// Remove any leading/trailing whitespace
//
line = strings.TrimSpace(line)
//
// Save this away
//
cs.stdin = append(cs.stdin, line)
//
// Loop again
//
line, err = scanner.ReadString(byte('\n'))
}
//
// Launch the UI
//
chooser := chooseui.New(cs.stdin)
choice := chooser.Choose()
//
// Did something get chosen? If not terminate
//
if choice == "" {
return 1
}
//
// Are we executing?
//
if cs.exec != "" {
//
// Split into command and arguments
//
run := templatedcmd.Expand(cs.exec, choice, "")
//
// Run it.
//
cmd := exec.Command(run[0], run[1:]...)
out, errr := cmd.CombinedOutput()
if errr != nil {
fmt.Printf("Error running '%v': %s\n", run, errr.Error())
return 1
}
//
// And we're done
//
fmt.Printf("%s\n", out)
return 0
}
//
// We're not running a command, so output the user's choice
//
fmt.Printf("%s\n", choice)
return 0
}