Move kitty-tool __complete__ to use the new CLI framework
This commit is contained in:
parent
e7c14c78d0
commit
79cfc1e70a
@ -41,8 +41,8 @@ func (self *Command) FormatSubCommands(output io.Writer, formatter *markup.Conte
|
|||||||
if !g.HasVisibleSubCommands() {
|
if !g.HasVisibleSubCommands() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fmt.Fprintln(output)
|
|
||||||
if g.Title != "" {
|
if g.Title != "" {
|
||||||
|
fmt.Fprintln(output)
|
||||||
fmt.Fprintln(output, formatter.Title(g.Title))
|
fmt.Fprintln(output, formatter.Title(g.Title))
|
||||||
}
|
}
|
||||||
for _, c := range g.SubCommands {
|
for _, c := range g.SubCommands {
|
||||||
@ -57,6 +57,7 @@ func (self *Command) FormatSubCommands(output io.Writer, formatter *markup.Conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Option) FormatOption(output io.Writer, formatter *markup.Context, screen_width int) {
|
func (self *Option) FormatOption(output io.Writer, formatter *markup.Context, screen_width int) {
|
||||||
|
fmt.Fprint(output, " ")
|
||||||
for i, a := range self.Aliases {
|
for i, a := range self.Aliases {
|
||||||
fmt.Fprint(output, formatter.Opt(a.String()))
|
fmt.Fprint(output, formatter.Opt(a.String()))
|
||||||
if i != len(self.Aliases)-1 {
|
if i != len(self.Aliases)-1 {
|
||||||
@ -102,7 +103,11 @@ func (self *Command) ShowHelp() {
|
|||||||
fmt.Fprintln(&output, formatter.Title("Usage")+":", formatter.Exe(strings.TrimSpace(self.CommandStringForUsage())),
|
fmt.Fprintln(&output, formatter.Title("Usage")+":", formatter.Exe(strings.TrimSpace(self.CommandStringForUsage())),
|
||||||
strings.TrimSpace(formatter.Prettify(self.Usage)))
|
strings.TrimSpace(formatter.Prettify(self.Usage)))
|
||||||
fmt.Fprintln(&output)
|
fmt.Fprintln(&output)
|
||||||
format_with_indent(&output, formatter.Prettify(prepare_help_text_for_display(self.HelpText)), "", screen_width)
|
if self.HelpText != "" {
|
||||||
|
format_with_indent(&output, formatter.Prettify(prepare_help_text_for_display(self.HelpText)), "", screen_width)
|
||||||
|
} else if self.ShortDescription != "" {
|
||||||
|
format_with_indent(&output, formatter.Prettify(self.ShortDescription), "", screen_width)
|
||||||
|
}
|
||||||
|
|
||||||
if self.HasVisibleSubCommands() {
|
if self.HasVisibleSubCommands() {
|
||||||
fmt.Fprintln(&output)
|
fmt.Fprintln(&output)
|
||||||
@ -118,8 +123,8 @@ func (self *Command) ShowHelp() {
|
|||||||
fmt.Fprintln(&output)
|
fmt.Fprintln(&output)
|
||||||
fmt.Fprintln(&output, formatter.Title("Options")+":")
|
fmt.Fprintln(&output, formatter.Title("Options")+":")
|
||||||
for _, title := range group_titles {
|
for _, title := range group_titles {
|
||||||
fmt.Fprintln(&output)
|
|
||||||
if title != "" {
|
if title != "" {
|
||||||
|
fmt.Fprintln(&output)
|
||||||
fmt.Fprintln(&output, formatter.Title(title))
|
fmt.Fprintln(&output, formatter.Title(title))
|
||||||
}
|
}
|
||||||
for _, opt := range gmap[title] {
|
for _, opt := range gmap[title] {
|
||||||
|
|||||||
@ -107,7 +107,7 @@ func option_from_spec(spec OptionSpec) (*Option, error) {
|
|||||||
}
|
}
|
||||||
parts := strings.Split(spec.Name, " ")
|
parts := strings.Split(spec.Name, " ")
|
||||||
ans.Name = camel_case_dest(parts[0])
|
ans.Name = camel_case_dest(parts[0])
|
||||||
ans.Aliases = make([]Alias, 0, len(parts))
|
ans.Aliases = make([]Alias, len(parts))
|
||||||
for i, x := range parts {
|
for i, x := range parts {
|
||||||
ans.Aliases[i] = Alias{NameWithoutHyphens: strings.TrimLeft(x, "-"), IsShort: !strings.HasPrefix(x, "--")}
|
ans.Aliases[i] = Alias{NameWithoutHyphens: strings.TrimLeft(x, "-"), IsShort: !strings.HasPrefix(x, "--")}
|
||||||
}
|
}
|
||||||
@ -198,7 +198,7 @@ func prepare_help_text_for_display(raw string) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
prev_indent = current_indent
|
prev_indent = current_indent
|
||||||
if !strings.HasSuffix(help.String(), "\n") {
|
if help.Len() > 0 && !strings.HasSuffix(help.String(), "\n") {
|
||||||
help.WriteString(" ")
|
help.WriteString(" ")
|
||||||
}
|
}
|
||||||
help.WriteString(line)
|
help.WriteString(line)
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import (
|
|||||||
var _ = fmt.Print
|
var _ = fmt.Print
|
||||||
|
|
||||||
func (self *Command) parse_args(ctx *Context, args []string) error {
|
func (self *Command) parse_args(ctx *Context, args []string) error {
|
||||||
args_to_parse := make([]string, 0, len(args))
|
args_to_parse := make([]string, len(args))
|
||||||
copy(args_to_parse, args)
|
copy(args_to_parse, args)
|
||||||
ctx.SeenCommands = append(ctx.SeenCommands, self)
|
ctx.SeenCommands = append(ctx.SeenCommands, self)
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ func (self *Command) parse_args(ctx *Context, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for len(self.Args) > 0 {
|
for len(args_to_parse) > 0 {
|
||||||
arg := consume_arg()
|
arg := consume_arg()
|
||||||
|
|
||||||
if expecting_arg_for == nil {
|
if expecting_arg_for == nil {
|
||||||
@ -49,10 +49,10 @@ func (self *Command) parse_args(ctx *Context, args []string) error {
|
|||||||
options_allowed = false
|
options_allowed = false
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
opt_str := ""
|
opt_str := arg
|
||||||
opt_val := ""
|
opt_val := ""
|
||||||
has_val := false
|
has_val := false
|
||||||
if strings.HasPrefix(opt_str, "--") || len(opt_str) == 2 {
|
if strings.HasPrefix(opt_str, "--") {
|
||||||
parts := strings.SplitN(arg, "=", 2)
|
parts := strings.SplitN(arg, "=", 2)
|
||||||
if len(parts) > 1 {
|
if len(parts) > 1 {
|
||||||
has_val = true
|
has_val = true
|
||||||
|
|||||||
@ -5,6 +5,7 @@ package cli
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -206,16 +207,12 @@ func (self *CommandGroup) Clone(parent *Command) *CommandGroup {
|
|||||||
return &ans
|
return &ans
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *CommandGroup) AddSubCommand(parent *Command, name string) (*Command, error) {
|
func (self *CommandGroup) AddSubCommand(parent *Command, name string) *Command {
|
||||||
for _, c := range self.SubCommands {
|
|
||||||
if c.Name == name {
|
|
||||||
return nil, fmt.Errorf("A subcommand with the name %#v already exists in the parent command: %#v", name, parent.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ans := NewRootCommand()
|
ans := NewRootCommand()
|
||||||
ans.Parent = parent
|
ans.Parent = parent
|
||||||
|
ans.Name = name
|
||||||
self.SubCommands = append(self.SubCommands, ans)
|
self.SubCommands = append(self.SubCommands, ans)
|
||||||
return ans, nil
|
return ans
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *CommandGroup) FindSubCommand(name string) *Command {
|
func (self *CommandGroup) FindSubCommand(name string) *Command {
|
||||||
@ -246,6 +243,7 @@ func (self *OptionGroup) AddOption(parent *Command, spec OptionSpec) (*Option, e
|
|||||||
ans, err := option_from_spec(spec)
|
ans, err := option_from_spec(spec)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ans.Parent = parent
|
ans.Parent = parent
|
||||||
|
self.Options = append(self.Options, ans)
|
||||||
}
|
}
|
||||||
return ans, err
|
return ans, err
|
||||||
}
|
}
|
||||||
@ -254,6 +252,7 @@ func (self *OptionGroup) AddOptionFromString(parent *Command, items ...string) (
|
|||||||
ans, err := OptionFromString(items...)
|
ans, err := OptionFromString(items...)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ans.Parent = parent
|
ans.Parent = parent
|
||||||
|
self.Options = append(self.Options, ans)
|
||||||
}
|
}
|
||||||
return ans, err
|
return ans, err
|
||||||
}
|
}
|
||||||
@ -320,6 +319,7 @@ func (self *Command) AddClone(group string, src *Command) (*Command, error) {
|
|||||||
|
|
||||||
func NewRootCommand() *Command {
|
func NewRootCommand() *Command {
|
||||||
ans := Command{
|
ans := Command{
|
||||||
|
Name: filepath.Base(os.Args[0]),
|
||||||
SubCommandGroups: make([]*CommandGroup, 0, 8),
|
SubCommandGroups: make([]*CommandGroup, 0, 8),
|
||||||
OptionGroups: make([]*OptionGroup, 0, 8),
|
OptionGroups: make([]*OptionGroup, 0, 8),
|
||||||
Args: make([]string, 0, 8),
|
Args: make([]string, 0, 8),
|
||||||
@ -338,7 +338,7 @@ func (self *Command) AddSubCommandGroup(title string) *CommandGroup {
|
|||||||
return &ans
|
return &ans
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Command) AddSubCommand(group string, name string) (*Command, error) {
|
func (self *Command) AddSubCommand(group string, name string) *Command {
|
||||||
return self.AddSubCommandGroup(group).AddSubCommand(self, name)
|
return self.AddSubCommandGroup(group).AddSubCommand(self, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,6 +363,7 @@ func (self *Command) Validate() error {
|
|||||||
if seen_dests[o.Name] {
|
if seen_dests[o.Name] {
|
||||||
return &ParseError{Message: fmt.Sprintf("The option :yellow:`%s` occurs twice inside %s", o.Name, self.Name)}
|
return &ParseError{Message: fmt.Sprintf("The option :yellow:`%s` occurs twice inside %s", o.Name, self.Name)}
|
||||||
}
|
}
|
||||||
|
seen_dests[o.Name] = true
|
||||||
for _, a := range o.Aliases {
|
for _, a := range o.Aliases {
|
||||||
q := a.String()
|
q := a.String()
|
||||||
if seen_flags[q] {
|
if seen_flags[q] {
|
||||||
@ -372,25 +373,23 @@ func (self *Command) Validate() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.Parent != nil {
|
if !seen_dests["Help"] {
|
||||||
if !seen_dests["Help"] {
|
if seen_flags["-h"] || seen_flags["--help"] {
|
||||||
if seen_flags["-h"] || seen_flags["--help"] {
|
return &ParseError{Message: fmt.Sprintf("The --help or -h flags are assigned to an option other than Help in %s", self.Name)}
|
||||||
return &ParseError{Message: fmt.Sprintf("The --help or -h flags are assigned to an option other than Help in %s", self.Name)}
|
|
||||||
}
|
|
||||||
_, err := self.Add(OptionSpec{Name: "--help -h", Type: "bool-set", Help: "Show help for this command"})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
_, err := self.Add(OptionSpec{Name: "--help -h", Type: "bool-set", Help: "Show help for this command"})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if self.Parent.Parent == nil && !seen_dests["Version"] {
|
if self.Parent == nil && !seen_dests["Version"] {
|
||||||
if seen_flags["--version"] {
|
if seen_flags["--version"] {
|
||||||
return &ParseError{Message: fmt.Sprintf("The --version flag is assigned to an option other than Version in %s", self.Name)}
|
return &ParseError{Message: fmt.Sprintf("The --version flag is assigned to an option other than Version in %s", self.Name)}
|
||||||
}
|
}
|
||||||
_, err := self.Add(OptionSpec{Name: "--version", Type: "bool-set", Help: "Show version"})
|
_, err := self.Add(OptionSpec{Name: "--version", Type: "bool-set", Help: "Show version"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,27 +3,17 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
"kitty/tools/cli"
|
"kitty/tools/cli"
|
||||||
"kitty/tools/cmd/at"
|
_ "kitty/tools/cmd/at"
|
||||||
"kitty/tools/completion"
|
"kitty/tools/completion"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var root = cli.CreateCommand(&cobra.Command{
|
root := cli.NewRootCommand()
|
||||||
Use: "kitty-tool command [command options] [command args]",
|
root.ShortDescription = "Fast, statically compiled implementations for various kitty command-line tools"
|
||||||
Short: "Fast, statically compiled implementations for various kitty command-line tools",
|
root.Usage = "command [command options] [command args]"
|
||||||
})
|
// root.AddCommand(at.EntryPoint(root))
|
||||||
root.AddCommand(at.EntryPoint(root))
|
|
||||||
|
|
||||||
root.AddCommand(completion.EntryPoint(root))
|
completion.EntryPoint(root)
|
||||||
|
root.Exec()
|
||||||
cli.Init(root)
|
|
||||||
if err := cli.Execute(root); err != nil {
|
|
||||||
cli.PrintError(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,8 +8,6 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
"kitty/tools/cli"
|
"kitty/tools/cli"
|
||||||
"kitty/tools/tty"
|
"kitty/tools/tty"
|
||||||
"kitty/tools/utils"
|
"kitty/tools/utils"
|
||||||
@ -95,15 +93,13 @@ func main(args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func EntryPoint(tool_root *cobra.Command) *cobra.Command {
|
func EntryPoint(tool_root *cli.Command) {
|
||||||
complete_command := cli.CreateCommand(&cobra.Command{
|
c := tool_root.AddSubCommand("", "__complete__")
|
||||||
Use: "__complete__ output_type [shell state...]",
|
c.Usage = "output_type [shell state...]"
|
||||||
Short: "Generate completions for kitty commands",
|
c.Hidden = true
|
||||||
Long: "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.ShortDescription = "Generate completions for kitty commands"
|
||||||
Hidden: true,
|
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."
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
c.Run = func(cmd *cli.Command, args []string) (ret int, err error) {
|
||||||
return main(args)
|
return ret, main(args)
|
||||||
},
|
}
|
||||||
})
|
|
||||||
return complete_command
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user