aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReto Brunner <reto@labrat.space>2021-01-30 11:33:31 +0100
committerReto Brunner <reto@labrat.space>2021-01-30 14:04:23 +0100
commit949781fa0a5f0654112b4f78558347ca991a89d3 (patch)
tree1d8d58e66b567709ed746654ceb92d75667557b4
parent9385827cae7bab6534933718d21eeb489448c476 (diff)
downloadaerc-949781fa0a5f0654112b4f78558347ca991a89d3.tar.gz
Refactor lib/open to accept user provided arguments
* Get rid of open_darwin It just lead to code duplication for a simple one string change. Instead we query it during initialization * Accept user provided arguments "open" on MacOS accepts things like -A to use a specific application Pass trough arguments the user provided in order to facilitate this * Refactor the function to a struct This makes it more convenient for the caller and avoids signatures like lib.OpenFile(nil, u.String(), nil) which are fairly unreadable
-rw-r--r--commands/msg/unsubscribe.go3
-rw-r--r--commands/msgview/open.go24
-rw-r--r--doc/aerc.1.scd4
-rw-r--r--lib/open.go63
-rw-r--r--lib/open_darwin.go21
5 files changed, 70 insertions, 45 deletions
diff --git a/commands/msg/unsubscribe.go b/commands/msg/unsubscribe.go
index 205a255d..cf3e4a86 100644
--- a/commands/msg/unsubscribe.go
+++ b/commands/msg/unsubscribe.go
@@ -119,6 +119,5 @@ func unsubscribeMailto(aerc *widgets.Aerc, u *url.URL) error {
}
func unsubscribeHTTP(u *url.URL) error {
- lib.OpenFile(u.String(), nil)
- return nil
+ return lib.NewXDGOpen(u.String()).Start()
}
diff --git a/commands/msgview/open.go b/commands/msgview/open.go
index 4aa61336..47b43692 100644
--- a/commands/msgview/open.go
+++ b/commands/msgview/open.go
@@ -1,7 +1,6 @@
package msgview
import (
- "errors"
"fmt"
"io"
"io/ioutil"
@@ -28,10 +27,6 @@ func (Open) Complete(aerc *widgets.Aerc, args []string) []string {
}
func (Open) Execute(aerc *widgets.Aerc, args []string) error {
- if len(args) != 1 {
- return errors.New("Usage: open")
- }
-
mv := aerc.SelectedTab().(*widgets.MessageViewer)
p := mv.SelectedMessagePart()
@@ -60,9 +55,22 @@ func (Open) Execute(aerc *widgets.Aerc, args []string) error {
return
}
- lib.OpenFile(tmpFile.Name(), func(err error) {
- aerc.PushError(" " + err.Error())
- })
+ xdg := lib.NewXDGOpen(tmpFile.Name())
+ // pass through any arguments the user provided to the underlying handler
+ if len(args) > 1 {
+ xdg.SetArgs(args[1:])
+ }
+ err = xdg.Start()
+ if err != nil {
+ aerc.PushError(err.Error())
+ return
+ }
+ go func() {
+ err := xdg.Wait()
+ if err != nil {
+ aerc.PushError(" " + err.Error())
+ }
+ }()
aerc.PushStatus("Opened", 10*time.Second)
})
diff --git a/doc/aerc.1.scd b/doc/aerc.1.scd
index 58f35bc9..f678a0a2 100644
--- a/doc/aerc.1.scd
+++ b/doc/aerc.1.scd
@@ -307,9 +307,9 @@ message list, the message in the message viewer, etc).
Cycles between message parts being shown. The list of message parts is shown
at the bottom of the message viewer.
-*open*
+*open* [args...]
Saves the current message part in a temporary file and opens it
- with the system handler.
+ with the system handler. Any given args are forwarded to the open handler
*save* [-fp] <path>
Saves the current message part to the given path.
diff --git a/lib/open.go b/lib/open.go
index ebcf8780..8a016eb3 100644
--- a/lib/open.go
+++ b/lib/open.go
@@ -1,23 +1,62 @@
-// +build !darwin
-
package lib
import (
"os/exec"
+ "runtime"
)
-func OpenFile(filename string, onErr func(error)) {
- cmd := exec.Command("xdg-open", filename)
- err := cmd.Start()
- if err != nil && onErr != nil {
- onErr(err)
- return
+var openBin string = "xdg-open"
+
+func init() {
+ if runtime.GOOS == "darwin" {
+ openBin = "open"
+ }
+}
+
+type xdgOpen struct {
+ args []string
+ errCh chan (error)
+ cmd *exec.Cmd
+}
+
+// NewXDGOpen returns a handler for opening a file via the system handler xdg-open
+// or comparable tools on other OSs than Linux
+func NewXDGOpen(filename string) *xdgOpen {
+ errch := make(chan error, 1)
+ return &xdgOpen{
+ errCh: errch,
+ args: []string{filename},
}
+}
+
+// SetArgs sets additional arguments to the open command prior to the filename
+func (xdg *xdgOpen) SetArgs(args []string) {
+ args = append([]string{}, args...) // don't overwrite array of caller
+ filename := xdg.args[len(xdg.args)-1]
+ xdg.args = append(args, filename)
+}
+
+// Start the open handler.
+// Returns an error if the command could not be started.
+// Use Wait to wait for the commands completion and to check the error.
+func (xdg *xdgOpen) Start() error {
+ xdg.cmd = exec.Command(openBin, xdg.args...)
+ err := xdg.cmd.Start()
+ if err != nil {
+ xdg.errCh <- err // for callers that just check the error from Wait()
+ close(xdg.errCh)
+ return err
+ }
go func() {
- err := cmd.Wait()
- if err != nil && onErr != nil {
- onErr(err)
- }
+ xdg.errCh <- xdg.cmd.Wait()
+ close(xdg.errCh)
}()
+ return nil
+}
+
+// Wait for the xdg-open command to complete
+// The xdgOpen must have been started
+func (xdg *xdgOpen) Wait() error {
+ return <-xdg.errCh
}
diff --git a/lib/open_darwin.go b/lib/open_darwin.go
deleted file mode 100644
index d98c8988..00000000
--- a/lib/open_darwin.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package lib
-
-import (
- "os/exec"
-)
-
-func OpenFile(filename string, onErr func(error)) {
- cmd := exec.Command("open", filename)
- err := cmd.Start()
- if err != nil && onErr != nil {
- onErr(err)
- return
- }
-
- go func() {
- err := cmd.Wait()
- if err != nil && onErr != nil {
- onErr(err)
- }
- }()
-}