package commandkit import ( "strings" internalcobra "gitea.maximumdirect.net/eric/CommandKit/internal/cobra" commandmeta "gitea.maximumdirect.net/eric/CommandKit/internal/commandmeta" "gitea.maximumdirect.net/eric/CommandKit/internal/commandpath" ) type completionContext struct { route routeResult command *commandmeta.Command aliases []commandmeta.FlagAlias completed []string tail []string current string commandPosition bool } func resolveCompletionContext(snapshot *routingSnapshot, completed []string, current string) completionContext { context := completionContext{completed: append([]string(nil), completed...), current: current} if snapshot == nil { return context } context.route = resolveEnteredRoute(completed, snapshot) switch context.route.kind { case routeCanonical: context.command = completionCommand(snapshot.metadata, context.route.canonicalPath) if context.command == nil || len(context.route.args) < len(context.route.canonicalPath) { context.command = nil return context } context.tail = append([]string(nil), context.route.args[len(context.route.canonicalPath):]...) context.aliases = snapshot.flagAliases[context.route.canonicalPath.Key()].neutralRecords() context.commandPosition = len(context.tail) == 0 case routeDiscovery: context.command = &commandmeta.Command{CoreFlags: commandmeta.ReportingFlags()} context.tail = append([]string(nil), context.route.args...) context.aliases = snapshot.discoveryFlags[context.route.discoveryPath.Key()].neutralRecords() } return context } func completionCommand(root *commandmeta.Command, path commandpath.Path) *commandmeta.Command { current := root for _, name := range path { if current == nil { return nil } var next *commandmeta.Command for _, child := range current.Children { if child.Name == name { next = child break } } current = next } return current } func completionChildren(snapshot *routingSnapshot, context completionContext) []commandmeta.CompletionChoice { if snapshot == nil || context.command == nil || !context.commandPosition { return nil } var choices []commandmeta.CompletionChoice for _, child := range context.command.Children { if !strings.HasPrefix(child.Name, context.current) || (len(context.route.canonicalPath) == 0 && child.Name == internalcobra.CompletionQueryToken) { continue } entered := append(append([]string(nil), context.completed...), child.Name) route := resolveEnteredRoute(entered, snapshot) intended := append(context.route.canonicalPath.Clone(), child.Name) if route.kind == routeCanonical && route.canonicalPath.Equal(intended) { choices = append(choices, commandmeta.CompletionChoice{Value: child.Name, Description: child.Summary}) } } return choices }