Suggestions for sub command names as well
This commit is contained in:
parent
0dab006733
commit
e536ef7844
@ -301,6 +301,31 @@ func (self *Command) GetVisibleOptions() ([]string, map[string][]*Option) {
|
|||||||
return group_titles, gmap
|
return group_titles, gmap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sort_levenshtein_matches(q string, matches []string) {
|
||||||
|
utils.StableSort(matches, func(a, b string) bool {
|
||||||
|
la, lb := utils.LevenshteinDistance(a, q, true), utils.LevenshteinDistance(b, q, true)
|
||||||
|
if la != lb {
|
||||||
|
return la < lb
|
||||||
|
}
|
||||||
|
return a < b
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Command) SuggestionsForCommand(name string, max_distance int /* good default is 2 */) []string {
|
||||||
|
ans := make([]string, 0, 8)
|
||||||
|
q := strings.ToLower(name)
|
||||||
|
for _, g := range self.SubCommandGroups {
|
||||||
|
for _, sc := range g.SubCommands {
|
||||||
|
if utils.LevenshteinDistance(sc.Name, q, true) <= max_distance {
|
||||||
|
ans = append(ans, sc.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort_levenshtein_matches(q, ans)
|
||||||
|
return ans
|
||||||
|
}
|
||||||
|
|
||||||
func (self *Command) SuggestionsForOption(name_with_hyphens string, max_distance int /* good default is 2 */) []string {
|
func (self *Command) SuggestionsForOption(name_with_hyphens string, max_distance int /* good default is 2 */) []string {
|
||||||
ans := make([]string, 0, 8)
|
ans := make([]string, 0, 8)
|
||||||
q := strings.ToLower(name_with_hyphens)
|
q := strings.ToLower(name_with_hyphens)
|
||||||
@ -313,13 +338,7 @@ func (self *Command) SuggestionsForOption(name_with_hyphens string, max_distance
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
utils.StableSort(ans, func(a, b string) bool {
|
sort_levenshtein_matches(q, ans)
|
||||||
la, lb := utils.LevenshteinDistance(a, q, true), utils.LevenshteinDistance(b, q, true)
|
|
||||||
if la != lb {
|
|
||||||
return la < lb
|
|
||||||
}
|
|
||||||
return a < b
|
|
||||||
})
|
|
||||||
return ans
|
return ans
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -101,6 +101,10 @@ func (self *Command) parse_args(ctx *Context, args []string) error {
|
|||||||
}
|
}
|
||||||
if !self.SubCommandIsOptional {
|
if !self.SubCommandIsOptional {
|
||||||
if len(possible_cmds) == 0 {
|
if len(possible_cmds) == 0 {
|
||||||
|
possibles := self.SuggestionsForCommand(arg, 2)
|
||||||
|
if len(possibles) > 0 {
|
||||||
|
return &ParseError{Message: fmt.Sprintf("Unknown subcommand: :yellow:`%s`. Did you mean:\n\t%s", arg, strings.Join(possibles, "\n\t"))}
|
||||||
|
}
|
||||||
return &ParseError{Message: fmt.Sprintf(":yellow:`%s` is not a known subcommand for :emph:`%s`. Use --help to get a list of valid subcommands.", arg, self.Name)}
|
return &ParseError{Message: fmt.Sprintf(":yellow:`%s` is not a known subcommand for :emph:`%s`. Use --help to get a list of valid subcommands.", arg, self.Name)}
|
||||||
}
|
}
|
||||||
cn := make([]string, len(possible_cmds))
|
cn := make([]string, len(possible_cmds))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user