package cache import ( "strings" "github.com/lithammer/fuzzysearch/fuzzy" "golang.org/x/exp/slices" "gitea.libretechconsulting.com/rmcguire/git-project-manager/internal/remotes/projects" ) // Performs a fuzzy find on the input string, returning the closest // matched based on its Levenshtein distance, along with an integer // indicating number of matches found func (c *Cache) FuzzyFindAlias(name string) []*ProjectAlias { ranks := fuzzy.RankFindFold(name, c.AliasStrings("")) if ranks.Len() == 1 { c.log.Debug("Fuzzy found alias result", c.log.Args( "searchTerm", ranks[0].Source, "foundAlias", ranks[0].Target, "levenshteinDistance", ranks[0].Distance, )) } else if ranks.Len() > 1 { found := make([]string, ranks.Len()) for i, r := range ranks { found[i] = r.Target } c.log.Debug("Fuzzy found multiple aliases, try being more specific", c.log.Args("foundAliases", strings.Join(found, ", "))) } aliases := make([]*ProjectAlias, 0, ranks.Len()) if ranks.Len() > 0 { for _, r := range ranks { alias := c.GetAliasByName(r.Target) if alias != nil { aliases = append(aliases, alias) } } } return slices.Clip(aliases) } // Returns all matching projects by fuzzy find term // Matches NameWithNamespace and Aliases func (c *Cache) FuzzyFindProjects(search string) []*projects.Project { projects := make([]*projects.Project, 0, len(c.Projects)) for _, p := range c.Projects { if fuzzy.MatchFold(search, p.NameWithNamespace) { projects = append(projects, p) continue } for _, a := range c.GetProjectAliases(p) { if fuzzy.MatchFold(search, a.Alias) { projects = append(projects, p) continue } } } return projects }