diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | config/aerc.conf | 6 | ||||
-rw-r--r-- | config/openers.go | 19 | ||||
-rw-r--r-- | doc/aerc-config.5.scd | 6 | ||||
-rw-r--r-- | lib/open.go | 22 |
5 files changed, 38 insertions, 16 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index cfb16690..4081aa86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). disabled using the `disable-ipc` setting. - Allow configuring URL handlers via `x-scheme-handler/<scheme>` `[openers]` in `aerc.conf`. +- Allow basic shell globbing in `[openers]` MIME types. ### Changed diff --git a/config/aerc.conf b/config/aerc.conf index bd8b08d8..02ea96fe 100644 --- a/config/aerc.conf +++ b/config/aerc.conf @@ -495,9 +495,13 @@ message/rfc822=colorize # encountered in the command, the temporary filename will be appened to the end # of the command. # +# Like [filters], openers support basic shell globbing. The first opener which +# matches the part's MIME type (or URL scheme handler MIME type) will be used, +# so order them from most to least specific. +# # Examples: # x-scheme-handler/irc=hexchat -# x-scheme-handler/http=firefox +# x-scheme-handler/http*=firefox # text/html=surf -dfgms # text/plain=gvim {} +125 # message/rfc822=thunderbird diff --git a/config/openers.go b/config/openers.go index 181536f5..e246ea64 100644 --- a/config/openers.go +++ b/config/openers.go @@ -1,6 +1,7 @@ package config import ( + "fmt" "strings" "git.sr.ht/~rjarry/aerc/log" @@ -8,7 +9,12 @@ import ( "github.com/google/shlex" ) -var Openers = make(map[string][]string) +type Opener struct { + Mime string + Args []string +} + +var Openers []Opener func parseOpeners(file *ini.File) error { openers, err := file.GetSection("openers") @@ -16,12 +22,15 @@ func parseOpeners(file *ini.File) error { goto out } - for mimeType, command := range openers.KeysHash() { - mimeType = strings.ToLower(mimeType) - if args, err := shlex.Split(command); err != nil { + for _, key := range openers.Keys() { + mime := strings.ToLower(key.Name()) + if args, err := shlex.Split(key.Value()); err != nil { return err } else { - Openers[mimeType] = args + if len(args) == 0 { + return fmt.Errorf("opener command empty for %s", mime) + } + Openers = append(Openers, Opener{Mime: mime, Args: args}) } } diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd index 290a1381..faa79cad 100644 --- a/doc/aerc-config.5.scd +++ b/doc/aerc-config.5.scd @@ -812,12 +812,16 @@ _{}_ is expanded as the temporary filename or URL to be opened. If it is not encountered in the command, the filename/URL will be appened to the end of the command. Environment variables are also expanded. Tilde is not expanded. +Like *[filters]*, openers support basic shell globbing. The first opener which +matches the part's MIME type (or URL scheme handler MIME type) will be used, so +order them from most to least specific. + Example: ``` [openers] x-scheme-handler/irc=hexchat -x-scheme-handler/https=firefox +x-scheme-handler/http\*=firefox text/html=surf -dfgms text/plain=gvim {} +125 message/rfc822=thunderbird diff --git a/lib/open.go b/lib/open.go index 0af51d1c..b60c4165 100644 --- a/lib/open.go +++ b/lib/open.go @@ -8,6 +8,7 @@ import ( "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/log" + "github.com/danwakefield/fnmatch" ) func XDGOpenMime( @@ -15,18 +16,21 @@ func XDGOpenMime( ) error { if len(args) == 0 { // no explicit command provided, lookup opener from mime type - opener, ok := config.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") + for _, o := range config.Openers { + if fnmatch.Match(o.Mime, mimeType, 0) { + args = append(args, o.Args...) + break } } } + if len(args) == 0 { + // 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++ { |