Make adding subcommands a bit nicer

This commit is contained in:
Kovid Goyal 2022-09-25 12:39:42 +05:30
parent 4396dede85
commit 5771bd0c01
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 42 additions and 27 deletions

View File

@ -279,7 +279,7 @@ func (self *OptionGroup) FindOption(name_with_hyphens string) *Option {
// }}}
type Command struct { // {{{
Name string
Name, Group string
Usage, ShortDescription, HelpText string
Hidden bool
@ -287,13 +287,14 @@ type Command struct { // {{{
AllowOptionsAfterArgs int
// If true does not fail if the first non-option arg is not a sub-command
SubCommandIsOptional bool
// The entry point for this command
Run func(cmd *Command, args []string) (int, error)
SubCommandGroups []*CommandGroup
OptionGroups []*OptionGroup
Parent *Command
Args []string
Run func(cmd *Command, args []string) (int, error)
option_map map[string]*Option
}
@ -317,17 +318,22 @@ func (self *Command) Clone(parent *Command) *Command {
func (self *Command) AddClone(group string, src *Command) *Command {
c := src.Clone(self)
g := self.AddSubCommandGroup(group)
c.Group = g.Title
g.SubCommands = append(g.SubCommands, c)
return c
}
func init_cmd(c *Command) {
c.SubCommandGroups = make([]*CommandGroup, 0, 8)
c.OptionGroups = make([]*OptionGroup, 0, 8)
c.Args = make([]string, 0, 8)
}
func NewRootCommand() *Command {
ans := Command{
Name: filepath.Base(os.Args[0]),
SubCommandGroups: make([]*CommandGroup, 0, 8),
OptionGroups: make([]*OptionGroup, 0, 8),
Args: make([]string, 0, 8),
Name: filepath.Base(os.Args[0]),
}
init_cmd(&ans)
return &ans
}
@ -342,8 +348,12 @@ func (self *Command) AddSubCommandGroup(title string) *CommandGroup {
return &ans
}
func (self *Command) AddSubCommand(group string, name string) *Command {
return self.AddSubCommandGroup(group).AddSubCommand(self, name)
func (self *Command) AddSubCommand(ans *Command) *Command {
g := self.AddSubCommandGroup(ans.Group)
g.SubCommands = append(g.SubCommands, ans)
init_cmd(ans)
ans.Parent = self
return ans
}
func (self *Command) Validate() error {

View File

@ -68,7 +68,7 @@ func TestCLIParsing(t *testing.T) {
root := NewRootCommand()
root.Add(OptionSpec{Name: "--from-parent -p", Type: "count", Depth: 1})
child1 := root.AddSubCommand("", "child1")
child1 := root.AddSubCommand(&Command{Name: "child1"})
child1.Add(OptionSpec{Name: "--choices", Choices: "a b c"})
child1.Add(OptionSpec{Name: "--simple-string -s"})
child1.Add(OptionSpec{Name: "--set-me", Type: "bool-set"})
@ -76,7 +76,7 @@ func TestCLIParsing(t *testing.T) {
child1.Add(OptionSpec{Name: "--float", Type: "float"})
child1.Add(OptionSpec{Name: "--list", Type: "list"})
child1.SubCommandIsOptional = true
gc1 := child1.AddSubCommand("", "gc1")
gc1 := child1.AddSubCommand(&Command{Name: "gc1"})
rt(
child1, "test --from-parent child1 -ps ss --choices b --from-parent one two",

View File

@ -311,10 +311,12 @@ func setup_global_options(cmd *cli.Command) (err error) {
}
func EntryPoint(tool_root *cli.Command) *cli.Command {
at_root_command := tool_root.AddSubCommand("", "@")
at_root_command.Usage = "[global options] [sub-command] [sub-command options] [sub-command args]"
at_root_command.ShortDescription = "Control kitty remotely"
at_root_command.HelpText = "Control kitty by sending it commands. Set the allow_remote_control option in :file:`kitty.conf` for this to work. When run without any sub-commands this will start an interactive shell to control kitty."
at_root_command := tool_root.AddSubCommand(&cli.Command{
Name: "@",
Usage: "[global options] [sub-command] [sub-command options] [sub-command args]",
ShortDescription: "Control kitty remotely",
HelpText: "Control kitty by sending it commands. Set the allow_remote_control option in :file:`kitty.conf` for this to work. When run without any sub-commands this will start an interactive shell to control kitty.",
})
add_rc_global_opts(at_root_command)
global_options_group := at_root_command.OptionGroups[0]

View File

@ -94,11 +94,13 @@ func run_CMD_NAME(cmd *cli.Command, args []string) (return_code int, err error)
}
func setup_CMD_NAME(parent *cli.Command) *cli.Command {
ans := parent.AddSubCommand("", "CMD_NAME")
ans.Usage = "ARGSPEC"
ans.ShortDescription = "SHORT_DESC"
ans.HelpText = "LONG_DESC"
ans.Run = run_CMD_NAME
ans := parent.AddSubCommand(&cli.Command{
Name: "CMD_NAME",
Usage: "ARGSPEC",
ShortDescription: "SHORT_DESC",
HelpText: "LONG_DESC",
Run: run_CMD_NAME,
})
ADD_FLAGS_CODE
return ans
}

View File

@ -94,12 +94,13 @@ func main(args []string) error {
}
func EntryPoint(tool_root *cli.Command) {
c := tool_root.AddSubCommand("", "__complete__")
c.Usage = "output_type [shell state...]"
c.Hidden = true
c.ShortDescription = "Generate completions for kitty commands"
c.HelpText = "Generate completion candidates for kitty commands. The command line is read from STDIN. output_type can be one of the supported shells or 'json' for JSON output."
c.Run = func(cmd *cli.Command, args []string) (ret int, err error) {
return ret, main(args)
}
tool_root.AddSubCommand(&cli.Command{
Name: "__complete__", Hidden: true,
Usage: "output_type [shell state...]",
ShortDescription: "Generate completions for kitty commands",
HelpText: "Generate completion candidates for kitty commands. The command line is read from STDIN. output_type can be one of the supported shells or 'json' for JSON output.",
Run: func(cmd *cli.Command, args []string) (ret int, err error) {
return ret, main(args)
},
})
}