forked from mirror/cobra
Improve suggestions - prefix will match
This commit is contained in:
parent
53d96508f5
commit
3afa4db2c6
|
@ -816,22 +816,32 @@ func TestRootSuggestions(t *testing.T) {
|
|||
cmd.AddCommand(cmdTimes)
|
||||
|
||||
tests := map[string]string{
|
||||
"time": "times",
|
||||
"tiems": "times",
|
||||
"timeS": "times",
|
||||
"rimes": "times",
|
||||
"time": "times",
|
||||
"tiems": "times",
|
||||
"tims": "times",
|
||||
"timeS": "times",
|
||||
"rimes": "times",
|
||||
"ti": "times",
|
||||
"t": "times",
|
||||
"timely": "times",
|
||||
"ri": "",
|
||||
"timezone": "",
|
||||
"foo": "",
|
||||
}
|
||||
|
||||
for typo, suggestion := range tests {
|
||||
cmd.DisableSuggestions = false
|
||||
result := simpleTester(cmd, typo)
|
||||
if expected := fmt.Sprintf(outputWithSuggestions, typo, suggestion); result.Output != expected {
|
||||
t.Errorf("Unexpected response.\nExpecting to be:\n %q\nGot:\n %q\n", expected, result.Output)
|
||||
}
|
||||
cmd.DisableSuggestions = true
|
||||
result = simpleTester(cmd, typo)
|
||||
if expected := fmt.Sprintf(outputWithoutSuggestions, typo); result.Output != expected {
|
||||
t.Errorf("Unexpected response.\nExpecting to be:\n %q\nGot:\n %q\n", expected, result.Output)
|
||||
for _, suggestionsDisabled := range []bool{false, true} {
|
||||
cmd.DisableSuggestions = suggestionsDisabled
|
||||
result := simpleTester(cmd, typo)
|
||||
expected := ""
|
||||
if len(suggestion) == 0 || suggestionsDisabled {
|
||||
expected = fmt.Sprintf(outputWithoutSuggestions, typo)
|
||||
} else {
|
||||
expected = fmt.Sprintf(outputWithSuggestions, typo, suggestion)
|
||||
}
|
||||
if result.Output != expected {
|
||||
t.Errorf("Unexpected response.\nExpecting to be:\n %q\nGot:\n %q\n", expected, result.Output)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
34
command.go
34
command.go
|
@ -429,33 +429,37 @@ func (c *Command) Find(args []string) (*Command, []string, error) {
|
|||
|
||||
// root command with subcommands, do subcommand checking
|
||||
if commandFound == c && len(argsWOflags) > 0 {
|
||||
suggestions := ""
|
||||
suggestionsString := ""
|
||||
if !c.DisableSuggestions {
|
||||
if c.SuggestionsMinimumDistance <= 0 {
|
||||
c.SuggestionsMinimumDistance = 2
|
||||
}
|
||||
similar := []string{}
|
||||
for _, cmd := range c.commands {
|
||||
if cmd.IsAvailableCommand() {
|
||||
levenshtein := ld(argsWOflags[0], cmd.Name(), true)
|
||||
if levenshtein <= c.SuggestionsMinimumDistance {
|
||||
similar = append(similar, cmd.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(similar) > 0 {
|
||||
suggestions += "\n\nDid you mean this?\n"
|
||||
for _, s := range similar {
|
||||
suggestions += fmt.Sprintf("\t%v\n", s)
|
||||
if suggestions := c.SuggestionsFor(argsWOflags[0]); len(suggestions) > 0 {
|
||||
suggestionsString += "\n\nDid you mean this?\n"
|
||||
for _, s := range suggestions {
|
||||
suggestionsString += fmt.Sprintf("\t%v\n", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
return commandFound, a, fmt.Errorf("unknown command %q for %q%s", argsWOflags[0], commandFound.CommandPath(), suggestions)
|
||||
return commandFound, a, fmt.Errorf("unknown command %q for %q%s", argsWOflags[0], commandFound.CommandPath(), suggestionsString)
|
||||
}
|
||||
|
||||
return commandFound, a, nil
|
||||
}
|
||||
|
||||
func (c *Command) SuggestionsFor(cmdName string) []string {
|
||||
suggestions := []string{}
|
||||
for _, cmd := range c.commands {
|
||||
if cmd.IsAvailableCommand() {
|
||||
levenshtein := ld(cmdName, cmd.Name(), true)
|
||||
if levenshtein <= c.SuggestionsMinimumDistance || strings.HasPrefix(strings.ToLower(cmd.Name()), strings.ToLower(cmdName)) {
|
||||
suggestions = append(suggestions, cmd.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
return suggestions
|
||||
}
|
||||
|
||||
func (c *Command) Root() *Command {
|
||||
var findRoot func(*Command) *Command
|
||||
|
||||
|
|
Loading…
Reference in New Issue