diff --git a/commands/choose.go b/commands/choose.go new file mode 100644 index 0000000..5bf36b1 --- /dev/null +++ b/commands/choose.go @@ -0,0 +1,48 @@ +package commands + +import ( + "fmt" + "strings" + + "git.sr.ht/~sircmpwn/aerc/widgets" +) + +type Choose struct{} + +func init() { + register(Choose{}) +} + +func (Choose) Aliases() []string { + return []string{"choose"} +} + +func (Choose) Complete(aerc *widgets.Aerc, args []string) []string { + return nil +} + +func (Choose) Execute(aerc *widgets.Aerc, args []string) error { + if len(args) < 5 || len(args)%4 != 1 { + return chooseUsage(args[0]) + } + + choices := []widgets.Choice{} + for i := 0; i+4 < len(args); i+=4 { + if args[i+1] != "-o" { + return chooseUsage(args[0]) + } + choices = append(choices, widgets.Choice{ + Key: args[i+2], + Text: args[i+3], + Command: strings.Split(args[i+4], " "), + }) + } + + aerc.RegisterChoices(choices) + + return nil +} + +func chooseUsage(cmd string) error { + return fmt.Errorf("Usage: %s -o [-o ]...", cmd) +} diff --git a/doc/aerc.1.scd b/doc/aerc.1.scd index 0294784..d2e52a9 100644 --- a/doc/aerc.1.scd +++ b/doc/aerc.1.scd @@ -77,6 +77,9 @@ These commands work in any context. passed as one argument to the command, unless it is empty, in which case no extra argument is added. +*choose* -o [-o ]... + Prompts the user to choose from various options. + *quit* Exits aerc. diff --git a/widgets/aerc.go b/widgets/aerc.go index 1d45696..8307bd0 100644 --- a/widgets/aerc.go +++ b/widgets/aerc.go @@ -39,6 +39,12 @@ type Aerc struct { getpasswd *GetPasswd } +type Choice struct { + Key string + Text string + Command []string +} + func NewAerc(conf *config.AercConfig, logger *log.Logger, cmd func(cmd []string) error, complete func(cmd string) []string, cmdHistory lib.History) *Aerc { @@ -444,6 +450,33 @@ func (aerc *Aerc) RegisterPrompt(prompt string, cmd []string) { aerc.prompts.Push(p) } +func (aerc *Aerc) RegisterChoices(choices []Choice) { + cmds := make(map[string][]string) + texts := []string{} + for _, c := range choices { + text := fmt.Sprintf("[%s] %s", c.Key, c.Text) + if strings.Contains(c.Text, c.Key) { + text = strings.Replace(c.Text, c.Key, "[" + c.Key + "]", 1) + } + texts = append(texts, text) + cmds[c.Key] = c.Command + } + prompt := strings.Join(texts, ", ") + "? " + p := NewPrompt(aerc.conf, prompt, func(text string) { + cmd, ok := cmds[text] + if !ok { + return + } + err := aerc.cmd(cmd) + if err != nil { + aerc.PushError(" " + err.Error()) + } + }, func(cmd string) []string { + return nil // TODO: completions + }) + aerc.prompts.Push(p) +} + func (aerc *Aerc) Mailto(addr *url.URL) error { acct := aerc.SelectedAccount() if acct == nil {