/
file_opener.go
105 lines (85 loc) · 2.07 KB
/
file_opener.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
// This is free and unencumbered software released into the public
// domain. For more information, see <http://unlicense.org> or the
// accompanying UNLICENSE file.
package command
import (
"fmt"
"os"
"github.com/nelsam/gxui"
"github.com/nelsam/gxui/themes/basic"
"github.com/nelsam/vidar/command/focus"
"github.com/nelsam/vidar/command/fs"
"github.com/nelsam/vidar/commander/bind"
"github.com/nelsam/vidar/plugin/status"
)
type Focuser interface {
For(...focus.Opt) bind.Bindable
}
type FileOpener struct {
status.General
driver gxui.Driver
file *fs.Locator
input <-chan gxui.Focusable
focuser Focuser
execer Executor
}
func NewFileOpener(driver gxui.Driver, theme *basic.Theme) *FileOpener {
o := &FileOpener{
General: status.General{Theme: theme},
driver: driver,
}
o.file = fs.NewLocator(driver, theme, fs.All)
return o
}
func (f *FileOpener) Name() string {
return "open-file"
}
func (f *FileOpener) Menu() string {
return "File"
}
func (f *FileOpener) Defaults() []fmt.Stringer {
return []fmt.Stringer{gxui.KeyboardEvent{
Modifier: gxui.ModControl,
Key: gxui.KeyO,
}}
}
func (f *FileOpener) Start(control gxui.Control) gxui.Control {
f.file.LoadDir(control)
input := make(chan gxui.Focusable, 1)
f.input = input
input <- f.file
close(input)
return nil
}
func (f *FileOpener) Next() gxui.Focusable {
return <-f.input
}
func (f *FileOpener) Reset() {
f.focuser = nil
f.execer = nil
}
func (f *FileOpener) Store(elem interface{}) bind.Status {
switch src := elem.(type) {
case Focuser:
f.focuser = src
case Executor:
f.execer = src
}
if f.focuser == nil || f.execer == nil {
return bind.Waiting
}
return bind.Executing
}
func (f *FileOpener) Exec() error {
path := f.file.Path()
if path == "" {
f.Err = "no file path provided"
return fmt.Errorf("command.FileOpener: %s", f.Err)
}
if finfo, err := os.Stat(path); err == nil && finfo.IsDir() {
f.Err = fmt.Sprintf("can't open directory %s as file", path)
return fmt.Errorf("command.FileOpener: %s", f.Err)
}
f.execer.Execute(f.focuser.For(focus.Path(path)))
return nil
}