Change Predicate to be of function type

This commit is contained in:
Eyal Posener 2017-05-06 20:07:50 +03:00
parent dc4c327ae8
commit f46c5f8a28
4 changed files with 35 additions and 46 deletions

View File

@ -2,13 +2,13 @@ package complete
type Commands map[string]Command
type Flags map[string]*Predicate
type Flags map[string]Predicate
type Command struct {
Name string
Sub Commands
Flags Flags
Args *Predicate
Args Predicate
}
// options returns all available complete options for the given command

View File

@ -11,16 +11,14 @@ import (
"github.com/posener/complete"
)
func predictTest(testType string) *complete.Predicate {
return &complete.Predicate{
Predictor: func(last string) []complete.Option {
tests := testNames(testType)
options := make([]complete.Option, len(tests))
for i := range tests {
options[i] = complete.Arg(tests[i])
}
return options
},
func predictTest(testType string) complete.Predicate {
return func(last string) []complete.Option {
tests := testNames(testType)
options := make([]complete.Option, len(tests))
for i := range tests {
options[i] = complete.Arg(tests[i])
}
return options
}
}

View File

@ -6,53 +6,41 @@ import (
)
// Predicate determines what terms can follow a command or a flag
type Predicate struct {
// Predictor is function that returns list of arguments that can
// come after the flag/command
Predictor func(last string) []Option
}
type Predicate func(last string) []Option
// Or unions two predicate struct, so that the result predicate
// returns the union of their predication
func (p *Predicate) Or(other *Predicate) *Predicate {
func (p Predicate) Or(other Predicate) Predicate {
if p == nil || other == nil {
return nil
}
return &Predicate{
Predictor: func(last string) []Option { return append(p.predict(last), other.predict(last)...) },
}
return func(last string) []Option { return append(p.predict(last), other.predict(last)...) }
}
func (p *Predicate) predict(last string) []Option {
if p == nil || p.Predictor == nil {
func (p Predicate) predict(last string) []Option {
if p == nil {
return nil
}
return p.Predictor(last)
return p(last)
}
var (
PredictNothing *Predicate = nil
PredictAnything = &Predicate{}
PredictDirs = &Predicate{Predictor: dirs}
PredictNothing Predicate = nil
)
func PredictSet(options ...string) *Predicate {
return &Predicate{
Predictor: func(last string) []Option {
ret := make([]Option, len(options))
for i := range options {
ret[i] = Arg(options[i])
}
return ret
},
func PredictAnything(last string) []Option { return nil }
func PredictSet(options ...string) Predicate {
return func(last string) []Option {
ret := make([]Option, len(options))
for i := range options {
ret[i] = Arg(options[i])
}
return ret
}
}
func PredictFiles(pattern string) *Predicate {
return &Predicate{Predictor: glob(pattern)}
}
func dirs(last string) (options []Option) {
func PredictDirs(last string) (options []Option) {
dir := dirFromLast(last)
return dirsAt(dir)
}
@ -71,7 +59,7 @@ func dirsAt(path string) []Option {
return filesToOptions(dirs)
}
func glob(pattern string) func(last string) []Option {
func PredictFiles(pattern string) Predicate {
return func(last string) []Option {
dir := dirFromLast(last)
files, err := filepath.Glob(filepath.Join(dir, pattern))

View File

@ -9,9 +9,12 @@ import (
func TestCompleter_Complete(t *testing.T) {
t.Parallel()
// Set debug environment variable so logs will be printed
if testing.Verbose() {
os.Setenv(envDebug, "1")
}
// Change to tests directory for testing completion of files and directories
err := os.Chdir("./tests")
if err != nil {
t.Fatal(err)
@ -20,20 +23,20 @@ func TestCompleter_Complete(t *testing.T) {
c := Command{
Sub: map[string]Command{
"sub1": {
Flags: map[string]*Predicate{
Flags: map[string]Predicate{
"-flag1": PredictAnything,
"-flag2": PredictNothing,
},
},
"sub2": {
Flags: map[string]*Predicate{
Flags: map[string]Predicate{
"-flag2": PredictNothing,
"-flag3": PredictSet("opt1", "opt2", "opt12"),
},
Args: PredictDirs.Or(PredictFiles("*.md")),
Args: Predicate(PredictDirs).Or(PredictFiles("*.md")),
},
},
Flags: map[string]*Predicate{
Flags: map[string]Predicate{
"-h": PredictNothing,
"-global1": PredictAnything,
"-o": PredictFiles("*.txt"),