Files
aerc-fork-mirror/commands/patch/patch.go
Robin Jarry d7cdaf1977 patch: use subcommand descriptions in completion items
go-opt v2.2.0 now supports providing individual descriptions for
completion items by appending a newline character to the completion item
followed by its description.

Do that for patch sub commands. Here's what it looks like:

       apply    (Apply the selected message(s) to the current project.)
       cd       (Change aerc's working directory to the current project.)
       drop     (Drop a patch from the repository.)
       find     (Search for applied patches.)
       init     (Create a new project.)
       list     (List the current project with the tracked patch sets.)
       ls       (List the current project with the tracked patch sets.)
       rebase   (Rebase the patch data.)
       switch   (Switch context to the specified project.)
       term     (Open a shell or run a command in the current project's directory.)
       unlink   (Delete all patch tracking data for the specified project.)
:patch

Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Antonin Godard <antonin@godard.cc>
2025-11-17 09:51:00 +01:00

92 lines
2.0 KiB
Go

package patch
import (
"errors"
"fmt"
"reflect"
"sort"
"git.sr.ht/~rjarry/aerc/commands"
"git.sr.ht/~rjarry/go-opt/v2"
)
var subCommands map[string]commands.Command
func register(cmd commands.Command) {
if subCommands == nil {
subCommands = make(map[string]commands.Command)
}
for _, alias := range cmd.Aliases() {
if subCommands[alias] != nil {
panic("duplicate sub command alias: " + alias)
}
subCommands[alias] = cmd
}
}
type Patch struct {
SubCmd commands.Command `opt:":cmd:" action:"ParseSub" complete:"CompleteSubNames"`
}
func init() {
commands.Register(Patch{})
}
func (Patch) Description() string {
return "Local patch management commands."
}
func (Patch) Context() commands.CommandContext {
return commands.GLOBAL
}
func (Patch) Aliases() []string {
return []string{"patch"}
}
func (p *Patch) ParseSub(arg string) error {
cmd, ok := subCommands[arg]
if ok {
context := commands.CurrentContext()
if cmd.Context()&context != 0 {
// copy zeroed struct
clone := reflect.New(reflect.TypeOf(cmd)).Interface()
p.SubCmd = clone.(commands.Command)
return nil
}
}
return fmt.Errorf("%s unknown sub-command", arg)
}
func (*Patch) CompleteSubNames(arg string) []string {
context := commands.CurrentContext()
options := make([]string, 0, len(subCommands))
for alias, cmd := range subCommands {
if cmd.Context()&context != 0 {
options = append(options, alias+"\n"+cmd.Description())
}
}
sort.Strings(options)
return commands.FilterList(options, arg, nil)
}
func (p *Patch) CompleteSubArgs(arg string) []string {
if p.SubCmd == nil {
return nil
}
// prepend arbitrary string to arg to work with sub-commands
options, _ := commands.GetCompletions(p.SubCmd, opt.LexArgs("a "+arg))
completions := make([]string, 0, len(options))
for _, o := range options {
completions = append(completions, o.Value)
}
return completions
}
func (p Patch) Execute(args []string) error {
if p.SubCmd == nil {
return errors.New("no subcommand found")
}
return p.SubCmd.Execute(args)
}