-
-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathcmd_choose_file.go
143 lines (114 loc) · 2.71 KB
/
cmd_choose_file.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
package main
import (
"flag"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/skx/sysbox/chooseui"
"github.com/skx/sysbox/templatedcmd"
)
// Structure for our options and state.
type chooseFileCommand struct {
// Command to execute
exec string
// Filenames we'll let the user choose between
files []string
}
// Arguments adds per-command args to the object.
func (cf *chooseFileCommand) Arguments(f *flag.FlagSet) {
if cf != nil {
f.StringVar(&cf.exec, "execute", "", "Command to execute once a selection has been made")
}
}
// Info returns the name of this subcommand.
func (cf *chooseFileCommand) Info() (string, string) {
return "choose-file", `Choose a file, interactively.
Details:
This command presents a directory view, showing you all the files beneath
the named directory. You can navigate with the keyboard, and press RETURN
to select a file.
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 a
video file, interactively:
$ xine "$(sysbox choose-file ~/Videos)"
$ sysbox choose-file -execute="xine {}" ~/Videos
See also 'sysbox help choose-stdin'.`
}
// Execute is invoked if the user specifies `choose-file` as the subcommand.
func (cf *chooseFileCommand) Execute(args []string) int {
//
// Get our starting directory
//
dir := "."
if len(args) > 0 {
dir = args[0]
}
//
// Find files
//
err := filepath.Walk(dir,
func(path string, info os.FileInfo, err error) error {
// Null info? That probably means that the
// destination we're trying to walk doesn't exist.
if info == nil {
return nil
}
// We'll add anything that isn't a directory
if !info.IsDir() {
if !strings.Contains(path, "/.") && !strings.HasPrefix(path, ".") {
cf.files = append(cf.files, path)
}
}
return nil
})
if err != nil {
fmt.Printf("error walking %s: %s\n", dir, err.Error())
return 1
}
if len(cf.files) < 1 {
fmt.Printf("Failed to find any files beneath %s\n", dir)
return 1
}
//
// Launch the UI
//
chooser := chooseui.New(cf.files)
choice := chooser.Choose()
//
// Did something get chosen? If not terminate
//
if choice == "" {
return 1
}
//
// Are we executing?
//
if cf.exec != "" {
//
// Split into command and arguments
//
run := templatedcmd.Expand(cf.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 executing, so show the user's choice
//
fmt.Printf("%s\n", choice)
return 0
}