From 6917e42c288a107ef7a293463b437861bd918df0 Mon Sep 17 00:00:00 2001 From: verse91 Date: Sat, 11 Apr 2026 20:34:05 +0700 Subject: [PATCH] feat (spec): improve command completion logic --- commands/core/spec.go | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/commands/core/spec.go b/commands/core/spec.go index 8ce1e5c..36158c0 100644 --- a/commands/core/spec.go +++ b/commands/core/spec.go @@ -78,6 +78,17 @@ func Lookup(input string) []Suggestion { for depth < len(tokens) { tok := tokens[depth] + if tok == "" { + break + } + + // skip options + if strings.HasPrefix(tok, "-") { + depth++ + continue + } + + // try to match subcommands found := false for _, sub := range currentSubs { if sub.Name == tok { @@ -88,10 +99,20 @@ func Lookup(input string) []Suggestion { break } } - if !found { - break + if found { + depth++ + continue } - depth++ + + // if no subcommand matches but we have a generator, + // and this is NOT the last token (meaning it's a finished argument), + // we consume it and move depth forward. + if currentGen != nil && depth < len(tokens)-1 { + depth++ + continue + } + + break } // build prefix from tokens consumed so far @@ -139,9 +160,22 @@ func Lookup(input string) []Suggestion { } } - // options + // 3. Options (Flags) if partial == "" || (len(partial) > 0 && partial[0] == '-') { + // Identify already used options to filter them out + usedOpts := make(map[string]bool) + for _, t := range tokens { + if strings.HasPrefix(t, "-") { + usedOpts[t] = true + } + } + for _, opt := range currentOpts { + // Skip if already used + if usedOpts[opt.Name] { + continue + } + if partial == "" || hasPrefix(opt.Name, partial) { results = append(results, Suggestion{ Cmd: prefix + " " + opt.Name,