aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Jarry <robin@jarry.cc>2023-10-17 00:14:49 +0200
committerRobin Jarry <robin@jarry.cc>2023-10-28 19:25:08 +0200
commit30851656591293ed2e19340ab78c937855a11143 (patch)
treef7c0aad888110163ebb21a9498784aea9f26f949
parent08ef572e08665ec3a06ea6ac315f3dd6d0eac5d1 (diff)
downloadaerc-30851656591293ed2e19340ab78c937855a11143.tar.gz
aerc-30851656591293ed2e19340ab78c937855a11143.zip
commands: remove command set completion api
Do not expose the completion of a command via its command set. Instead, require a single command object to be resolved in order to execute it. Extract the command names and the template terms completions in main.go. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Koni Marti <koni.marti@gmail.com> Tested-by: Moritz Poldrack <moritz@poldrack.dev> Tested-by: Inwit <inwit@sindominio.net>
-rw-r--r--commands/commands.go62
-rw-r--r--commands/prompt.go2
-rw-r--r--main.go39
3 files changed, 42 insertions, 61 deletions
diff --git a/commands/commands.go b/commands/commands.go
index c2137a58..d76194af 100644
--- a/commands/commands.go
+++ b/commands/commands.go
@@ -4,7 +4,6 @@ import (
"bytes"
"errors"
"reflect"
- "sort"
"strings"
"unicode"
@@ -153,11 +152,6 @@ func ExpandTemplates(
func GetTemplateCompletion(
cmd string,
) ([]string, string, bool) {
- args, err := splitCmd(cmd)
- if err != nil || len(args) == 0 {
- return nil, "", false
- }
-
countLeft := strings.Count(cmd, "{{")
if countLeft == 0 {
return nil, "", false
@@ -197,48 +191,16 @@ func GetTemplateCompletion(
}
// GetCompletions returns the completion options and the command prefix
-func (cmds *Commands) GetCompletions(
- cmd string,
+func GetCompletions(
+ cmd Command, args *opt.Args,
) (options []string, prefix string) {
- log.Tracef("completing command: %s", cmd)
-
- // start completion
- args, err := splitCmd(cmd)
- if err != nil {
- return
- }
-
- // nothing entered, list all commands
- if len(args) == 0 {
- options = cmds.Names()
- sort.Strings(options)
- return
- }
-
- // complete command name
- spaceTerminated := cmd[len(cmd)-1] == ' '
- if len(args) == 1 && !spaceTerminated {
- for _, n := range cmds.Names() {
- options = append(options, n+" ")
- }
- options = CompletionFromList(options, args)
-
- return
- }
-
- // look for command in dictionary
- c, ok := cmds.dict()[args[0]]
- if !ok {
- return
- }
-
// complete options
var spec string
- if provider, ok := c.(OptionsProvider); ok {
+ if provider, ok := cmd.(OptionsProvider); ok {
spec = provider.Options()
}
- parser, err := newParser(cmd, spec, spaceTerminated)
+ parser, err := newParser(args.String(), spec, strings.HasSuffix(args.String(), " "))
if err != nil {
log.Debugf("completion parser failed: %v", err)
return
@@ -256,15 +218,15 @@ func (cmds *Commands) GetCompletions(
}
options = append(options, option)
}
- prefix = cmd
+ prefix = args.String()
case OPTION_ARGUMENT:
- cmpl, ok := c.(OptionCompleter)
+ cmpl, ok := cmd.(OptionCompleter)
if !ok {
return
}
- stem := cmd
+ stem := args.String()
if parser.arg != "" {
- stem = strings.TrimSuffix(cmd, parser.arg)
+ stem = strings.TrimSuffix(stem, parser.arg)
}
pad := ""
if !strings.HasSuffix(stem, " ") {
@@ -277,14 +239,16 @@ func (cmds *Commands) GetCompletions(
}
prefix = stem
case OPERAND:
- stem := strings.Join(args[:parser.optind], " ")
- for _, option := range c.Complete(args[1:]) {
+ clone := args.Clone()
+ clone.Cut(clone.Count() - parser.optind)
+ args.Shift(1)
+ for _, option := range cmd.Complete(args.Args()) {
if strings.Contains(option, " ") {
option = escape(option)
}
options = append(options, " "+option)
}
- prefix = stem
+ prefix = clone.String()
}
return
diff --git a/commands/prompt.go b/commands/prompt.go
index d42a6597..dd259c30 100644
--- a/commands/prompt.go
+++ b/commands/prompt.go
@@ -40,7 +40,7 @@ func (Prompt) Complete(args []string) []string {
if hascommand {
return nil
}
- cs, _ = GlobalCommands.GetCompletions(args[1])
+ cs = GlobalCommands.Names()
}
if cs == nil {
return nil
diff --git a/main.go b/main.go
index 43e980e9..dc7d0267 100644
--- a/main.go
+++ b/main.go
@@ -125,21 +125,38 @@ func execCommand(
return err
}
-func getCompletions(cmd string) ([]string, string) {
- if options, prefix, ok := commands.GetTemplateCompletion(cmd); ok {
+func getCompletions(cmdline string) ([]string, string) {
+ cmdline = strings.TrimLeft(cmdline, ":")
+
+ // complete template terms
+ if options, prefix, ok := commands.GetTemplateCompletion(cmdline); ok {
+ sort.Strings(options)
return options, prefix
}
- var completions []string
- var prefix string
- for _, set := range getCommands(app.SelectedTabContent()) {
- options, s := set.GetCompletions(cmd)
- if s != "" {
- prefix = s
+
+ args := opt.LexArgs(cmdline)
+ cmds := getCommands(app.SelectedTabContent())
+
+ if args.Count() < 2 && args.TrailingSpace() == "" {
+ // complete command names
+ var completions []string
+ for _, set := range cmds {
+ for _, n := range set.Names() {
+ if strings.HasPrefix(n, cmdline) {
+ completions = append(completions, n)
+ }
+ }
}
- completions = append(completions, options...)
+ sort.Strings(completions)
+ return completions, ""
+ }
+
+ // complete command arguments
+ _, cmd := expandAbbreviations(args.Arg(0), cmds)
+ if cmd == nil {
+ return nil, cmdline
}
- sort.Strings(completions)
- return completions, prefix
+ return commands.GetCompletions(cmd, args)
}
// set at build time