From 9e0b642a91bda5c09f85e06c33d779a2897289d5 Mon Sep 17 00:00:00 2001 From: chriswalz Date: Mon, 1 Mar 2021 21:04:36 -0500 Subject: [PATCH] feature: add fuzzy search/querying for branch suggestions. closes #103 --- README.md | 1 + cmd/bit_cmd.go | 29 ++++++++++++++++++++++++++--- cmd/cmd_test.go | 3 ++- go.mod | 5 ++++- go.sum | 6 ++++-- 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index ff39b06..2bd3024 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,7 @@ Thanks to [Gitless](https://gitless.com/), [git-extras](https://github.com/tj/gi ## Changelog v1.0 - [X] enhancement: significantly more autocompletions +- [X] enhancement: use fuzzy search for branch suggestions - [X] refactor: completions now represented in tree data structure - [X] fix: bit save no longer shows debug error outside debug mode - [X] fix: use --is-inside-work-tree to determine whether inside a git repo diff --git a/cmd/bit_cmd.go b/cmd/bit_cmd.go index 5dd7ebf..c0bf8ac 100644 --- a/cmd/bit_cmd.go +++ b/cmd/bit_cmd.go @@ -3,6 +3,8 @@ package cmd import ( "fmt" "github.com/chriswalz/complete/v3" + "github.com/google/shlex" + "github.com/lithammer/fuzzysearch/fuzzy" "os" "sort" "strings" @@ -79,20 +81,41 @@ func specificCommandCompleter(subCmd string, suggestionMap *complete.CompTree) f } } +var fuzzyQuery = func(s, prefix string) bool { + return fuzzy.Match(prefix, s) +} + func promptCompleter(suggestionTree *complete.CompTree, text string) []prompt.Suggest { text = "bit " + text var sugg []prompt.Suggest - suggestions, err := complete.CompleteLine(text, suggestionTree) + queryFunc := strings.HasPrefix + + split, err := shlex.Split(strings.TrimSpace(text)) if err != nil { log.Debug().Err(err).Send() return sugg } - split := strings.Split(strings.TrimSpace(text), " ") lastToken := split[len(split)-1] + lastCommand := lastToken + if !strings.HasSuffix(text, " ") && len(split) >= 2 { + lastCommand = split[len(split)-2] + } + + // use fuzzy search completion when querying branch names + if isBranchCompletionCommand(lastCommand) { + queryFunc = fuzzyQuery + } + + suggestions, err := complete.CompleteLine(text, suggestionTree, queryFunc) + if err != nil { + log.Debug().Err(err).Send() + return sugg + } + // for branches dont undo most recent sorts with alphabetical sort - if !isBranchCompletionCommand(lastToken) { + if !isBranchCompletionCommand(lastCommand) { sort.Slice(suggestions, func(i, j int) bool { return suggestions[i].Name < suggestions[j].Name }) diff --git a/cmd/cmd_test.go b/cmd/cmd_test.go index a5d551b..0374b83 100644 --- a/cmd/cmd_test.go +++ b/cmd/cmd_test.go @@ -3,6 +3,7 @@ package cmd import ( "fmt" "github.com/chriswalz/complete/v3" + "strings" "testing" "github.com/c-bata/go-prompt" @@ -204,7 +205,7 @@ func TestCompletion(t *testing.T) { }, } for _, e := range expects { - reality, err := complete.CompleteLine(e.line, suggestionsTree) + reality, err := complete.CompleteLine(e.line, suggestionsTree, strings.HasPrefix) assert.Equal(t, err, nil) for _, p := range e.predictions { diff --git a/go.mod b/go.mod index 9f4728f..7d64551 100644 --- a/go.mod +++ b/go.mod @@ -8,14 +8,16 @@ require ( github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect github.com/c-bata/go-prompt v0.2.5 github.com/c4milo/unpackit v0.0.0-20170704181138-4ed373e9ef1c // indirect - github.com/chriswalz/complete/v3 v3.0.12 + github.com/chriswalz/complete/v3 v3.0.13 github.com/dsnet/compress v0.0.1 // indirect github.com/google/go-github v17.0.0+incompatible // indirect github.com/google/go-github/v32 v32.1.0 + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gosuri/uilive v0.0.4 // indirect github.com/gosuri/uiprogress v0.0.1 // indirect github.com/hooklift/assert v0.1.0 // indirect github.com/klauspost/pgzip v1.2.5 // indirect + github.com/lithammer/fuzzysearch v1.1.1 // indirect github.com/pkg/errors v0.8.1 github.com/rs/zerolog v1.20.0 github.com/spf13/cobra v1.1.1 @@ -23,4 +25,5 @@ require ( github.com/thoas/go-funk v0.7.0 github.com/tj/go-update v2.2.4+incompatible github.com/ulikunitz/xz v0.5.8 // indirect + ) diff --git a/go.sum b/go.sum index 6561a9d..05eee86 100644 --- a/go.sum +++ b/go.sum @@ -44,8 +44,8 @@ github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7F github.com/c4milo/unpackit v0.0.0-20170704181138-4ed373e9ef1c h1:aprLqMn7gSPT+vdDSl+/E6NLEuArwD/J7IWd8bJt5lQ= github.com/c4milo/unpackit v0.0.0-20170704181138-4ed373e9ef1c/go.mod h1:Ie6SubJv/NTO9Q0UBH0QCl3Ve50lu9hjbi5YJUw03TE= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/chriswalz/complete/v3 v3.0.12 h1:HW54dvYu7u63NR/eMtCZ9GEq9xTG8gChhEIA/QmD+bU= -github.com/chriswalz/complete/v3 v3.0.12/go.mod h1:U4RZv3y+X3pV/uhqcJhlqlnug7IfJNiVVmIZ7+bsf20= +github.com/chriswalz/complete/v3 v3.0.13 h1:34B9sIn+gSnjb7Q0cCqoqa1WUYRdwOyAZUkcjlYLjEY= +github.com/chriswalz/complete/v3 v3.0.13/go.mod h1:U4RZv3y+X3pV/uhqcJhlqlnug7IfJNiVVmIZ7+bsf20= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -166,6 +166,8 @@ github.com/kr/pty v1.1.4 h1:5Myjjh3JY/NaAi4IsUbHADytDyl1VE1Y9PXDlL+P/VQ= github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lithammer/fuzzysearch v1.1.1 h1:8F9OAV2xPuYblToVohjanztdnPjbtA0MLgMvDKQ0Z08= +github.com/lithammer/fuzzysearch v1.1.1/go.mod h1:H2bng+w5gsR7NlfIJM8ElGZI0sX6C/9uzGqicVXGU6c= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=