mirror of
https://github.com/spf13/cobra
synced 2024-11-24 14:47:12 +00:00
zsh-completion: added support for subcommand description.
Also make the template more elegant on the way...
This commit is contained in:
parent
f0508c8e76
commit
2662787697
2 changed files with 84 additions and 35 deletions
|
@ -37,43 +37,50 @@ var (
|
|||
{{/* should accept Command (that contains subcommands) as parameter */}}
|
||||
{{define "argumentsC" -}}
|
||||
function {{constructPath .}} {
|
||||
local line
|
||||
local -a commands
|
||||
|
||||
_arguments -C \
|
||||
{{range extractFlags . -}}
|
||||
{{" "}}{{if simpleFlag .}}{{template "simpleFlag" .}}{{else}}{{template "complexFlag" .}}{{end}} \
|
||||
{{end}} "1: :({{subCmdList .}})" \
|
||||
_arguments -C \{{- range extractFlags .}}
|
||||
{{if simpleFlag .}}{{template "simpleFlag" .}}{{else}}{{template "complexFlag" .}}{{end}} \{{- end}}
|
||||
"1: :->cmnds" \
|
||||
"*::arg:->args"
|
||||
|
||||
case $line[1] in {{- range .Commands}}{{if not .Hidden}}
|
||||
{{cmdName .}})
|
||||
{{constructPath .}}
|
||||
;;
|
||||
{{end}}{{end}} esac
|
||||
case $state in
|
||||
cmnds)
|
||||
commands=({{range .Commands}}{{if not .Hidden}}
|
||||
"{{cmdName .}}:{{.Short}}"{{end}}{{end}}
|
||||
)
|
||||
_describe "command" commands
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$words[1]" in {{- range .Commands}}{{if not .Hidden}}
|
||||
{{cmdName .}})
|
||||
{{constructPath .}}
|
||||
;;{{end}}{{end}}
|
||||
esac
|
||||
}
|
||||
{{range .Commands}}
|
||||
{{range .Commands}}{{if not .Hidden}}
|
||||
{{template "selectCmdTemplate" .}}
|
||||
{{- end}}
|
||||
{{- end}}{{end}}
|
||||
{{- end}}
|
||||
|
||||
{{/* should accept Command without subcommands as parameter */}}
|
||||
{{define "arguments" -}}
|
||||
function {{constructPath .}} {
|
||||
{{with extractFlags . -}}
|
||||
{{ " _arguments" -}}
|
||||
{{range .}} \
|
||||
{{" _arguments"}}{{range extractFlags .}} \
|
||||
{{if simpleFlag .}}{{template "simpleFlag" .}}{{else}}{{template "complexFlag" .}}{{end -}}
|
||||
{{end}}
|
||||
{{end -}}
|
||||
}
|
||||
{{- end}}
|
||||
{{end}}
|
||||
|
||||
{{/* dispatcher for commands with or without subcommands */}}
|
||||
{{define "selectCmdTemplate" -}}
|
||||
{{if .Hidden}}{{/* ignore hidden*/}}{{else -}}
|
||||
{{if .Commands}}{{template "argumentsC" .}}{{else}}{{template "arguments" .}}{{end}}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
|
||||
{{/* template entry point */}}
|
||||
{{define "Main" -}}
|
||||
#compdef _{{cmdName .}} {{cmdName .}}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ func TestGenZshCompletion(t *testing.T) {
|
|||
return r
|
||||
}(),
|
||||
expectedExpressions: []string{
|
||||
`\\\n\s+"1: :\(help subcmd1 subcmd2\)" \\\n`,
|
||||
`commands=\(\n\s+"help:.*\n\s+"subcmd1:.*\n\s+"subcmd2:.*\n\s+\)`,
|
||||
`_arguments \\\n.*"--debug\[description]"`,
|
||||
`_arguments -C \\\n.*"--debug\[description]"`,
|
||||
`function _rootcmd_subcmd1 {`,
|
||||
|
@ -185,24 +185,17 @@ func TestGenZshCompletionHidden(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkConstructPath(b *testing.B) {
|
||||
c := &Command{
|
||||
Use: "main",
|
||||
Long: "main long description which is very long",
|
||||
Short: "main short description",
|
||||
}
|
||||
d := &Command{
|
||||
Use: "hello",
|
||||
}
|
||||
e := &Command{
|
||||
Use: "world",
|
||||
}
|
||||
c.AddCommand(d)
|
||||
d.AddCommand(e)
|
||||
func BenchmarkMediumSizeConstruct(b *testing.B) {
|
||||
root := constructLargeCommandHeirarchy()
|
||||
// if err := root.GenZshCompletionFile("_mycmd"); err != nil {
|
||||
// b.Error(err)
|
||||
// }
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
res := constructPath(e)
|
||||
if res != "_main_hello_world" {
|
||||
b.Errorf("expeced path to be '_main_hello_world', got %s", res)
|
||||
buf := new(bytes.Buffer)
|
||||
err := root.GenZshCompletion(buf)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -232,3 +225,52 @@ func TestExtractFlags(t *testing.T) {
|
|||
t.Errorf("expected Command D to return 2 flags, got %d", len(resD))
|
||||
}
|
||||
}
|
||||
|
||||
func constructLargeCommandHeirarchy() *Command {
|
||||
var config, st1, st2 string
|
||||
var long, debug bool
|
||||
var in1, in2 int
|
||||
|
||||
r := genTestCommand("mycmd", false)
|
||||
r.PersistentFlags().StringVarP(&config, "config", "c", config, "config usage")
|
||||
if err := r.MarkPersistentFlagFilename("config", "*"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
s1 := genTestCommand("sub1", true)
|
||||
s1.Flags().BoolVar(&long, "long", long, "long descriptin")
|
||||
s2 := genTestCommand("sub2", true)
|
||||
s2.PersistentFlags().BoolVar(&debug, "debug", debug, "debug description")
|
||||
s3 := genTestCommand("sub3", true)
|
||||
s3.Hidden = true
|
||||
s1_1 := genTestCommand("sub1sub1", true)
|
||||
s1_1.Flags().StringVar(&st1, "st1", st1, "st1 description")
|
||||
s1_1.Flags().StringVar(&st2, "st2", st2, "st2 description")
|
||||
s1_2 := genTestCommand("sub1sub2", true)
|
||||
s1_3 := genTestCommand("sub1sub3", true)
|
||||
s1_3.Flags().IntVar(&in1, "int1", in1, "int1 descriptionn")
|
||||
s1_3.Flags().IntVar(&in2, "int2", in2, "int2 descriptionn")
|
||||
s2_1 := genTestCommand("sub2sub1", true)
|
||||
s2_2 := genTestCommand("sub2sub2", true)
|
||||
s2_3 := genTestCommand("sub2sub3", true)
|
||||
s2_4 := genTestCommand("sub2sub4", true)
|
||||
s2_5 := genTestCommand("sub2sub5", true)
|
||||
|
||||
s1.AddCommand(s1_1, s1_2, s1_3)
|
||||
s2.AddCommand(s2_1, s2_2, s2_3, s2_4, s2_5)
|
||||
r.AddCommand(s1, s2, s3)
|
||||
r.Execute()
|
||||
return r
|
||||
}
|
||||
|
||||
func genTestCommand(name string, withRun bool) *Command {
|
||||
r := &Command{
|
||||
Use: name,
|
||||
Short: name + " short description",
|
||||
Long: "Long description for " + name,
|
||||
}
|
||||
if withRun {
|
||||
r.Run = emptyRun
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue