| //go:build !urfave_cli_no_suggest | |
| // +build !urfave_cli_no_suggest | |
| package cli | |
| import ( | |
| "fmt" | |
| "github.com/xrash/smetrics" | |
| ) | |
| func init() { | |
| SuggestFlag = suggestFlag | |
| SuggestCommand = suggestCommand | |
| } | |
| func jaroWinkler(a, b string) float64 { | |
| // magic values are from https://github.com/xrash/smetrics/blob/039620a656736e6ad994090895784a7af15e0b80/jaro-winkler.go#L8 | |
| const ( | |
| boostThreshold = 0.7 | |
| prefixSize = 4 | |
| ) | |
| return smetrics.JaroWinkler(a, b, boostThreshold, prefixSize) | |
| } | |
| func suggestFlag(flags []Flag, provided string, hideHelp bool) string { | |
| distance := 0.0 | |
| suggestion := "" | |
| for _, flag := range flags { | |
| flagNames := flag.Names() | |
| if !hideHelp && HelpFlag != nil { | |
| flagNames = append(flagNames, HelpFlag.Names()...) | |
| } | |
| for _, name := range flagNames { | |
| newDistance := jaroWinkler(name, provided) | |
| if newDistance > distance { | |
| distance = newDistance | |
| suggestion = name | |
| } | |
| } | |
| } | |
| if len(suggestion) == 1 { | |
| suggestion = "-" + suggestion | |
| } else if len(suggestion) > 1 { | |
| suggestion = "--" + suggestion | |
| } | |
| return suggestion | |
| } | |
| // suggestCommand takes a list of commands and a provided string to suggest a | |
| // command name | |
| func suggestCommand(commands []*Command, provided string) (suggestion string) { | |
| distance := 0.0 | |
| for _, command := range commands { | |
| for _, name := range append(command.Names(), helpName, helpAlias) { | |
| newDistance := jaroWinkler(name, provided) | |
| if newDistance > distance { | |
| distance = newDistance | |
| suggestion = name | |
| } | |
| } | |
| } | |
| return fmt.Sprintf(SuggestDidYouMeanTemplate, suggestion) | |
| } |