diff options
author | Koni Marti <koni.marti@gmail.com> | 2022-11-20 16:22:39 +0100 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2022-11-21 13:31:00 +0100 |
commit | c063b1d5f38ae144b7c86fe450a58f5f0ead667b (patch) | |
tree | cc067ecdf0312523358ae446779a68a1bb78cf44 /commands/compose/attach.go | |
parent | e5f2fb08d8a7604aeef726698ef696874bcd2561 (diff) | |
download | aerc-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.go | 93 |
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 +} |