Improve suggestions - prefix will match

This commit is contained in:
Fabiano Franz 2015-09-25 11:41:47 -03:00
parent 53d96508f5
commit 3afa4db2c6
2 changed files with 42 additions and 28 deletions

View File

@ -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)
}
}
}
}

View File

@ -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