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