Change Match to be a function

This commit is contained in:
Eyal Posener 2017-05-11 20:48:40 +03:00
parent 967bae76f3
commit 115e175c3d
7 changed files with 41 additions and 58 deletions

View File

@ -53,8 +53,8 @@ func (c *Command) predict(a Args) (options []string, only bool) {
// add global available complete Predict
for flag := range c.Flags {
if m := match.Prefix(flag); m.Match(a.Last) {
options = append(options, m.String())
if match.Prefix(flag, a.Last) {
options = append(options, flag)
}
}
@ -82,8 +82,8 @@ func (c *Command) searchSub(a Args) (sub string, all []string, only bool) {
// subCommands returns a list of matching sub commands
func (c *Command) subCommands(last string) (prediction []string) {
for sub := range c.Sub {
if m := match.Prefix(sub); m.Match(last) {
prediction = append(prediction, m.String())
if match.Prefix(sub, last) {
prediction = append(prediction, sub)
}
}
return

View File

@ -21,8 +21,8 @@ func predictTest(funcPrefix ...string) complete.Predictor {
return complete.PredictFunc(func(a complete.Args) (prediction []string) {
tests := testNames(funcPrefix)
for _, t := range tests {
if m := match.Prefix(t); m.Match(a.Last) {
prediction = append(prediction, m.String())
if match.Prefix(t, a.Last) {
prediction = append(prediction, t)
}
}
return

View File

@ -1,26 +1,16 @@
package match
import (
"strings"
)
import "strings"
// File is a file name Matcher, if the last word can prefix the
// File path, there is a possible match
type File string
func (a File) String() string {
return string(a)
}
// Match returns true if prefix's abs path prefixes a's abs path
func (a File) Match(prefix string) bool {
// File returns true if prefix can match the file
func File(file, prefix string) bool {
// special case for current directory completion
if a == "./" && (prefix == "." || prefix == "") {
if file == "./" && (prefix == "." || prefix == "") {
return true
}
cmp := strings.TrimPrefix(string(a), "./")
file = strings.TrimPrefix(file, "./")
prefix = strings.TrimPrefix(prefix, "./")
return strings.HasPrefix(cmp, prefix)
return strings.HasPrefix(file, prefix)
}

View File

@ -1,11 +1,6 @@
package match
import "fmt"
// Matcher matches itself to a string
// it is used for comparing a given argument to the last typed
// word, and see if it is a possible auto complete option.
type Matcher interface {
fmt.Stringer
Match(prefix string) bool
}
// Match matches two strings
// it is used for comparing a term to the last typed
// word, the prefix, and see if it is a possible auto complete option.
type Match func(term, prefix string) bool

View File

@ -1,6 +1,7 @@
package match
import (
"fmt"
"os"
"testing"
)
@ -21,11 +22,13 @@ func TestMatch(t *testing.T) {
}
tests := []struct {
m Matcher
m Match
long string
tests []matcherTest
}{
{
m: Prefix("abcd"),
m: Prefix,
long: "abcd",
tests: []matcherTest{
{prefix: "", want: true},
{prefix: "ab", want: true},
@ -33,14 +36,16 @@ func TestMatch(t *testing.T) {
},
},
{
m: Prefix(""),
m: Prefix,
long: "",
tests: []matcherTest{
{prefix: "ac", want: false},
{prefix: "", want: true},
},
},
{
m: File("file.txt"),
m: File,
long: "file.txt",
tests: []matcherTest{
{prefix: "", want: true},
{prefix: "f", want: true},
@ -59,7 +64,8 @@ func TestMatch(t *testing.T) {
},
},
{
m: File("./file.txt"),
m: File,
long: "./file.txt",
tests: []matcherTest{
{prefix: "", want: true},
{prefix: "f", want: true},
@ -78,7 +84,8 @@ func TestMatch(t *testing.T) {
},
},
{
m: File("/file.txt"),
m: File,
long: "/file.txt",
tests: []matcherTest{
{prefix: "", want: true},
{prefix: "f", want: false},
@ -97,7 +104,8 @@ func TestMatch(t *testing.T) {
},
},
{
m: File("./"),
m: File,
long: "./",
tests: []matcherTest{
{prefix: "", want: true},
{prefix: ".", want: true},
@ -109,9 +117,9 @@ func TestMatch(t *testing.T) {
for _, tt := range tests {
for _, ttt := range tt.tests {
name := "matcher='" + tt.m.String() + "'&prefix='" + ttt.prefix + "'"
name := fmt.Sprintf("matcher=%T&long='%s'&prefix='%s'", tt.m, tt.long, ttt.prefix)
t.Run(name, func(t *testing.T) {
got := tt.m.Match(ttt.prefix)
got := tt.m(tt.long, ttt.prefix)
if got != ttt.want {
t.Errorf("Failed %s: got = %t, want: %t", name, got, ttt.want)
}

View File

@ -3,13 +3,7 @@ package match
import "strings"
// Prefix is a simple Matcher, if the word is it's prefix, there is a match
type Prefix string
func (a Prefix) String() string {
return string(a)
}
// Match returns true if a has the prefix as prefix
func (a Prefix) Match(prefix string) bool {
return strings.HasPrefix(string(a), prefix)
func Prefix(long, prefix string) bool {
return strings.HasPrefix(long, prefix)
}

View File

@ -49,19 +49,15 @@ var PredictAnything = PredictFunc(func(Args) []string { return nil })
// PredictSet expects specific set of terms, given in the options argument.
func PredictSet(options ...string) Predictor {
p := predictSet{}
for _, o := range options {
p = append(p, match.Prefix(o))
}
return p
return predictSet(options)
}
type predictSet []match.Prefix
type predictSet []string
func (p predictSet) Predict(a Args) (prediction []string) {
for _, m := range p {
if m.Match(a.Last) {
prediction = append(prediction, m.String())
if match.Prefix(m, a.Last) {
prediction = append(prediction, m)
}
}
return
@ -104,8 +100,8 @@ func files(pattern string, allowDirs, allowFiles bool) PredictFunc {
}
// add all matching files to prediction
for _, f := range files {
if m := match.File(f); m.Match(a.Last) {
prediction = append(prediction, m.String())
if match.File(f, a.Last) {
prediction = append(prediction, f)
}
}
return