// SuggestCommands can be used to match a given word // which is very similar to one among the list of available commands. func SuggestCommands(given string, available []string) []string { commandSet := make(map[string]struct{}) for _, command := range available { commandSet[command] = struct{}{} } if len(commandSet) == 0 || given == "" { return nil } if _, ok := commandSet[given]; ok { return nil } var scores cmdScores for command := range commandSet { levenshtein := smetrics.WagnerFischer(command, given, 1, 1, 1) jaroWinkler := smetrics.JaroWinkler(command, given, 0.7, 4) if levenshtein > levenThreshold { continue } if jaroWinkler < jaroThreshold { continue } scores = append( scores, cmdScore{ name: command, levenshtein: levenshtein, jaroWinkler: jaroWinkler, }, ) } if len(scores) == 0 { return nil } sort.Sort(scores) levenshtein := scores[0].levenshtein var matches []string for _, score := range scores { if score.levenshtein != levenshtein { break } matches = append(matches, score.name) } return matches }
//TODO this needs to be improved a lot! func distance(a, b string) float32 { return float32(smetrics.WagnerFischer(a, b, 1, 1, 2)) / float32(len(a)+len(b)) }