Suggestions for sub command names as well

This commit is contained in:
Kovid Goyal 2022-09-30 19:37:59 +05:30
parent 0dab006733
commit e536ef7844
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 30 additions and 7 deletions

View File

@ -301,6 +301,31 @@ func (self *Command) GetVisibleOptions() ([]string, map[string][]*Option) {
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 {
ans := make([]string, 0, 8)
q := strings.ToLower(name_with_hyphens)
@ -313,13 +338,7 @@ func (self *Command) SuggestionsForOption(name_with_hyphens string, max_distance
}
return nil
})
utils.StableSort(ans, 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
})
sort_levenshtein_matches(q, ans)
return ans
}

View File

@ -101,6 +101,10 @@ func (self *Command) parse_args(ctx *Context, args []string) error {
}
if !self.SubCommandIsOptional {
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)}
}
cn := make([]string, len(possible_cmds))