mirror of
https://github.com/spf13/cobra
synced 2024-11-24 22:57: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 */}}
|
{{/* should accept Command (that contains subcommands) as parameter */}}
|
||||||
{{define "argumentsC" -}}
|
{{define "argumentsC" -}}
|
||||||
function {{constructPath .}} {
|
function {{constructPath .}} {
|
||||||
local line
|
local -a commands
|
||||||
|
|
||||||
_arguments -C \
|
_arguments -C \{{- range extractFlags .}}
|
||||||
{{range extractFlags . -}}
|
{{if simpleFlag .}}{{template "simpleFlag" .}}{{else}}{{template "complexFlag" .}}{{end}} \{{- end}}
|
||||||
{{" "}}{{if simpleFlag .}}{{template "simpleFlag" .}}{{else}}{{template "complexFlag" .}}{{end}} \
|
"1: :->cmnds" \
|
||||||
{{end}} "1: :({{subCmdList .}})" \
|
|
||||||
"*::arg:->args"
|
"*::arg:->args"
|
||||||
|
|
||||||
case $line[1] in {{- range .Commands}}{{if not .Hidden}}
|
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 .}})
|
{{cmdName .}})
|
||||||
{{constructPath .}}
|
{{constructPath .}}
|
||||||
;;
|
;;{{end}}{{end}}
|
||||||
{{end}}{{end}} esac
|
esac
|
||||||
}
|
}
|
||||||
{{range .Commands}}
|
{{range .Commands}}{{if not .Hidden}}
|
||||||
{{template "selectCmdTemplate" .}}
|
{{template "selectCmdTemplate" .}}
|
||||||
{{- end}}
|
{{- end}}{{end}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
|
||||||
{{/* should accept Command without subcommands as parameter */}}
|
{{/* should accept Command without subcommands as parameter */}}
|
||||||
{{define "arguments" -}}
|
{{define "arguments" -}}
|
||||||
function {{constructPath .}} {
|
function {{constructPath .}} {
|
||||||
{{with extractFlags . -}}
|
{{" _arguments"}}{{range extractFlags .}} \
|
||||||
{{ " _arguments" -}}
|
|
||||||
{{range .}} \
|
|
||||||
{{if simpleFlag .}}{{template "simpleFlag" .}}{{else}}{{template "complexFlag" .}}{{end -}}
|
{{if simpleFlag .}}{{template "simpleFlag" .}}{{else}}{{template "complexFlag" .}}{{end -}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end -}}
|
|
||||||
}
|
}
|
||||||
{{- end}}
|
{{end}}
|
||||||
|
|
||||||
|
{{/* dispatcher for commands with or without subcommands */}}
|
||||||
{{define "selectCmdTemplate" -}}
|
{{define "selectCmdTemplate" -}}
|
||||||
{{if .Hidden}}{{/* ignore hidden*/}}{{else -}}
|
{{if .Hidden}}{{/* ignore hidden*/}}{{else -}}
|
||||||
{{if .Commands}}{{template "argumentsC" .}}{{else}}{{template "arguments" .}}{{end}}
|
{{if .Commands}}{{template "argumentsC" .}}{{else}}{{template "arguments" .}}{{end}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
|
||||||
|
{{/* template entry point */}}
|
||||||
{{define "Main" -}}
|
{{define "Main" -}}
|
||||||
#compdef _{{cmdName .}} {{cmdName .}}
|
#compdef _{{cmdName .}} {{cmdName .}}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ func TestGenZshCompletion(t *testing.T) {
|
||||||
return r
|
return r
|
||||||
}(),
|
}(),
|
||||||
expectedExpressions: []string{
|
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 \\\n.*"--debug\[description]"`,
|
||||||
`_arguments -C \\\n.*"--debug\[description]"`,
|
`_arguments -C \\\n.*"--debug\[description]"`,
|
||||||
`function _rootcmd_subcmd1 {`,
|
`function _rootcmd_subcmd1 {`,
|
||||||
|
@ -185,24 +185,17 @@ func TestGenZshCompletionHidden(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkConstructPath(b *testing.B) {
|
func BenchmarkMediumSizeConstruct(b *testing.B) {
|
||||||
c := &Command{
|
root := constructLargeCommandHeirarchy()
|
||||||
Use: "main",
|
// if err := root.GenZshCompletionFile("_mycmd"); err != nil {
|
||||||
Long: "main long description which is very long",
|
// b.Error(err)
|
||||||
Short: "main short description",
|
// }
|
||||||
}
|
|
||||||
d := &Command{
|
|
||||||
Use: "hello",
|
|
||||||
}
|
|
||||||
e := &Command{
|
|
||||||
Use: "world",
|
|
||||||
}
|
|
||||||
c.AddCommand(d)
|
|
||||||
d.AddCommand(e)
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
res := constructPath(e)
|
buf := new(bytes.Buffer)
|
||||||
if res != "_main_hello_world" {
|
err := root.GenZshCompletion(buf)
|
||||||
b.Errorf("expeced path to be '_main_hello_world', got %s", res)
|
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))
|
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