summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rw-r--r--command.go17
-rw-r--r--complete.go22
-rw-r--r--complete_test.go44
-rw-r--r--gocomplete/tests.go11
-rw-r--r--gocomplete/tests_test.go27
-rw-r--r--predict_set.go11
-rw-r--r--predict_test.go6
8 files changed, 57 insertions, 83 deletions
diff --git a/.travis.yml b/.travis.yml
index 459df21..c2798f8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,8 +1,8 @@
language: go
sudo: false
go:
+ - 1.9
- 1.8
- - tip
before_install:
- go get -u -t ./...
diff --git a/command.go b/command.go
index 6de48e9..82d37d5 100644
--- a/command.go
+++ b/command.go
@@ -1,7 +1,5 @@
package complete
-import "github.com/posener/complete/match"
-
// Command represents a command line
// It holds the data that enables auto completion of command line
// Command can also be a sub command.
@@ -25,9 +23,9 @@ type Command struct {
}
// Predict returns all possible predictions for args according to the command struct
-func (c *Command) Predict(a Args) (predictions []string) {
- predictions, _ = c.predict(a)
- return
+func (c *Command) Predict(a Args) []string {
+ options, _ := c.predict(a)
+ return options
}
// Commands is the type of Sub member, it maps a command name to a command struct
@@ -36,9 +34,7 @@ type Commands map[string]Command
// Predict completion of sub command names names according to command line arguments
func (c Commands) Predict(a Args) (prediction []string) {
for sub := range c {
- if match.Prefix(sub, a.Last) {
- prediction = append(prediction, sub)
- }
+ prediction = append(prediction, sub)
}
return
}
@@ -56,10 +52,7 @@ func (f Flags) Predict(a Args) (prediction []string) {
if flagHyphenStart && !lastHyphenStart {
continue
}
-
- if match.Prefix(flag, a.Last) {
- prediction = append(prediction, flag)
- }
+ prediction = append(prediction, flag)
}
return
}
diff --git a/complete.go b/complete.go
index d7b6bf4..185d1e8 100644
--- a/complete.go
+++ b/complete.go
@@ -8,9 +8,11 @@ package complete
import (
"flag"
"fmt"
+ "io"
"os"
"github.com/posener/complete/cmd"
+ "github.com/posener/complete/match"
)
const (
@@ -22,6 +24,7 @@ const (
type Complete struct {
Command Command
cmd.CLI
+ Out io.Writer
}
// New creates a new complete command.
@@ -33,6 +36,7 @@ func New(name string, command Command) *Complete {
return &Complete{
Command: command,
CLI: cmd.CLI{Name: name},
+ Out: os.Stdout,
}
}
@@ -58,13 +62,20 @@ func (c *Complete) Complete() bool {
return c.CLI.Run()
}
Log("Completing line: %s", line)
-
a := newArgs(line)
Log("Completing last field: %s", a.Last)
options := c.Command.Predict(a)
+ Log("Options: %s", options)
- Log("Completion: %s", options)
- output(options)
+ // filter only options that match the last argument
+ matches := []string{}
+ for _, option := range options {
+ if match.Prefix(option, a.Last) {
+ matches = append(matches, option)
+ }
+ }
+ Log("Matches: %s", matches)
+ c.output(matches)
return true
}
@@ -76,10 +87,9 @@ func getLine() (string, bool) {
return line, true
}
-func output(options []string) {
- Log("")
+func (c *Complete) output(options []string) {
// stdout of program defines the complete options
for _, option := range options {
- fmt.Println(option)
+ fmt.Fprintln(c.Out, option)
}
}
diff --git a/complete_test.go b/complete_test.go
index cd7880c..1611ad4 100644
--- a/complete_test.go
+++ b/complete_test.go
@@ -1,8 +1,10 @@
package complete
import (
+ "bytes"
"os"
"sort"
+ "strings"
"testing"
)
@@ -34,6 +36,7 @@ func TestCompleter_Complete(t *testing.T) {
"-global1": PredictAnything,
},
}
+ cmp := New("cmd", c)
tests := []struct {
args string
@@ -195,18 +198,13 @@ func TestCompleter_Complete(t *testing.T) {
for _, tt := range tests {
t.Run(tt.args, func(t *testing.T) {
-
- tt.args = "cmd " + tt.args
- os.Setenv(envComplete, tt.args)
- line, _ := getLine()
-
- got := c.Predict(newArgs(line))
+ got := runComplete(cmp, tt.args)
sort.Strings(tt.want)
sort.Strings(got)
if !equalSlices(got, tt.want) {
- t.Errorf("failed '%s'\ngot = %s\nwant: %s", t.Name(), got, tt.want)
+ t.Errorf("failed '%s'\ngot: %s\nwant: %s", t.Name(), got, tt.want)
}
})
}
@@ -242,6 +240,8 @@ func TestCompleter_Complete_SharedPrefix(t *testing.T) {
},
}
+ cmp := New("cmd", c)
+
tests := []struct {
args string
want []string
@@ -278,12 +278,7 @@ func TestCompleter_Complete_SharedPrefix(t *testing.T) {
for _, tt := range tests {
t.Run(tt.args, func(t *testing.T) {
-
- tt.args = "cmd " + tt.args
- os.Setenv(envComplete, tt.args)
- line, _ := getLine()
-
- got := c.Predict(newArgs(line))
+ got := runComplete(cmp, tt.args)
sort.Strings(tt.want)
sort.Strings(got)
@@ -295,6 +290,29 @@ func TestCompleter_Complete_SharedPrefix(t *testing.T) {
}
}
+// runComplete runs the complete login for test purposes
+// it gets the complete struct and command line arguments and returns
+// the complete options
+func runComplete(c *Complete, args string) (completions []string) {
+ os.Setenv(envComplete, "cmd "+args)
+ b := bytes.NewBuffer(nil)
+ c.Out = b
+ c.Complete()
+ completions = parseOutput(b.String())
+ return
+}
+
+func parseOutput(output string) []string {
+ lines := strings.Split(output, "\n")
+ options := []string{}
+ for _, l := range lines {
+ if l != "" {
+ options = append(options, l)
+ }
+ }
+ return options
+}
+
func equalSlices(a, b []string) bool {
if len(a) != len(b) {
return false
diff --git a/gocomplete/tests.go b/gocomplete/tests.go
index a952dab..e755ae5 100644
--- a/gocomplete/tests.go
+++ b/gocomplete/tests.go
@@ -7,7 +7,6 @@ import (
"strings"
"github.com/posener/complete"
- "github.com/posener/complete/match"
)
var (
@@ -21,14 +20,8 @@ var (
// for test names use prefix of 'Test' or 'Example', and for benchmark
// test names use 'Benchmark'
func funcPredict(funcRegexp *regexp.Regexp) complete.Predictor {
- return complete.PredictFunc(func(a complete.Args) (prediction []string) {
- tests := funcNames(funcRegexp)
- for _, t := range tests {
- if match.Prefix(t, a.Last) {
- prediction = append(prediction, t)
- }
- }
- return
+ return complete.PredictFunc(func(a complete.Args) []string {
+ return funcNames(funcRegexp)
})
}
diff --git a/gocomplete/tests_test.go b/gocomplete/tests_test.go
index 6799157..150e2e2 100644
--- a/gocomplete/tests_test.go
+++ b/gocomplete/tests_test.go
@@ -23,37 +23,10 @@ func TestPredictions(t *testing.T) {
want: []string{"TestPredictions", "Example"},
},
{
- name: "predict tests not found",
- predictor: predictTest,
- last: "X",
- },
- {
name: "predict benchmark ok",
predictor: predictBenchmark,
want: []string{"BenchmarkFake"},
},
- {
- name: "predict benchmarks not found",
- predictor: predictBenchmark,
- last: "X",
- },
- {
- name: "predict local ok",
- predictor: complete.PredictFunc(predictPackages),
- last: ".",
- want: []string{"./"},
- },
- {
- name: "predict system ok",
- predictor: complete.PredictFunc(predictPackages),
- last: "github.com/posener/complete/goc",
- want: []string{"github.com/posener/complete/gocomplete/"},
- },
- {
- name: "predict packages not found",
- predictor: complete.PredictFunc(predictPackages),
- last: "X",
- },
}
for _, tt := range tests {
diff --git a/predict_set.go b/predict_set.go
index 8fc59d7..fa4a34a 100644
--- a/predict_set.go
+++ b/predict_set.go
@@ -1,7 +1,5 @@
package complete
-import "github.com/posener/complete/match"
-
// PredictSet expects specific set of terms, given in the options argument.
func PredictSet(options ...string) Predictor {
return predictSet(options)
@@ -9,11 +7,6 @@ func PredictSet(options ...string) Predictor {
type predictSet []string
-func (p predictSet) Predict(a Args) (prediction []string) {
- for _, m := range p {
- if match.Prefix(m, a.Last) {
- prediction = append(prediction, m)
- }
- }
- return
+func (p predictSet) Predict(a Args) []string {
+ return p
}
diff --git a/predict_test.go b/predict_test.go
index 8baecf7..24df78d 100644
--- a/predict_test.go
+++ b/predict_test.go
@@ -22,12 +22,6 @@ func TestPredicate(t *testing.T) {
want: []string{"a", "b", "c"},
},
{
- name: "set with does",
- p: PredictSet("./..", "./x"),
- argList: []string{"./.", "./.."},
- want: []string{"./.."},
- },
- {
name: "set/empty",
p: PredictSet(),
want: []string{},