예제 #1
0
func suggestUnknownCmd(args []string, root *cmds.Command) []string {
	if root == nil {
		return nil
	}

	arg := args[0]
	var suggestions []string
	sortableSuggestions := make(suggestionSlice, 0)
	var sFinal []string
	const MIN_LEVENSHTEIN = 3

	var options levenshtein.Options = levenshtein.Options{
		InsCost: 1,
		DelCost: 3,
		SubCost: 2,
		Matches: func(sourceCharacter rune, targetCharacter rune) bool {
			return sourceCharacter == targetCharacter
		},
	}

	// Start with a simple strings.Contains check
	for name, _ := range root.Subcommands {
		if strings.Contains(arg, name) {
			suggestions = append(suggestions, name)
		}
	}

	// If the string compare returns a match, return
	if len(suggestions) > 0 {
		return suggestions
	}

	for name, _ := range root.Subcommands {
		lev := levenshtein.DistanceForStrings([]rune(arg), []rune(name), options)
		if lev <= MIN_LEVENSHTEIN {
			sortableSuggestions = append(sortableSuggestions, &suggestion{name, lev})
		}
	}
	sort.Sort(sortableSuggestions)

	for _, j := range sortableSuggestions {
		sFinal = append(sFinal, j.cmd)
	}
	return sFinal
}
예제 #2
0
func TestLevenshtein(t *testing.T) {
	for _, testCase := range testCases {
		distance := levenshtein.DistanceForStrings(
			[]rune(testCase.source),
			[]rune(testCase.target),
			levenshtein.DefaultOptions)
		if distance != testCase.distance {
			t.Log(
				"Distance between",
				testCase.source,
				"and",
				testCase.target,
				"computed as",
				distance,
				", should be",
				testCase.distance)
			t.Fail()
		}
	}
}