aboutsummaryrefslogtreecommitdiffstats
path: root/commands/compose/attach.go
diff options
context:
space:
mode:
authorKoni Marti <koni.marti@gmail.com>2022-11-20 16:22:39 +0100
committerRobin Jarry <robin@jarry.cc>2022-11-21 13:31:00 +0100
commitc063b1d5f38ae144b7c86fe450a58f5f0ead667b (patch)
treecc067ecdf0312523358ae446779a68a1bb78cf44 /commands/compose/attach.go
parente5f2fb08d8a7604aeef726698ef696874bcd2561 (diff)
downloadaerc-c063b1d5f38ae144b7c86fe450a58f5f0ead667b.tar.gz
attach: open file picker menu with -m flag
Open a user-defined file picker with the -m flag for the attach command to select attachments. Specify your file picker of choice with the 'file-picker-cmd' in the [composer] section of aerc.conf, e.g. "file-picker-cmd=fzf -m". A '%s' placeholder can be used in the 'file-picker-cmd' which is then substituted for the argument <arg> provided to :attach -m <arg>. For example, when you set 'file-picker-cmd=find %s -type f | fzf -m', you can easily change the directory to start the search with ':attach -m <path-to-search>'. Tested with fzf, fzy and peco. Implements: https://todo.sr.ht/~rjarry/aerc/108 Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Tim Culverhouse <tim@timculverhouse.com>
Diffstat (limited to 'commands/compose/attach.go')
-rw-r--r--commands/compose/attach.go93
1 files changed, 91 insertions, 2 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
+}