aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--commands/compose/attach.go93
-rw-r--r--config/aerc.conf8
-rw-r--r--config/compose.go1
-rw-r--r--doc/aerc-config.5.scd13
-rw-r--r--doc/aerc.1.scd6
5 files changed, 118 insertions, 3 deletions
diff --git a/commands/compose/attach.go b/commands/compose/attach.go
index 99898d5d..967b7902 100644
--- a/commands/compose/attach.go
+++ b/commands/compose/attach.go
@@ -1,9 +1,12 @@
package compose
import (
+ "bufio"
"errors"
"fmt"
+ "io"
"os"
+ "os/exec"
"path/filepath"
"strings"
@@ -28,12 +31,19 @@ func (Attach) Complete(aerc *widgets.Aerc, args []string) []string {
return commands.CompletePath(path)
}
-func (Attach) Execute(aerc *widgets.Aerc, args []string) error {
+func (a Attach) Execute(aerc *widgets.Aerc, args []string) error {
if len(args) == 1 {
return fmt.Errorf("Usage: :attach <path>")
}
- path := strings.Join(args[1:], " ")
+ if args[1] == "-m" {
+ return a.openMenu(aerc, args[2:])
+ }
+
+ return a.addPath(aerc, strings.Join(args[1:], " "))
+}
+
+func (a Attach) addPath(aerc *widgets.Aerc, path string) error {
path, err := homedir.Expand(path)
if err != nil {
logging.Errorf("failed to expand path '%s': %v", path, err)
@@ -76,3 +86,82 @@ func (Attach) Execute(aerc *widgets.Aerc, args []string) error {
return nil
}
+
+func (a Attach) openMenu(aerc *widgets.Aerc, args []string) error {
+ filePickerCmd := aerc.Config().Compose.FilePickerCmd
+ if filePickerCmd == "" {
+ return fmt.Errorf("no file-picker-cmd defined")
+ }
+
+ if strings.Contains(filePickerCmd, "%s") {
+ verb := ""
+ if len(args) > 0 {
+ verb = args[0]
+ }
+ filePickerCmd = strings.ReplaceAll(filePickerCmd, "%s", verb)
+ }
+
+ picks, err := os.CreateTemp("", "aerc-filepicker-*")
+ if err != nil {
+ return err
+ }
+
+ filepicker := exec.Command("sh", "-c", filePickerCmd+" >&3")
+ filepicker.ExtraFiles = append(filepicker.ExtraFiles, picks)
+
+ t, err := widgets.NewTerminal(filepicker)
+ if err != nil {
+ return err
+ }
+ t.OnClose = func(err error) {
+ defer func() {
+ if err := picks.Close(); err != nil {
+ logging.Errorf("error closing file: %v", err)
+ }
+ if err := os.Remove(picks.Name()); err != nil {
+ logging.Errorf("could not remove tmp file: %v", err)
+ }
+ }()
+
+ aerc.CloseDialog()
+
+ if err != nil {
+ logging.Errorf("terminal closed with error: %v", err)
+ return
+ }
+
+ _, err = picks.Seek(0, io.SeekStart)
+ if err != nil {
+ logging.Errorf("seek failed: %v", err)
+ }
+
+ scanner := bufio.NewScanner(picks)
+ for scanner.Scan() {
+ f := strings.TrimSpace(scanner.Text())
+ if _, err := os.Stat(f); err != nil {
+ continue
+ }
+ logging.Infof("File picker attaches: %v", f)
+ err := a.addPath(aerc, f)
+ if err != nil {
+ logging.Errorf("attach failed "+
+ "for file %s: %v", f, err)
+ }
+
+ }
+ }
+
+ aerc.AddDialog(widgets.NewDialog(
+ t,
+ // start pos on screen
+ func(h int) int {
+ return h / 8
+ },
+ // dialog height
+ func(h int) int {
+ return h - 2*h/8
+ },
+ ))
+
+ return nil
+}
diff --git a/config/aerc.conf b/config/aerc.conf
index adfa1e12..8b153ad8 100644
--- a/config/aerc.conf
+++ b/config/aerc.conf
@@ -338,6 +338,14 @@ header-layout=To|From,Subject
# This parameter can also be set per account in accounts.conf.
address-book-cmd=
+# Specifies the command to be used to select attachments. Any occurence of '%s'
+# in the file-picker-cmd will be replaced the argument <arg> to :attach -m
+# <arg>.
+#
+# The command must output the selected files to standard output, one file per
+# line.
+file-picker-cmd=
+
#
# Allow to address yourself when replying
#
diff --git a/config/compose.go b/config/compose.go
index 31ee0a8b..f9c1ba90 100644
--- a/config/compose.go
+++ b/config/compose.go
@@ -14,6 +14,7 @@ type ComposeConfig struct {
AddressBookCmd string `ini:"address-book-cmd"`
ReplyToSelf bool `ini:"reply-to-self"`
NoAttachmentWarning *regexp.Regexp `ini:"-"`
+ FilePickerCmd string `ini:"file-picker-cmd"`
}
func defaultComposeConfig() ComposeConfig {
diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd
index f18b5110..513f7373 100644
--- a/doc/aerc-config.5.scd
+++ b/doc/aerc-config.5.scd
@@ -555,6 +555,19 @@ These options are configured in the *[compose]* section of aerc.conf.
Default: none
+*file-picker-cmd*
+ Specifies the command to be used to select attachments. Any occurence of
+ '%s' in the file-picker-cmd will be replaced with the argument <arg>
+ to :attach -m <arg>.
+
+ The command must output the selected files to standard output,
+ one file per line.
+
+ Example:
+ file-picker-cmd=fzf --multi --query=%s
+
+ Default: none
+
*reply-to-self*
If set to false, do not mail yourself when replying (e.g., if replying
to emails previously sent by yourself, address your replies to the
diff --git a/doc/aerc.1.scd b/doc/aerc.1.scd
index 4f9b6a7f..c1efc954 100644
--- a/doc/aerc.1.scd
+++ b/doc/aerc.1.scd
@@ -479,10 +479,14 @@ message list, the message in the message viewer, etc).
*abort*
Close the composer without sending, discarding the message in progress.
-*attach* <path>
+*attach* [-m [<arg>] | <path>]
Attaches the file at the given path to the email. The path can contain
globbing syntax described at https://godocs.io/path/filepath#Match.
+ *-m* [<arg>]
+ Runs the 'file-picker-cmd' to select files to be attached.
+ Requires an argument when 'file-picker-cmd' contains the '%s' verb.
+
*attach-key*
Attaches the public key for the configured account to the email.