github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/commands/cli/cmd_suggestion.go (about) 1 package cli 2 3 import ( 4 "sort" 5 "strings" 6 7 levenshtein "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/texttheater/golang-levenshtein/levenshtein" 8 cmds "github.com/ipfs/go-ipfs/commands" 9 ) 10 11 // Make a custom slice that can be sorted by its levenshtein value 12 type suggestionSlice []*suggestion 13 14 type suggestion struct { 15 cmd string 16 levenshtein int 17 } 18 19 func (s suggestionSlice) Len() int { 20 return len(s) 21 } 22 23 func (s suggestionSlice) Swap(i, j int) { 24 s[i], s[j] = s[j], s[i] 25 } 26 27 func (s suggestionSlice) Less(i, j int) bool { 28 return s[i].levenshtein < s[j].levenshtein 29 } 30 31 func suggestUnknownCmd(args []string, root *cmds.Command) []string { 32 arg := args[0] 33 var suggestions []string 34 sortableSuggestions := make(suggestionSlice, 0) 35 var sFinal []string 36 const MIN_LEVENSHTEIN = 3 37 38 var options levenshtein.Options = levenshtein.Options{ 39 InsCost: 1, 40 DelCost: 3, 41 SubCost: 2, 42 Matches: func(sourceCharacter rune, targetCharacter rune) bool { 43 return sourceCharacter == targetCharacter 44 }, 45 } 46 47 // Start with a simple strings.Contains check 48 for name, _ := range root.Subcommands { 49 if strings.Contains(arg, name) { 50 suggestions = append(suggestions, name) 51 } 52 } 53 54 // If the string compare returns a match, return 55 if len(suggestions) > 0 { 56 return suggestions 57 } 58 59 for name, _ := range root.Subcommands { 60 lev := levenshtein.DistanceForStrings([]rune(arg), []rune(name), options) 61 if lev <= MIN_LEVENSHTEIN { 62 sortableSuggestions = append(sortableSuggestions, &suggestion{name, lev}) 63 } 64 } 65 sort.Sort(sortableSuggestions) 66 67 for _, j := range sortableSuggestions { 68 sFinal = append(sFinal, j.cmd) 69 } 70 return sFinal 71 }