add suggestions template

This commit is contained in:
John Brunton 2020-06-25 12:12:02 +01:00
parent 04318720db
commit eb5c65715d
2 changed files with 46 additions and 4 deletions

View file

@ -201,6 +201,8 @@ type Command struct {
helpCommand *Command helpCommand *Command
// versionTemplate is the version template defined by user. // versionTemplate is the version template defined by user.
versionTemplate string versionTemplate string
// suggestionsTemplate is the suggestions template defined by user.
suggestionsTemplate string
// inReader is a reader defined by the user that replaces stdin // inReader is a reader defined by the user that replaces stdin
inReader io.Reader inReader io.Reader
@ -284,6 +286,11 @@ func (c *Command) SetVersionTemplate(s string) {
c.versionTemplate = s c.versionTemplate = s
} }
// SetSuggestionsTemplate sets suggestions template. Can be defined by Application.
func (c *Command) SetSuggestionsTemplate(s string) {
c.suggestionsTemplate = s
}
// SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands. // SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands.
// The user should not have a cyclic dependency on commands. // The user should not have a cyclic dependency on commands.
func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string) flag.NormalizedName) { func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string) flag.NormalizedName) {
@ -527,6 +534,22 @@ func (c *Command) VersionTemplate() string {
` `
} }
// SuggestionsTemplate return suggestions template for the command.
func (c *Command) SuggestionsTemplate() string {
if c.suggestionsTemplate != "" {
return c.suggestionsTemplate
}
if c.HasParent() {
return c.parent.SuggestionsTemplate()
}
return `
Did you mean this?
{{range .}}{{print "\t" .}}{{end}}
`
}
func hasNoOptDefVal(name string, fs *flag.FlagSet) bool { func hasNoOptDefVal(name string, fs *flag.FlagSet) bool {
flag := fs.Lookup(name) flag := fs.Lookup(name)
if flag == nil { if flag == nil {
@ -639,10 +662,10 @@ func (c *Command) findSuggestions(arg string) string {
} }
suggestionsString := "" suggestionsString := ""
if suggestions := c.SuggestionsFor(arg); len(suggestions) > 0 { if suggestions := c.SuggestionsFor(arg); len(suggestions) > 0 {
suggestionsString += "\n\nDid you mean this?\n" var suggestionsBuffer bytes.Buffer
for _, s := range suggestions { suggestions := c.SuggestionsFor(arg)
suggestionsString += fmt.Sprintf("\t%v\n", s) tmpl(&suggestionsBuffer, c.SuggestionsTemplate(), suggestions)
} suggestionsString += suggestionsBuffer.String()
} }
return suggestionsString return suggestionsString
} }

View file

@ -1202,6 +1202,25 @@ func TestSuggestions(t *testing.T) {
} }
} }
func TestSuggestionsTemplate(t *testing.T) {
rootCmd := &Command{Use: "root", Run: emptyRun}
timesCmd := &Command{
Use: "times",
SuggestFor: []string{"counts"},
Run: emptyRun,
}
rootCmd.AddCommand(timesCmd)
rootCmd.SetSuggestionsTemplate(`
customized suggestions: {{range .}}{{.}}{{end}}`)
output, _ := executeCommand(rootCmd, "time")
expected := "Error: unknown command \"time\" for \"root\"\ncustomized suggestions: times\nRun 'root --help' for usage.\n"
if output != expected {
t.Errorf("Unexpected response.\nExpected:\n %q\nGot:\n %q\n", expected, output)
}
}
func TestRemoveCommand(t *testing.T) { func TestRemoveCommand(t *testing.T) {
rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun} rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun}
childCmd := &Command{Use: "child", Run: emptyRun} childCmd := &Command{Use: "child", Run: emptyRun}