From 04d16f6064c7c71068f47b4e7106f15a05b6b326 Mon Sep 17 00:00:00 2001 From: Eyal Posener Date: Fri, 5 May 2017 21:59:10 +0300 Subject: Renamings --- command.go | 6 ++--- complete.go | 8 +++--- complete_test.go | 20 +++++++------- flag.go | 65 --------------------------------------------- gocomplete/complete.go | 10 +++---- predicate.go | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 87 deletions(-) delete mode 100644 flag.go create mode 100644 predicate.go diff --git a/command.go b/command.go index f3321fb..9292a89 100644 --- a/command.go +++ b/command.go @@ -2,7 +2,7 @@ package complete type Commands map[string]Command -type Flags map[string]FlagOptions +type Flags map[string]Predicate type Command struct { Sub Commands @@ -18,8 +18,8 @@ func (c *Command) options(args []string) (options []Option, only bool) { // if prev has something that needs to follow it, // it is the most relevant completion - if options, ok := c.Flags[last(args)]; ok && options.HasFollow { - return options.follows(), true + if predicate, ok := c.Flags[last(args)]; ok && predicate.Expects { + return predicate.predict(), true } sub, options, only := c.searchSub(args) diff --git a/complete.go b/complete.go index 6345e63..e7e209e 100644 --- a/complete.go +++ b/complete.go @@ -34,10 +34,10 @@ func (c *Completer) complete(args []string) []string { return c.chooseRelevant(last(args), all) } -func (c *Completer) chooseRelevant(last string, list []Option) (options []string) { - for _, sub := range list { - if sub.Matches(last) { - options = append(options, sub.String()) +func (c *Completer) chooseRelevant(last string, options []Option) (relevant []string) { + for _, option := range options { + if option.Matches(last) { + relevant = append(relevant, option.String()) } } return diff --git a/complete_test.go b/complete_test.go index 3485a99..aad747e 100644 --- a/complete_test.go +++ b/complete_test.go @@ -17,22 +17,22 @@ func TestCompleter_Complete(t *testing.T) { Command: Command{ Sub: map[string]Command{ "sub1": { - Flags: map[string]FlagOptions{ - "-flag1": FlagUnknownFollow, - "-flag2": FlagNoFollow, + Flags: map[string]Predicate{ + "-flag1": PredictAnything, + "-flag2": PredictNothing, }, }, "sub2": { - Flags: map[string]FlagOptions{ - "-flag2": FlagNoFollow, - "-flag3": FlagNoFollow, + Flags: map[string]Predicate{ + "-flag2": PredictNothing, + "-flag3": PredictNothing, }, }, }, - Flags: map[string]FlagOptions{ - "-h": FlagNoFollow, - "-global1": FlagUnknownFollow, - "-o": FlagFileFilter("./gocomplete/*.go"), + Flags: map[string]Predicate{ + "-h": PredictNothing, + "-global1": PredictAnything, + "-o": PredictFiles("./gocomplete/*.go"), }, }, } diff --git a/flag.go b/flag.go deleted file mode 100644 index 645cb83..0000000 --- a/flag.go +++ /dev/null @@ -1,65 +0,0 @@ -package complete - -import ( - "os" - "path/filepath" -) - -type FlagOptions struct { - HasFollow bool - FollowsOptions func() []Option -} - -func (f *FlagOptions) follows() []Option { - if f.FollowsOptions == nil { - return nil - } - return f.FollowsOptions() -} - -var ( - FlagNoFollow = FlagOptions{} - FlagUnknownFollow = FlagOptions{HasFollow: true} -) - -func FlagFileFilter(pattern string) FlagOptions { - return FlagOptions{ - HasFollow: true, - FollowsOptions: glob(pattern), - } -} - -func glob(pattern string) func() []Option { - return func() []Option { - files, err := filepath.Glob(pattern) - if err != nil { - logger("failed glob operation with pattern '%s': %s", pattern, err) - } - if !filepath.IsAbs(pattern) { - filesToRel(files) - } - options := make([]Option, len(files)) - for i, f := range files { - options[i] = ArgFileName(f) - } - return options - } -} -func filesToRel(files []string) { - wd, err := os.Getwd() - if err != nil { - return - } - for i := range files { - abs, err := filepath.Abs(files[i]) - if err != nil { - continue - } - rel, err := filepath.Rel(wd, abs) - if err != nil { - continue - } - files[i] = "./" + rel - } - return -} diff --git a/gocomplete/complete.go b/gocomplete/complete.go index 727e190..5b31cc6 100644 --- a/gocomplete/complete.go +++ b/gocomplete/complete.go @@ -7,15 +7,15 @@ import ( var ( build = complete.Command{ Flags: complete.Flags{ - "-o": complete.FlagUnknownFollow, - "-i": complete.FlagNoFollow, + "-o": complete.PredictFiles("*"), + "-i": complete.PredictNothing, }, } test = complete.Command{ Flags: complete.Flags{ - "-run": complete.FlagUnknownFollow, - "-count": complete.FlagUnknownFollow, + "-run": complete.PredictAnything, + "-count": complete.PredictAnything, }, } @@ -25,7 +25,7 @@ var ( "test": test, }, Flags: complete.Flags{ - "-h": complete.FlagNoFollow, + "-h": complete.PredictNothing, }, } ) diff --git a/predicate.go b/predicate.go new file mode 100644 index 0000000..5ba544b --- /dev/null +++ b/predicate.go @@ -0,0 +1,71 @@ +package complete + +import ( + "os" + "path/filepath" +) + +// Predicate determines what terms can follow a command or a flag +type Predicate struct { + // Expects determine if the predicate expects something after. + // flags/commands that do not expect any specific argument should + // leave it on false + Expects bool + // Predictor is function that returns list of arguments that can + // come after the flag/command + Predictor func() []Option +} + +func (f *Predicate) predict() []Option { + if f.Predictor == nil { + return nil + } + return f.Predictor() +} + +var ( + PredictNothing = Predicate{Expects: false} + PredictAnything = Predicate{Expects: true} +) + +func PredictFiles(pattern string) Predicate { + return Predicate{ + Expects: true, + Predictor: glob(pattern), + } +} + +func glob(pattern string) func() []Option { + return func() []Option { + files, err := filepath.Glob(pattern) + if err != nil { + logger("failed glob operation with pattern '%s': %s", pattern, err) + } + if !filepath.IsAbs(pattern) { + filesToRel(files) + } + options := make([]Option, len(files)) + for i, f := range files { + options[i] = ArgFileName(f) + } + return options + } +} +func filesToRel(files []string) { + wd, err := os.Getwd() + if err != nil { + return + } + for i := range files { + abs, err := filepath.Abs(files[i]) + if err != nil { + continue + } + rel, err := filepath.Rel(wd, abs) + if err != nil { + continue + } + files[i] = "./" + rel + } + return +} -- cgit v1.2.3