diff --git a/go.mod b/go.mod index a659b683f..4c2d959cc 100644 --- a/go.mod +++ b/go.mod @@ -15,5 +15,5 @@ require ( github.com/mattn/go-colorable v0.1.9 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/rivo/uniseg v0.2.0 // indirect - golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect + golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect ) diff --git a/go.sum b/go.sum index 765b9fc50..aa928e16b 100644 --- a/go.sum +++ b/go.sum @@ -21,8 +21,7 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/tools/cli/infrastructure.go b/tools/cli/infrastructure.go index 7396da990..a8834f5eb 100644 --- a/tools/cli/infrastructure.go +++ b/tools/cli/infrastructure.go @@ -88,16 +88,8 @@ var yellow_fmt = color.New(color.FgYellow).SprintFunc() var blue_fmt = color.New(color.FgBlue).SprintFunc() var green_fmt = color.New(color.FgGreen).SprintFunc() -func cmd_name(cmd *cobra.Command) string { - if cmd.Annotations != nil { - parts := strings.Split(cmd.Annotations["exe"], " ") - return parts[len(parts)-1] - } - return cmd.Name() -} - func print_created_by(root *cobra.Command) { - fmt.Println(italic_fmt(root.Annotations["exe"]), opt_fmt(root.Version), "created by", title_fmt("Kovid Goyal")) + fmt.Println(italic_fmt(root.Name()), opt_fmt(root.Version), "created by", title_fmt("Kovid Goyal")) } func print_line_with_indent(text string, indent string, screen_width int) { @@ -238,7 +230,17 @@ func show_usage(cmd *cobra.Command) error { if tty_size_err == nil && ws.Cols < 80 { screen_width = int(ws.Cols) } - fmt.Println(title_fmt("Usage")+":", exe_fmt(cmd.Annotations["exe"]), cmd.Use) + use := cmd.Use + idx := strings.Index(use, " ") + if idx > -1 { + use = use[idx + 1:] + } + var parent_names []string + cmd.VisitParents(func(p *cobra.Command) { + parent_names = append(parent_names, p.Name()) + }) + parent_names = append(parent_names, cmd.Name()) + fmt.Println(title_fmt("Usage")+":", exe_fmt(strings.Join(parent_names, " ")), use) fmt.Println() if len(cmd.Long) > 0 { print_with_indent(cmd.Long, "", screen_width) @@ -249,12 +251,12 @@ func show_usage(cmd *cobra.Command) error { fmt.Println() fmt.Println(title_fmt("Commands") + ":") for _, child := range cmd.Commands() { - fmt.Println(" ", opt_fmt(cmd_name(child))) + fmt.Println(" ", opt_fmt(child.Name())) print_with_indent(child.Short, " ", screen_width) } fmt.Println() print_with_indent("Get help for an individual command by running:", "", screen_width) - fmt.Println(" ", cmd.Annotations["exe"], italic_fmt("command"), "-h") + fmt.Println(" ", cmd.Name(), italic_fmt("command"), "-h") } if cmd.HasAvailableFlags() { options_title := cmd.Annotations["options_title"] @@ -272,7 +274,9 @@ func show_usage(cmd *cobra.Command) error { defval := "" switch flag.Value.Type() { default: - defval = fmt.Sprintf("[=%s]", italic_fmt(flag.DefValue)) + if (flag.DefValue != "") { + defval = fmt.Sprintf("[=%s]", italic_fmt(flag.DefValue)) + } case "bool": case "count": } @@ -285,7 +289,7 @@ func show_usage(cmd *cobra.Command) error { case "help": msg = "Print this help message" case "version": - msg = "Print the version of " + RootCmd.Annotations["exe"] + ": " + italic_fmt(RootCmd.Version) + msg = "Print the version of " + RootCmd.Name() + ": " + italic_fmt(RootCmd.Version) } print_with_indent(msg, " ", screen_width) if cmd.Annotations["choices-"+flag.Name] != "" { @@ -307,12 +311,20 @@ func show_usage(cmd *cobra.Command) error { return nil } -func CreateCommand(cmd *cobra.Command, exe string) *cobra.Command { +func CreateCommand(cmd *cobra.Command) *cobra.Command { cmd.Annotations = make(map[string]string) - cmd.Annotations["exe"] = exe + if cmd.Run == nil { + cmd.Run = SubCommandRequired + } return cmd } +func SubCommandRequired(cmd *cobra.Command, args []string) { + cmd.Usage() + fmt.Fprintln(os.Stderr, color.RedString("\nNo command specified for "+cmd.Name())) + os.Exit(1) +} + func Init(root *cobra.Command) { RootCmd = root root.Version = kitty.VersionString diff --git a/tools/cmd/at/main.go b/tools/cmd/at/main.go index 27bad9ffc..1a9242903 100644 --- a/tools/cmd/at/main.go +++ b/tools/cmd/at/main.go @@ -1,10 +1,7 @@ -package main +package at import ( - "fmt" - "os" - "github.com/fatih/color" "github.com/spf13/cobra" "kitty/tools/cli" @@ -12,18 +9,13 @@ import ( ) var encrypt_cmd = crypto.Encrypt_cmd -var exe_name = "kitty-at" -func main() { +func EntryPoint(tool_root *cobra.Command) *cobra.Command { var root = cli.CreateCommand(&cobra.Command{ - Use: "[global options] command [command options] [command args]", + Use: "@ [global options] command [command options] [command args]", Short: "Control kitty remotely", Long: "Control kitty by sending it commands. Set the allow_remote_control option in kitty.conf or use a password, for this to work.", - Run: func(cmd *cobra.Command, args []string) { - cmd.Usage() - fmt.Fprintln(os.Stderr, color.RedString("\nNo command specified for "+exe_name)) - }, - }, exe_name) + }) root.Annotations["options_title"] = "Global options" root.PersistentFlags().String("password", "", @@ -32,9 +24,5 @@ func main() { " accepted before or is pre-configured in :file:`kitty.conf`.") cli.PersistentChoices(root, "use-password", "If no password is available, kitty will usually just send the remote control command without a password. This option can be used to force it to always or never use the supplied password.", "if-available", "always", "never") - cli.Init(root) - if err := root.Execute(); err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } + return root } diff --git a/tools/cmd/main.go b/tools/cmd/main.go new file mode 100644 index 000000000..bc44c5b78 --- /dev/null +++ b/tools/cmd/main.go @@ -0,0 +1,25 @@ +package main + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" + + "kitty/tools/cli" + "kitty/tools/cmd/at" +) + +func main() { + var root = cli.CreateCommand(&cobra.Command{ + Use: "kitty-tool command [command options] [command args]", + Short: "Fast, statically compiled implementations for various kitty command-line tools", + }) + root.AddCommand(at.EntryPoint(root)) + + cli.Init(root) + if err := root.Execute(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +}