package complete type Commands map[string]Command type Flags map[string]*Predicate type Command struct { Name string Sub Commands Flags Flags Args *Predicate } // options returns all available complete options for the given command // args are all except the last command line arguments relevant to the command func (c *Command) options(args []string) (options []Option, only bool) { // remove the first argument, which is the command name args = args[1:] last := last(args) // if prev has something that needs to follow it, // it is the most relevant completion if predicate, ok := c.Flags[last]; ok && predicate != nil { return predicate.predict(last), true } sub, options, only := c.searchSub(args) if only { return } // if no subcommand was entered in any of the args, add the // subcommands as complete options. if sub == "" { options = append(options, c.subCommands()...) } // add global available complete options for flag := range c.Flags { options = append(options, Arg(flag)) } // add additional expected argument of the command options = append(options, c.Args.predict(last)...) return } func (c *Command) searchSub(args []string) (sub string, all []Option, only bool) { for i, arg := range args { if cmd, ok := c.Sub[arg]; ok { sub = arg all, only = cmd.options(args[i:]) return } } return "", nil, false } func (c *Command) subCommands() []Option { subs := make([]Option, 0, len(c.Sub)) for sub := range c.Sub { subs = append(subs, Arg(sub)) } return subs }