diff options
Diffstat (limited to 'commands/compose')
-rw-r--r-- | commands/compose/abort.go | 7 | ||||
-rw-r--r-- | commands/compose/attach-key.go | 7 | ||||
-rw-r--r-- | commands/compose/attach.go | 81 | ||||
-rw-r--r-- | commands/compose/cc-bcc.go | 16 | ||||
-rw-r--r-- | commands/compose/detach.go | 18 | ||||
-rw-r--r-- | commands/compose/edit.go | 27 | ||||
-rw-r--r-- | commands/compose/encrypt.go | 7 | ||||
-rw-r--r-- | commands/compose/header.go | 40 | ||||
-rw-r--r-- | commands/compose/multipart.go | 36 | ||||
-rw-r--r-- | commands/compose/next-field.go | 9 | ||||
-rw-r--r-- | commands/compose/postpone.go | 22 | ||||
-rw-r--r-- | commands/compose/send.go | 75 | ||||
-rw-r--r-- | commands/compose/sign.go | 5 | ||||
-rw-r--r-- | commands/compose/switch.go | 42 |
14 files changed, 123 insertions, 269 deletions
diff --git a/commands/compose/abort.go b/commands/compose/abort.go index a11c06c5..4bacb9c3 100644 --- a/commands/compose/abort.go +++ b/commands/compose/abort.go @@ -1,8 +1,6 @@ package compose import ( - "errors" - "git.sr.ht/~rjarry/aerc/app" ) @@ -21,12 +19,7 @@ func (Abort) Complete(args []string) []string { } func (Abort) Execute(args []string) error { - if len(args) != 1 { - return errors.New("Usage: abort") - } composer, _ := app.SelectedTabContent().(*app.Composer) - app.RemoveTab(composer, true) - return nil } diff --git a/commands/compose/attach-key.go b/commands/compose/attach-key.go index 74e05bb7..e81a6a5a 100644 --- a/commands/compose/attach-key.go +++ b/commands/compose/attach-key.go @@ -1,8 +1,6 @@ package compose import ( - "errors" - "git.sr.ht/~rjarry/aerc/app" ) @@ -21,11 +19,6 @@ func (AttachKey) Complete(args []string) []string { } func (AttachKey) Execute(args []string) error { - if len(args) != 1 { - return errors.New("Usage: attach-key") - } - composer, _ := app.SelectedTabContent().(*app.Composer) - return composer.SetAttachKey(!composer.AttachKey()) } diff --git a/commands/compose/attach.go b/commands/compose/attach.go index fb533941..3acf28c2 100644 --- a/commands/compose/attach.go +++ b/commands/compose/attach.go @@ -18,11 +18,13 @@ import ( "git.sr.ht/~rjarry/aerc/lib/xdg" "git.sr.ht/~rjarry/aerc/log" "github.com/pkg/errors" - - "git.sr.ht/~sircmpwn/getopt" ) -type Attach struct{} +type Attach struct { + Menu bool `opt:"-m"` + Name string `opt:"-r"` + Path string `opt:"..." metavar:"<path>" required:"false"` +} func init() { register(Attach{}) @@ -38,48 +40,20 @@ func (Attach) Complete(args []string) []string { } func (a Attach) Execute(args []string) error { - var ( - menu bool - read bool - ) - - opts, optind, err := getopt.Getopts(args, "mr") - if err != nil { - return err - } - - for _, opt := range opts { - switch opt.Option { - case 'm': - if read { - return errors.New("-m and -r are mutually exclusive") - } - menu = true - case 'r': - if menu { - return errors.New("-m and -r are mutually exclusive") - } - read = true + if a.Menu && a.Name != "" { + return errors.New("-m and -r are mutually exclusive") + } + switch { + case a.Menu: + return a.openMenu() + case a.Name != "": + if a.Path == "" { + return errors.New("command is required") } + return a.readCommand() + default: + return a.addPath(a.Path) } - - args = args[optind:] - - if menu { - return a.openMenu(args) - } - - if read { - if len(args) < 2 { - return fmt.Errorf("Usage: :attach -r <name> <cmd> [args...]") - } - return a.readCommand(args[0], args[1:]) - } - - if len(args) == 0 { - return fmt.Errorf("Usage: :attach <path>") - } - return a.addPath(strings.Join(args, " ")) } func (a Attach) addPath(path string) error { @@ -129,18 +103,14 @@ func (a Attach) addPath(path string) error { return nil } -func (a Attach) openMenu(args []string) error { +func (a Attach) openMenu() error { filePickerCmd := 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) + filePickerCmd = strings.ReplaceAll(filePickerCmd, "%s", a.Path) } picks, err := os.CreateTemp("", "aerc-filepicker-*") @@ -215,9 +185,8 @@ func (a Attach) openMenu(args []string) error { return nil } -func (a Attach) readCommand(name string, args []string) error { - args = append([]string{"-c"}, args...) - cmd := exec.Command("sh", args...) +func (a Attach) readCommand() error { + cmd := exec.Command("sh", "-c", a.Path) data, err := cmd.Output() if err != nil { @@ -226,20 +195,20 @@ func (a Attach) readCommand(name string, args []string) error { reader := bufio.NewReader(bytes.NewReader(data)) - mimeType, mimeParams, err := lib.FindMimeType(name, reader) + mimeType, mimeParams, err := lib.FindMimeType(a.Name, reader) if err != nil { return errors.Wrap(err, "FindMimeType") } - mimeParams["name"] = name + mimeParams["name"] = a.Name composer, _ := app.SelectedTabContent().(*app.Composer) - err = composer.AddPartAttachment(name, mimeType, mimeParams, reader) + err = composer.AddPartAttachment(a.Name, mimeType, mimeParams, reader) if err != nil { return errors.Wrap(err, "AddPartAttachment") } - app.PushSuccess(fmt.Sprintf("Attached %s", name)) + app.PushSuccess(fmt.Sprintf("Attached %s", a.Name)) return nil } diff --git a/commands/compose/cc-bcc.go b/commands/compose/cc-bcc.go index e1f94c1e..aeb6af97 100644 --- a/commands/compose/cc-bcc.go +++ b/commands/compose/cc-bcc.go @@ -1,12 +1,12 @@ package compose import ( - "strings" - "git.sr.ht/~rjarry/aerc/app" ) -type CC struct{} +type CC struct { + Recipients string `opt:"recipients"` +} func init() { register(CC{}) @@ -20,18 +20,14 @@ func (CC) Complete(args []string) []string { return nil } -func (CC) Execute(args []string) error { - var addrs string - if len(args) > 1 { - addrs = strings.Join(args[1:], " ") - } +func (c CC) Execute(args []string) error { composer, _ := app.SelectedTabContent().(*app.Composer) switch args[0] { case "cc": - return composer.AddEditor("Cc", addrs, true) + return composer.AddEditor("Cc", c.Recipients, true) case "bcc": - return composer.AddEditor("Bcc", addrs, true) + return composer.AddEditor("Bcc", c.Recipients, true) } return nil diff --git a/commands/compose/detach.go b/commands/compose/detach.go index 4847713f..a2996516 100644 --- a/commands/compose/detach.go +++ b/commands/compose/detach.go @@ -2,12 +2,13 @@ package compose import ( "fmt" - "strings" "git.sr.ht/~rjarry/aerc/app" ) -type Detach struct{} +type Detach struct { + Path string `opt:"path" required:"false"` +} func init() { register(Detach{}) @@ -22,27 +23,24 @@ func (Detach) Complete(args []string) []string { return composer.GetAttachments() } -func (Detach) Execute(args []string) error { - var path string +func (d Detach) Execute(args []string) error { composer, _ := app.SelectedTabContent().(*app.Composer) - if len(args) > 1 { - path = strings.Join(args[1:], " ") - } else { + if d.Path == "" { // if no attachment is specified, delete the first in the list atts := composer.GetAttachments() if len(atts) > 0 { - path = atts[0] + d.Path = atts[0] } else { return fmt.Errorf("No attachments to delete") } } - if err := composer.DeleteAttachment(path); err != nil { + if err := composer.DeleteAttachment(d.Path); err != nil { return err } - app.PushSuccess(fmt.Sprintf("Detached %s", path)) + app.PushSuccess(fmt.Sprintf("Detached %s", d.Path)) return nil } diff --git a/commands/compose/edit.go b/commands/compose/edit.go index 2948e964..80f4e6f4 100644 --- a/commands/compose/edit.go +++ b/commands/compose/edit.go @@ -5,10 +5,12 @@ import ( "git.sr.ht/~rjarry/aerc/app" "git.sr.ht/~rjarry/aerc/config" - "git.sr.ht/~sircmpwn/getopt" ) -type Edit struct{} +type Edit struct { + Edit bool `opt:"-e"` + NoEdit bool `opt:"-E"` +} func init() { register(Edit{}) @@ -22,30 +24,15 @@ func (Edit) Complete(args []string) []string { return nil } -func (Edit) Execute(args []string) error { +func (e Edit) Execute(args []string) error { composer, ok := app.SelectedTabContent().(*app.Composer) if !ok { return errors.New("only valid while composing") } - editHeaders := config.Compose.EditHeaders - opts, optind, err := getopt.Getopts(args, "eE") - if err != nil { - return err - } - if len(args) != optind { - return errors.New("Usage: edit [-e|-E]") - } - for _, opt := range opts { - switch opt.Option { - case 'e': - editHeaders = true - case 'E': - editHeaders = false - } - } + editHeaders := (config.Compose.EditHeaders || e.Edit) && !e.NoEdit - err = composer.ShowTerminal(editHeaders) + err := composer.ShowTerminal(editHeaders) if err != nil { return err } diff --git a/commands/compose/encrypt.go b/commands/compose/encrypt.go index b9094c5e..3121dff0 100644 --- a/commands/compose/encrypt.go +++ b/commands/compose/encrypt.go @@ -1,8 +1,6 @@ package compose import ( - "errors" - "git.sr.ht/~rjarry/aerc/app" ) @@ -21,12 +19,7 @@ func (Encrypt) Complete(args []string) []string { } func (Encrypt) Execute(args []string) error { - if len(args) != 1 { - return errors.New("Usage: encrypt") - } - composer, _ := app.SelectedTabContent().(*app.Composer) - composer.SetEncrypt(!composer.Encrypt()) return nil } diff --git a/commands/compose/header.go b/commands/compose/header.go index 5c13fde5..aaa14e43 100644 --- a/commands/compose/header.go +++ b/commands/compose/header.go @@ -6,10 +6,14 @@ import ( "git.sr.ht/~rjarry/aerc/app" "git.sr.ht/~rjarry/aerc/commands" - "git.sr.ht/~sircmpwn/getopt" ) -type Header struct{} +type Header struct { + Force bool `opt:"-f"` + Remove bool `opt:"-d"` + Name string `opt:"name"` + Value string `opt:"..." required:"false"` +} var headers = []string{ "From", @@ -38,47 +42,25 @@ func (Header) Complete(args []string) []string { } func (h Header) Execute(args []string) error { - opts, optind, err := getopt.Getopts(args, h.Options()) - args = args[optind:] - if err == nil && len(args) < 1 { - err = fmt.Errorf("not enough arguments") - } - if err != nil { - return fmt.Errorf("%w. usage: header [-fd] <name> [<value>]", err) - } - - var force bool = false - var remove bool = false - for _, opt := range opts { - switch opt.Option { - case 'f': - force = true - case 'd': - remove = true - } - } - composer, _ := app.SelectedTabContent().(*app.Composer) - name := strings.TrimRight(args[0], ":") + name := strings.TrimRight(h.Name, ":") - if remove { + if h.Remove { return composer.DelEditor(name) } - value := strings.Join(args[1:], " ") - - if !force { + if !h.Force { headers, err := composer.PrepareHeader() if err != nil { return err } - if headers.Get(name) != "" && value != "" { + if headers.Get(name) != "" && h.Value != "" { return fmt.Errorf( "Header %s is already set to %q (use -f to overwrite)", name, headers.Get(name)) } } - return composer.AddEditor(name, value, false) + return composer.AddEditor(name, h.Value, false) } diff --git a/commands/compose/multipart.go b/commands/compose/multipart.go index 0ad1dc4d..96941062 100644 --- a/commands/compose/multipart.go +++ b/commands/compose/multipart.go @@ -7,10 +7,12 @@ import ( "git.sr.ht/~rjarry/aerc/app" "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/config" - "git.sr.ht/~sircmpwn/getopt" ) -type Multipart struct{} +type Multipart struct { + Remove bool `opt:"-d"` + Mime string `opt:"mime" metavar:"<mime/type>"` +} func init() { register(Multipart{}) @@ -29,37 +31,21 @@ func (Multipart) Complete(args []string) []string { return commands.CompletionFromList(completions, args) } -func (a Multipart) Execute(args []string) error { +func (m Multipart) Execute(args []string) error { composer, ok := app.SelectedTabContent().(*app.Composer) if !ok { return fmt.Errorf(":multipart is only available on the compose::review screen") } - opts, optind, err := getopt.Getopts(args, "d") - if err != nil { - return fmt.Errorf("Usage: :multipart [-d] <mime/type>") - } - var remove bool = false - for _, opt := range opts { - if opt.Option == 'd' { - remove = true - } - } - args = args[optind:] - if len(args) != 1 { - return fmt.Errorf("Usage: :multipart [-d] <mime/type>") - } - mime := args[0] - - if remove { - return composer.RemovePart(mime) + if m.Remove { + return composer.RemovePart(m.Mime) } else { - _, found := config.Converters[mime] + _, found := config.Converters[m.Mime] if !found { - return fmt.Errorf("no command defined for MIME type: %s", mime) + return fmt.Errorf("no command defined for MIME type: %s", m.Mime) } - err = composer.AppendPart( - mime, + err := composer.AppendPart( + m.Mime, map[string]string{"Charset": "UTF-8"}, // the actual content of the part will be rendered // every time the body of the email is updated diff --git a/commands/compose/next-field.go b/commands/compose/next-field.go index be5f8e53..88fbb03d 100644 --- a/commands/compose/next-field.go +++ b/commands/compose/next-field.go @@ -1,8 +1,6 @@ package compose import ( - "fmt" - "git.sr.ht/~rjarry/aerc/app" ) @@ -21,9 +19,6 @@ func (NextPrevField) Complete(args []string) []string { } func (NextPrevField) Execute(args []string) error { - if len(args) > 2 { - return nextPrevFieldUsage(args[0]) - } composer, _ := app.SelectedTabContent().(*app.Composer) if args[0] == "prev-field" { composer.PrevField() @@ -32,7 +27,3 @@ func (NextPrevField) Execute(args []string) error { } return nil } - -func nextPrevFieldUsage(cmd string) error { - return fmt.Errorf("Usage: %s", cmd) -} diff --git a/commands/compose/postpone.go b/commands/compose/postpone.go index ac16d904..767e759c 100644 --- a/commands/compose/postpone.go +++ b/commands/compose/postpone.go @@ -6,8 +6,6 @@ import ( "github.com/pkg/errors" - "git.sr.ht/~sircmpwn/getopt" - "git.sr.ht/~rjarry/aerc/app" "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/log" @@ -15,7 +13,9 @@ import ( "git.sr.ht/~rjarry/aerc/worker/types" ) -type Postpone struct{} +type Postpone struct { + Folder string `opt:"-t"` +} func init() { register(Postpone{}) @@ -42,11 +42,6 @@ func (Postpone) Complete(args []string) []string { } func (p Postpone) Execute(args []string) error { - opts, optind, err := getopt.Getopts(args, p.Options()) - if err != nil { - return err - } - acct := app.SelectedAccount() if acct == nil { return errors.New("No account selected") @@ -63,15 +58,8 @@ func (p Postpone) Execute(args []string) error { if composer.RecalledFrom() != "" { targetFolder = composer.RecalledFrom() } - for _, opt := range opts { - if opt.Option == 't' { - targetFolder = opt.Value - } - } - args = args[optind:] - - if len(args) != 0 { - return errors.New("Usage: postpone [-t <folder>]") + if p.Folder != "" { + targetFolder = p.Folder } if targetFolder == "" { return errors.New("No Postpone location configured") diff --git a/commands/compose/send.go b/commands/compose/send.go index cd964d70..e3672471 100644 --- a/commands/compose/send.go +++ b/commands/compose/send.go @@ -10,7 +10,6 @@ import ( "strings" "time" - "git.sr.ht/~sircmpwn/getopt" "github.com/emersion/go-sasl" "github.com/emersion/go-smtp" "github.com/google/shlex" @@ -19,6 +18,7 @@ import ( "git.sr.ht/~rjarry/aerc/app" "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/commands/mode" + "git.sr.ht/~rjarry/aerc/commands/msg" "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/log" "git.sr.ht/~rjarry/aerc/models" @@ -27,7 +27,10 @@ import ( "golang.org/x/oauth2" ) -type Send struct{} +type Send struct { + Archive string `opt:"-a" action:"ParseArchive" metavar:"flat|year|month"` + CopyTo string `opt:"-t"` +} func init() { register(Send{}) @@ -52,14 +55,17 @@ func (Send) Complete(args []string) []string { return nil } -func (s Send) Execute(args []string) error { - opts, optind, err := getopt.Getopts(args, s.Options()) - if err != nil { - return err - } - if optind != len(args) { - return errors.New("Usage: send [-a <flat|year|month>] [-t <folder>") +func (s *Send) ParseArchive(arg string) error { + for _, a := range msg.ARCHIVE_TYPES { + if a == arg { + s.Archive = arg + return nil + } } + return errors.New("unsupported archive type") +} + +func (s Send) Execute(args []string) error { tab := app.SelectedTab() if tab == nil { return errors.New("No selected tab") @@ -69,15 +75,8 @@ func (s Send) Execute(args []string) error { config := composer.Config() - var copyto string = config.CopyTo - var archive string - for _, opt := range opts { - if opt.Option == 'a' { - archive = opt.Value - } - if opt.Option == 't' { - copyto = opt.Value - } + if s.CopyTo == "" { + s.CopyTo = config.CopyTo } outgoing, err := config.Outgoing.ConnectionString() @@ -115,13 +114,14 @@ func (s Send) Execute(args []string) error { domain = domain_ } ctx := sendCtx{ - uri: uri, - scheme: scheme, - auth: auth, - from: config.From, - rcpts: rcpts, - domain: domain, - copyto: copyto, + uri: uri, + scheme: scheme, + auth: auth, + from: config.From, + rcpts: rcpts, + domain: domain, + archive: s.Archive, + copyto: s.CopyTo, } log.Debugf("send config uri: %s", ctx.uri) @@ -148,7 +148,7 @@ func (s Send) Execute(args []string) error { msg+" Abort send? [Y/n] ", func(text string) { if text == "n" || text == "N" { - send(composer, ctx, header, tabName, archive) + send(composer, ctx, header, tabName) } }, func(cmd string) ([]string, string) { if cmd == "" { @@ -161,14 +161,14 @@ func (s Send) Execute(args []string) error { app.PushPrompt(prompt) } else { - send(composer, ctx, header, tabName, archive) + send(composer, ctx, header, tabName) } return nil } func send(composer *app.Composer, ctx sendCtx, - header *mail.Header, tabName string, archive string, + header *mail.Header, tabName string, ) { // we don't want to block the UI thread while we are sending // so we do everything in a goroutine and hide the composer from the user @@ -243,13 +243,13 @@ func send(composer *app.Composer, ctx sendCtx, "message sent, but copying to %v failed: %v", ctx.copyto, err.Error()) app.PushError(errmsg) - composer.SetSent(archive) + composer.SetSent(ctx.archive) composer.Close() return } } app.PushStatus("Message sent.", 10*time.Second) - composer.SetSent(archive) + composer.SetSent(ctx.archive) composer.Close() }() } @@ -267,13 +267,14 @@ func listRecipients(h *mail.Header) ([]*mail.Address, error) { } type sendCtx struct { - uri *url.URL - scheme string - auth string - from *mail.Address - rcpts []*mail.Address - domain string - copyto string + uri *url.URL + scheme string + auth string + from *mail.Address + rcpts []*mail.Address + domain string + copyto string + archive string } func newSendmailSender(ctx sendCtx) (io.WriteCloser, error) { diff --git a/commands/compose/sign.go b/commands/compose/sign.go index ae7c3417..e30fca05 100644 --- a/commands/compose/sign.go +++ b/commands/compose/sign.go @@ -1,7 +1,6 @@ package compose import ( - "errors" "time" "git.sr.ht/~rjarry/aerc/app" @@ -22,10 +21,6 @@ func (Sign) Complete(args []string) []string { } func (Sign) Execute(args []string) error { - if len(args) != 1 { - return errors.New("Usage: sign") - } - composer, _ := app.SelectedTabContent().(*app.Composer) err := composer.SetSign(!composer.Sign()) diff --git a/commands/compose/switch.go b/commands/compose/switch.go index 1cc388f1..0c027a41 100644 --- a/commands/compose/switch.go +++ b/commands/compose/switch.go @@ -2,17 +2,19 @@ package compose import ( "errors" - "fmt" "git.sr.ht/~rjarry/aerc/app" - "git.sr.ht/~sircmpwn/getopt" ) type AccountSwitcher interface { SwitchAccount(*app.AccountView) error } -type SwitchAccount struct{} +type SwitchAccount struct { + Next bool `opt:"-n"` + Prev bool `opt:"-p"` + Account string `opt:"..." metavar:"<account>" required:"false"` +} func init() { register(SwitchAccount{}) @@ -26,30 +28,9 @@ func (SwitchAccount) Complete(args []string) []string { return app.AccountNames() } -func (SwitchAccount) Execute(args []string) error { - opts, optind, err := getopt.Getopts(args, "np") - if err != nil { - return err - } - var next, prev bool - for _, opt := range opts { - switch opt.Option { - case 'n': - next = true - prev = false - case 'p': - next = false - prev = true - } - } - posargs := args[optind:] - // NOT ((prev || next) XOR (len(posargs) == 1)) - if (prev || next) == (len(posargs) == 1) { - name := "" - if acct := app.SelectedAccount(); acct != nil { - name = fmt.Sprintf("Current account: %s. ", acct.Name()) - } - return errors.New(name + "Usage: switch-account [-np] <account-name>") +func (s SwitchAccount) Execute(args []string) error { + if !s.Prev && !s.Next && s.Account == "" { + return errors.New("Usage: switch-account -n | -p | <account-name>") } switcher, ok := app.SelectedTabContent().(AccountSwitcher) @@ -58,14 +39,15 @@ func (SwitchAccount) Execute(args []string) error { } var acct *app.AccountView + var err error switch { - case prev: + case s.Prev: acct, err = app.PrevAccount() - case next: + case s.Next: acct, err = app.NextAccount() default: - acct, err = app.Account(posargs[0]) + acct, err = app.Account(s.Account) } if err != nil { return err |