Add :choose command

Usage:
	*choose* -o <key> <text> <command> [-o <key> <text> <command>]...

Prompts the user to choose from various options.
This commit is contained in:
Ray Ganardi 2020-04-24 11:36:16 +02:00 committed by Drew DeVault
parent acf69b7490
commit 447e662057
3 changed files with 84 additions and 0 deletions

48
commands/choose.go Normal file
View file

@ -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 <key> <text> <command> [-o <key> <text> <command>]...", cmd)
}

View file

@ -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 <key> <text> <command> [-o <key> <text> <command>]...
Prompts the user to choose from various options.
*quit*
Exits aerc.

View file

@ -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 {