45bff88515
Instead of xdg-open (or open on MacOS), allow forcing a program to open a message part. The program is determined in that order of priority: 1) If :open has arguments, they will be used as command to open the attachment. If the arguments contain the {} placeholder, the temporary file will be substituted, otherwise the file path is added at the end of the arguments. 2) If a command is specified in the [openers] section of aerc.conf for the part MIME type, then it is used with the same rules of {} substitution. 3) Finally, fallback to xdg-open/open with the file path as argument. Update the docs and default config accordingly with examples. Fixes: https://todo.sr.ht/~rjarry/aerc/64 Co-authored-by: Jason Stewart <support@eggplantsd.com> Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Moritz Poldrack <moritz@poldrack.dev>
57 lines
1.2 KiB
Go
57 lines
1.2 KiB
Go
package lib
|
|
|
|
import (
|
|
"fmt"
|
|
"os/exec"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"git.sr.ht/~rjarry/aerc/logging"
|
|
)
|
|
|
|
func XDGOpen(uri string) error {
|
|
return XDGOpenMime(uri, "", nil, nil)
|
|
}
|
|
|
|
func XDGOpenMime(
|
|
uri string, mimeType string,
|
|
openers map[string][]string, args []string,
|
|
) error {
|
|
if len(args) == 0 {
|
|
// no explicit command provided, lookup opener from mime type
|
|
opener, ok := openers[mimeType]
|
|
if ok {
|
|
args = opener
|
|
} else {
|
|
// no opener defined in config, fallback to default
|
|
if runtime.GOOS == "darwin" {
|
|
args = append(args, "open")
|
|
} else {
|
|
args = append(args, "xdg-open")
|
|
}
|
|
}
|
|
}
|
|
|
|
i := 0
|
|
for ; i < len(args); i++ {
|
|
if strings.Contains(args[i], "{}") {
|
|
break
|
|
}
|
|
}
|
|
if i < len(args) {
|
|
// found {} placeholder in args, replace with uri
|
|
args[i] = strings.Replace(args[i], "{}", uri, 1)
|
|
} else {
|
|
// no {} placeholder in args, add uri at the end
|
|
args = append(args, uri)
|
|
}
|
|
|
|
logging.Infof("running command: %v", args)
|
|
cmd := exec.Command(args[0], args[1:]...)
|
|
out, err := cmd.CombinedOutput()
|
|
logging.Debugf("command: %v exited. err=%v out=%s", args, err, out)
|
|
if err != nil {
|
|
return fmt.Errorf("%v: %w", args, err)
|
|
}
|
|
return nil
|
|
}
|