summary refs log tree commit diff stats
diff options
context:
space:
mode:
-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 205a255..cf3e4a8 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 4aa6133..47b4369 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 58f35bc..f678a0a 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 ebcf878..8a016eb 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 d98c898..0000000
--- 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)
-		}
-	}()
-}