summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--args.go43
-rw-r--r--args_test.go6
-rw-r--r--complete.go9
-rw-r--r--complete_test.go20
-rw-r--r--gocomplete/complete.go2
-rw-r--r--predict_test.go2
6 files changed, 64 insertions, 18 deletions
diff --git a/args.go b/args.go
index 73c356d..1ba4d69 100644
--- a/args.go
+++ b/args.go
@@ -3,6 +3,8 @@ package complete
import (
"os"
"path/filepath"
+ "strings"
+ "unicode"
)
// Args describes command line arguments
@@ -37,16 +39,41 @@ func (a Args) Directory() string {
return fixPathForm(a.Last, dir)
}
-func newArgs(line []string) Args {
- completed := removeLast(line[1:])
+func newArgs(line string) Args {
+ var (
+ all []string
+ completed []string
+ )
+ parts := splitFields(line)
+ if len(parts) > 0 {
+ all = parts[1:]
+ completed = removeLast(parts[1:])
+ }
return Args{
- All: line[1:],
+ All: all,
Completed: completed,
- Last: last(line),
+ Last: last(parts),
LastCompleted: last(completed),
}
}
+func splitFields(line string) []string {
+ parts := strings.Fields(line)
+ if len(line) > 0 && unicode.IsSpace(rune(line[len(line)-1])) {
+ parts = append(parts, "")
+ }
+ parts = splitLastEqual(parts)
+ return parts
+}
+
+func splitLastEqual(line []string) []string {
+ if len(line) == 0 {
+ return line
+ }
+ parts := strings.Split(line[len(line)-1], "=")
+ return append(line[:len(line)-1], parts...)
+}
+
func (a Args) from(i int) Args {
if i > len(a.All) {
i = len(a.All)
@@ -67,9 +94,9 @@ func removeLast(a []string) []string {
return a
}
-func last(args []string) (last string) {
- if len(args) > 0 {
- last = args[len(args)-1]
+func last(args []string) string {
+ if len(args) == 0 {
+ return ""
}
- return
+ return args[len(args)-1]
}
diff --git a/args_test.go b/args_test.go
index a211815..e67125e 100644
--- a/args_test.go
+++ b/args_test.go
@@ -49,7 +49,7 @@ func TestArgs(t *testing.T) {
for _, tt := range tests {
t.Run(tt.line, func(t *testing.T) {
- a := newArgs(strings.Split(tt.line, " "))
+ a := newArgs(tt.line)
if got, want := strings.Join(a.Completed, " "), tt.completed; got != want {
t.Errorf("%s failed: Completed = %q, want %q", t.Name(), got, want)
@@ -131,7 +131,7 @@ func TestArgs_From(t *testing.T) {
for _, tt := range tests {
t.Run(fmt.Sprintf("%s/%d", tt.line, tt.from), func(t *testing.T) {
- a := newArgs(strings.Split(tt.line, " "))
+ a := newArgs(tt.line)
n := a.from(tt.from)
if got, want := strings.Join(n.All, " "), tt.newLine; got != want {
@@ -205,7 +205,7 @@ func TestArgs_Directory(t *testing.T) {
for _, tt := range tests {
t.Run(tt.line, func(t *testing.T) {
- a := newArgs(strings.Split(tt.line, " "))
+ a := newArgs(tt.line)
if got, want := a.Directory(), tt.directory; got != want {
t.Errorf("%s failed: directory = %q, want %q", t.Name(), got, want)
diff --git a/complete.go b/complete.go
index 1df6617..d7b6bf4 100644
--- a/complete.go
+++ b/complete.go
@@ -9,7 +9,6 @@ import (
"flag"
"fmt"
"os"
- "strings"
"github.com/posener/complete/cmd"
)
@@ -61,7 +60,7 @@ func (c *Complete) Complete() bool {
Log("Completing line: %s", line)
a := newArgs(line)
-
+ Log("Completing last field: %s", a.Last)
options := c.Command.Predict(a)
Log("Completion: %s", options)
@@ -69,12 +68,12 @@ func (c *Complete) Complete() bool {
return true
}
-func getLine() ([]string, bool) {
+func getLine() (string, bool) {
line := os.Getenv(envComplete)
if line == "" {
- return nil, false
+ return "", false
}
- return strings.Split(line, " "), true
+ return line, true
}
func output(options []string) {
diff --git a/complete_test.go b/complete_test.go
index ba4df4a..cd7880c 100644
--- a/complete_test.go
+++ b/complete_test.go
@@ -144,14 +144,30 @@ func TestCompleter_Complete(t *testing.T) {
want: []string{"./a.txt", "./b.txt", "./c.txt", "./.dot.txt", "./", "./dir/", "./outer/"},
},
{
+ args: "-o=./",
+ want: []string{"./a.txt", "./b.txt", "./c.txt", "./.dot.txt", "./", "./dir/", "./outer/"},
+ },
+ {
args: "-o .",
want: []string{"./a.txt", "./b.txt", "./c.txt", "./.dot.txt", "./", "./dir/", "./outer/"},
},
{
+ args: "-o ./b",
+ want: []string{"./b.txt"},
+ },
+ {
+ args: "-o=./b",
+ want: []string{"./b.txt"},
+ },
+ {
args: "-o ./read",
want: []string{},
},
{
+ args: "-o=./read",
+ want: []string{},
+ },
+ {
args: "-o ./readme.md",
want: []string{},
},
@@ -160,6 +176,10 @@ func TestCompleter_Complete(t *testing.T) {
want: []string{"sub1", "sub2"},
},
{
+ args: "-o=./readme.md ",
+ want: []string{"sub1", "sub2"},
+ },
+ {
args: "-o sub2 -flag3 ",
want: []string{"opt1", "opt2", "opt12"},
},
diff --git a/gocomplete/complete.go b/gocomplete/complete.go
index 9f46dcd..553de9d 100644
--- a/gocomplete/complete.go
+++ b/gocomplete/complete.go
@@ -28,7 +28,7 @@ func main() {
"-asmflags": complete.PredictAnything,
"-buildmode": complete.PredictAnything,
"-compiler": complete.PredictAnything,
- "-gccgoflags": complete.PredictAnything,
+ "-gccgoflags": complete.PredictSet("gccgo", "gc"),
"-gcflags": complete.PredictAnything,
"-installsuffix": complete.PredictAnything,
"-ldflags": complete.PredictAnything,
diff --git a/predict_test.go b/predict_test.go
index ac26e33..8baecf7 100644
--- a/predict_test.go
+++ b/predict_test.go
@@ -158,7 +158,7 @@ func TestPredicate(t *testing.T) {
for _, arg := range tt.argList {
t.Run(tt.name+"/arg="+arg, func(t *testing.T) {
- matches := tt.p.Predict(newArgs(strings.Split(arg, " ")))
+ matches := tt.p.Predict(newArgs(arg))
sort.Strings(matches)
sort.Strings(tt.want)