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
|
package browserenv
import (
"io"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"github.com/pkg/browser"
)
var Stderr io.Writer = os.Stderr
var Stdout io.Writer = os.Stdout
var percentS = regexp.MustCompile("%s[[:^alpha:]]?")
const commandSeparator = ":"
func OpenFile(path string) error {
envCommand := envBrowserCommand()
if envCommand != "" {
path, err := filepath.Abs(path)
if err != nil {
return err
}
url := "file://" + path
return runBrowserCommand(envCommand, url)
}
return browser.OpenFile(path)
}
func OpenReader(r io.Reader) error {
envCommand := envBrowserCommand()
if envCommand != "" {
tempFile, err := ioutil.TempFile("", "browserenv")
if err != nil {
return err
}
_, err = io.Copy(tempFile, r)
if err != nil {
return err
}
return OpenFile(tempFile.Name())
}
return browser.OpenReader(r)
}
func OpenURL(url string) error {
envCommand := envBrowserCommand()
if envCommand != "" {
return runBrowserCommand(envCommand, url)
}
return browser.OpenURL(url)
}
// TODO
func envBrowserCommand() string {
return os.Getenv("BROWSER")
}
// TODO
func runBrowserCommand(commands, url string) error {
commandList := strings.Split(commands, commandSeparator)
var err error
for _, command := range commandList {
cmd := browserCommand(command, url)
// Keep running commands from left to right until one of them exits
// successfully.
err = cmd.Run()
if err == nil || cmd.ProcessState.ExitCode() == 0 {
return err
}
}
return err
}
// TODO
func browserCommand(command, url string) *exec.Cmd {
shellArgs := shell()
shell := shellArgs[0]
args := shellArgs[1:]
command = fmtBrowserCommand(command, url)
args = append(args, command)
cmd := exec.Command(shell, args...)
cmd.Stdout = Stdout
cmd.Stderr = Stderr
return cmd
}
func fmtBrowserCommand(command, url string) string {
url = escapeURL(url)
if browserCommandIncludesURL(command) {
command = fmtWithURL(command, url)
} else {
command = shellEscapeCommand(command, url)
}
return command
}
func browserCommandIncludesURL(command string) bool {
return percentS.MatchString(command)
}
func fmtWithURL(command, url string) string {
// TODO: shellescape URL
return strings.ReplaceAll(command, "%s", url)
}
func escapeURL(url string) string {
return strings.ReplaceAll(url, "'", "%27")
}
|