diff options
Diffstat (limited to 'commands/msg/read.go')
-rw-r--r-- | commands/msg/read.go | 131 |
1 files changed, 46 insertions, 85 deletions
diff --git a/commands/msg/read.go b/commands/msg/read.go index cffd2218..55bb90c4 100644 --- a/commands/msg/read.go +++ b/commands/msg/read.go @@ -2,16 +2,20 @@ package msg import ( "fmt" + "strings" "time" - "git.sr.ht/~sircmpwn/getopt" - "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/widgets" "git.sr.ht/~rjarry/aerc/worker/types" ) -type FlagMsg struct{} +type FlagMsg struct { + Toggle bool `opt:"-t"` + Answered bool `opt:"-a"` + Flag models.Flags `opt:"-x" parse:"ParseFlag"` + FlagName string +} func init() { register(FlagMsg{}) @@ -25,6 +29,23 @@ func (FlagMsg) Complete(aerc *widgets.Aerc, args []string) []string { return nil } +func (f *FlagMsg) ParseFlag(arg string) error { + switch strings.ToLower(arg) { + case "seen": + f.Flag = models.SeenFlag + f.FlagName = "seen" + case "answered": + f.Flag = models.AnsweredFlag + f.FlagName = "answered" + case "flagged": + f.Flag = models.FlaggedFlag + f.FlagName = "flagged" + default: + return fmt.Errorf("Unknown flag %q", arg) + } + return nil +} + // If this was called as 'flag' or 'unflag', without the toggle (-t) // option, then it will flag the corresponding messages with the given // flag. If the toggle option was given, it will individually toggle @@ -32,84 +53,18 @@ func (FlagMsg) Complete(aerc *widgets.Aerc, args []string) []string { // // If this was called as 'read' or 'unread', it has the same effect as // 'flag' or 'unflag', respectively, but the 'Seen' flag is affected. -func (FlagMsg) Execute(aerc *widgets.Aerc, args []string) error { - // The flag to change - var flag models.Flags - // User-readable name of the flag to change - var flagName string - // Whether to toggle the flag (true) or to enable/disable it (false) - var toggle bool - // Whether to enable (true) or disable (false) the flag - enable := (args[0] == "read" || args[0] == "flag") +func (f FlagMsg) Execute(aerc *widgets.Aerc, args []string) error { // User-readable name for the action being performed var actionName string - // Getopt option string, varies by command name - var getoptString string - // Help message to provide on parsing failure - var helpMessage string - // Used during parsing to prevent choosing a flag muliple times - // A default flag will be used if this is false - flagChosen := false - - if args[0] == "read" || args[0] == "unread" { - flag = models.SeenFlag - flagName = "read" - getoptString = "t" - helpMessage = "Usage: " + args[0] + " [-t]" - } else { // 'flag' / 'unflag' - flag = models.FlaggedFlag - flagName = "flagged" - getoptString = "tax:" - helpMessage = "Usage: " + args[0] + " [-t] [-a | -x <flag>]" - } - opts, optind, err := getopt.Getopts(args, getoptString) - if err != nil { - return err - } - for _, opt := range opts { - switch opt.Option { - case 't': - toggle = true - case 'a': - if flagChosen { - return fmt.Errorf("Cannot choose a flag multiple times! " + helpMessage) - } - flag = models.AnsweredFlag - flagName = "answered" - flagChosen = true - case 'x': - if flagChosen { - return fmt.Errorf("Cannot choose a flag multiple times! " + helpMessage) - } - // TODO: Support all flags? - switch opt.Value { - case "Seen": - flag = models.SeenFlag - flagName = "seen" - case "Answered": - flag = models.AnsweredFlag - flagName = "answered" - case "Flagged": - flag = models.FlaggedFlag - flagName = "flagged" - default: - return fmt.Errorf("Unknown / Prohibited flag \"%v\"", opt.Value) - } - flagChosen = true + switch args[0] { + case "read", "unread": + if f.Flag != 0 || f.Answered { + // these arguments are only supported for :flag :unflag + return fmt.Errorf("Usage: %s -t", args[0]) } - } - switch { - case toggle: - actionName = "Toggling" - case enable: - actionName = "Setting" - default: - actionName = "Unsetting" - } - if optind != len(args) { - // Any non-option arguments: Error - return fmt.Errorf(helpMessage) + f.Flag = models.SeenFlag + f.FlagName = "seen" } h := newHelper(aerc) @@ -122,7 +77,7 @@ func (FlagMsg) Execute(aerc *widgets.Aerc, args []string) error { var toEnable []uint32 var toDisable []uint32 - if toggle { + if f.Toggle { // If toggling, split messages into those that need to // be enabled / disabled. msgs, err := h.messages() @@ -130,29 +85,35 @@ func (FlagMsg) Execute(aerc *widgets.Aerc, args []string) error { return err } for _, m := range msgs { - if m.Flags.Has(flag) { + if m.Flags.Has(f.Flag) { toDisable = append(toDisable, m.Uid) } else { toEnable = append(toEnable, m.Uid) } } + actionName = "Toggling" } else { msgUids, err := h.markedOrSelectedUids() if err != nil { return err } - if enable { + switch args[0] { + case "read", "flag": toEnable = msgUids - } else { + actionName = "Setting" + default: toDisable = msgUids + actionName = "Unsetting" } } + status := fmt.Sprintf("%s flag %q successful", actionName, f.FlagName) + if len(toEnable) != 0 { - store.Flag(toEnable, flag, true, func(msg types.WorkerMessage) { + store.Flag(toEnable, f.Flag, true, func(msg types.WorkerMessage) { switch msg := msg.(type) { case *types.Done: - aerc.PushStatus(actionName+" flag '"+flagName+"' successful", 10*time.Second) + aerc.PushStatus(status, 10*time.Second) store.Marker().ClearVisualMark() case *types.Error: aerc.PushError(msg.Error.Error()) @@ -160,10 +121,10 @@ func (FlagMsg) Execute(aerc *widgets.Aerc, args []string) error { }) } if len(toDisable) != 0 { - store.Flag(toDisable, flag, false, func(msg types.WorkerMessage) { + store.Flag(toDisable, f.Flag, false, func(msg types.WorkerMessage) { switch msg := msg.(type) { case *types.Done: - aerc.PushStatus(actionName+" flag '"+flagName+"' successful", 10*time.Second) + aerc.PushStatus(status, 10*time.Second) store.Marker().ClearVisualMark() case *types.Error: aerc.PushError(msg.Error.Error()) |