~sircmpwn/aerc

on macOS, :open now can use the specified application v1 PROPOSED

JD: 1
 on macOS, :open now can use the specified application

 4 files changed, 97 insertions(+), 2 deletions(-)
> Much better would be to just pass
> any non recognized arguments to the
> open call prior to the filename.
Yeah, that makes sense, thanks for a hint.

However, about these possibile "non recognized arguments": this way, we'll have a case with no arguments at all (the usual `:open`) and a case with whatever is going after `:open` to be passed to open/xdg-open -- so, when to show help for :open then? Should we also introduce something like `:open --help`? No other commands seem to support that...
Next
> However, about these possibile "non recognized arguments": this way,
> we'll have a case with no arguments at all (the usual `:open`) and a
> case with whatever is going after `:open` to be passed to open/xdg-open
> -- so, when to show help for :open then? Should we also introduce
What do you mean by help? The command completion?
 
> something like `:open --help`? No other commands seem to support
> that...
No, we'll simply document the behaviour and call it a day. `open [args...]` or some such.
Next
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/aerc/patches/13969/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH] on macOS, :open now can use the specified application Export this patch

Differently from xdg-open, macOS's /usr/bin/open can also use non-default 
applications to open files. This patch adds -A parameter to aerc's :open
command, which allows to open message parts with custom programs. E.g. to 
open a HTML part in a non-default browser, use :open -A Safari. Or even
:open -A MacVim to open it in an editor instead of a browser.

DISCLAIMER: again, I'm not a programmer, and this probably can be done in 
a way better manner (if someone needs this functionality at all :)
---
 commands/msgview/open.go        |  2 +
 commands/msgview/open_darwin.go | 89 +++++++++++++++++++++++++++++++++++++++++
 doc/aerc.1.scd                  |  5 ++-
 lib/open_darwin.go              |  3 +-
 4 files changed, 97 insertions(+), 2 deletions(-)
 create mode 100644 commands/msgview/open_darwin.go

diff --git a/commands/msgview/open.go b/commands/msgview/open.go
index 4aa6133..ec33d60 100644
--- a/commands/msgview/open.go
+++ b/commands/msgview/open.go
@@ -1,3 +1,5 @@
// +build !darwin

package msgview

import (
diff --git a/commands/msgview/open_darwin.go b/commands/msgview/open_darwin.go
new file mode 100644
index 0000000..32909e1
--- /dev/null
+++ b/commands/msgview/open_darwin.go
@@ -0,0 +1,89 @@
package msgview

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"mime"
	"os"
	"time"

	"git.sr.ht/~sircmpwn/getopt"

	"git.sr.ht/~sircmpwn/aerc/lib"
	"git.sr.ht/~sircmpwn/aerc/widgets"
)

type Open struct{}

func init() {
	register(Open{})
}

func (Open) Aliases() []string {
	return []string{"open"}
}

func (Open) Complete(aerc *widgets.Aerc, args []string) []string {
	return nil
}

func (Open) Execute(aerc *widgets.Aerc, args []string) error {
    opts, optind, err := getopt.Getopts(args, "A:")
	if err != nil {
		return err
	}
	if optind != len(args) {
		return errors.New("Usage: open [-A <application>]")
	}
	var (
		theApp   string
	)
	for _, opt := range opts {
		switch opt.Option {
		case 'A':
			theApp = opt.Value
		}
	}

	mv := aerc.SelectedTab().(*widgets.MessageViewer)
	p := mv.SelectedMessagePart()

	store := mv.Store()
	store.FetchBodyPart(p.Msg.Uid, p.Index, func(reader io.Reader) {
		extension := ""
		// try to determine the correct extension based on mimetype
		if part, err := p.Msg.BodyStructure.PartAtIndex(p.Index); err == nil {
			mimeType := fmt.Sprintf("%s/%s", part.MIMEType, part.MIMESubType)

			if exts, _ := mime.ExtensionsByType(mimeType); exts != nil && len(exts) > 0 {
				extension = exts[0]
			}
		}

		tmpFile, err := ioutil.TempFile(os.TempDir(), "aerc-*"+extension)
		if err != nil {
			aerc.PushError(" " + err.Error())
			return
		}
		defer tmpFile.Close()

		_, err = io.Copy(tmpFile, reader)
		if err != nil {
			aerc.PushError(" " + err.Error())
			return
		}

		if theApp != "" {
			theApp = "-a|" + theApp + "|"
		}
		lib.OpenFile(theApp + tmpFile.Name(), func(err error) {
			aerc.PushError(" " + err.Error())
		})

		aerc.PushStatus("Opened", 10*time.Second)
	})

	return nil
}
diff --git a/doc/aerc.1.scd b/doc/aerc.1.scd
index d77552f..45bd191 100644
--- a/doc/aerc.1.scd
+++ b/doc/aerc.1.scd
@@ -299,10 +299,13 @@ 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* [-A <application>]
	Saves the current message part in a temporary file and opens it
	with the system handler.

	*-A* On macOS, the system handler can be overridden. For example, to open
	the current message part in a non-default editor, use :open -A MacVim

*save* [-fp] <path>
	Saves the current message part to the given path.
	If the path is not an absolute path, general.default-save-path will be
diff --git a/lib/open_darwin.go b/lib/open_darwin.go
index d98c898..83619c1 100644
--- a/lib/open_darwin.go
+++ b/lib/open_darwin.go
@@ -2,10 +2,11 @@ package lib

import (
	"os/exec"
	"strings"
)

func OpenFile(filename string, onErr func(error)) {
	cmd := exec.Command("open", filename)
	cmd := exec.Command("open", strings.Split(filename, "|")...)
	err := cmd.Start()
	if err != nil && onErr != nil {
		onErr(err)
-- 
2.7.4




-- 
JD
Hi,

On Sat, Sep 19, 2020 at 02:53:33PM +0300, JD wrote: