summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--args.go18
-rw-r--r--args_test.go215
-rw-r--r--predict_files.go26
-rw-r--r--utils.go31
4 files changed, 262 insertions, 28 deletions
diff --git a/args.go b/args.go
index 1fe090a..2dbb816 100644
--- a/args.go
+++ b/args.go
@@ -28,18 +28,23 @@ type Args struct {
// in case that it is not, we fall back to the current directory.
func (a Args) Directory() string {
if info, err := os.Stat(a.Last); err == nil && info.IsDir() {
+ if !filepath.IsAbs(a.Last) {
+ return relativePath(a.Last)
+ }
return a.Last
}
dir := filepath.Dir(a.Last)
- _, err := os.Stat(dir)
- if err != nil {
+ if info, err := os.Stat(dir); err != nil || !info.IsDir() {
return "./"
}
+ if !filepath.IsAbs(dir) {
+ dir = relativePath(dir)
+ }
return dir
}
func newArgs(line []string) Args {
- completed := removeLast(line)
+ completed := removeLast(line[1:])
return Args{
All: line[1:],
Completed: completed,
@@ -49,7 +54,14 @@ func newArgs(line []string) Args {
}
func (a Args) from(i int) Args {
+ if i > len(a.All) {
+ i = len(a.All)
+ }
a.All = a.All[i:]
+
+ if i > len(a.Completed) {
+ i = len(a.Completed)
+ }
a.Completed = a.Completed[i:]
return a
}
diff --git a/args_test.go b/args_test.go
new file mode 100644
index 0000000..78d346f
--- /dev/null
+++ b/args_test.go
@@ -0,0 +1,215 @@
+package complete
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+)
+
+func TestArgs(t *testing.T) {
+ t.Parallel()
+ tests := []struct {
+ line string
+ completed string
+ last string
+ lastCompleted string
+ }{
+ {
+ line: "a b c",
+ completed: "b",
+ last: "c",
+ lastCompleted: "b",
+ },
+ {
+ line: "a b ",
+ completed: "b",
+ last: "",
+ lastCompleted: "b",
+ },
+ {
+ line: "",
+ completed: "",
+ last: "",
+ lastCompleted: "",
+ },
+ {
+ line: "a",
+ completed: "",
+ last: "a",
+ lastCompleted: "",
+ },
+ {
+ line: "a ",
+ completed: "",
+ last: "",
+ lastCompleted: "",
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.line, func(t *testing.T) {
+
+ a := newArgs(strings.Split(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)
+ }
+ if got, want := a.Last, tt.last; got != want {
+ t.Errorf("Last = %q, want %q", got, want)
+ }
+ if got, want := a.LastCompleted, tt.lastCompleted; got != want {
+ t.Errorf("%s failed: LastCompleted = %q, want %q", t.Name(), got, want)
+ }
+ })
+ }
+}
+
+func TestArgs_From(t *testing.T) {
+ t.Parallel()
+ tests := []struct {
+ line string
+ from int
+ newLine string
+ newCompleted string
+ }{
+ {
+ line: "a b c",
+ from: 0,
+ newLine: "b c",
+ newCompleted: "b",
+ },
+ {
+ line: "a b c",
+ from: 1,
+ newLine: "c",
+ newCompleted: "",
+ },
+ {
+ line: "a b c",
+ from: 2,
+ newLine: "",
+ newCompleted: "",
+ },
+ {
+ line: "a b c",
+ from: 3,
+ newLine: "",
+ newCompleted: "",
+ },
+ {
+ line: "a b c ",
+ from: 0,
+ newLine: "b c ",
+ newCompleted: "b c",
+ },
+ {
+ line: "a b c ",
+ from: 1,
+ newLine: "c ",
+ newCompleted: "c",
+ },
+ {
+ line: "a b c ",
+ from: 2,
+ newLine: "",
+ newCompleted: "",
+ },
+ {
+ line: "",
+ from: 0,
+ newLine: "",
+ newCompleted: "",
+ },
+ {
+ line: "",
+ from: 1,
+ newLine: "",
+ newCompleted: "",
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(fmt.Sprintf("%s/%d", tt.line, tt.from), func(t *testing.T) {
+
+ a := newArgs(strings.Split(tt.line, " "))
+ n := a.from(tt.from)
+
+ if got, want := strings.Join(n.All, " "), tt.newLine; got != want {
+ t.Errorf("%s failed: all = %q, want %q", t.Name(), got, want)
+ }
+ if got, want := strings.Join(n.Completed, " "), tt.newCompleted; got != want {
+ t.Errorf("%s failed: completed = %q, want %q", t.Name(), got, want)
+ }
+ })
+ }
+}
+
+func TestArgs_Directory(t *testing.T) {
+ t.Parallel()
+ initTests()
+
+ tests := []struct {
+ line string
+ directory string
+ }{
+ {
+ line: "a b c",
+ directory: "./",
+ },
+ {
+ line: "a b c /tm",
+ directory: "/",
+ },
+ {
+ line: "a b c /tmp",
+ directory: "/tmp",
+ },
+ {
+ line: "a b c /tmp ",
+ directory: "./",
+ },
+ {
+ line: "a b c ./",
+ directory: "./",
+ },
+ {
+ line: "a b c ./dir",
+ directory: "./dir/",
+ },
+ {
+ line: "a b c dir",
+ directory: "./dir/",
+ },
+ {
+ line: "a b c ./di",
+ directory: "./",
+ },
+ {
+ line: "a b c ./dir ",
+ directory: "./",
+ },
+ {
+ line: "a b c ./di",
+ directory: "./",
+ },
+ {
+ line: "a b c ./a.txt",
+ directory: "./",
+ },
+ {
+ line: "a b c ./a.txt/x",
+ directory: "./",
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.line, func(t *testing.T) {
+
+ a := newArgs(strings.Split(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/predict_files.go b/predict_files.go
index 5f83e77..af26e81 100644
--- a/predict_files.go
+++ b/predict_files.go
@@ -78,7 +78,7 @@ func PredictFilesSet(files []string) PredictFunc {
for _, f := range files {
// change file name to relative if necessary
if rel {
- f = toRel(f)
+ f = relativePath(f)
}
// test matching of file to the argument
@@ -119,27 +119,3 @@ func listFiles(dir, pattern string, allowFiles bool) []string {
return list
}
-// toRel changes a file name to a relative name
-func toRel(file string) string {
- // get wording directory for relative name
- workDir, err := os.Getwd()
- if err != nil {
- return file
- }
-
- abs, err := filepath.Abs(file)
- if err != nil {
- return file
- }
- rel, err := filepath.Rel(workDir, abs)
- if err != nil {
- return file
- }
- if rel != "." {
- rel = "./" + rel
- }
- if info, err := os.Stat(rel); err == nil && info.IsDir() {
- rel += "/"
- }
- return rel
-}
diff --git a/utils.go b/utils.go
new file mode 100644
index 0000000..a59a0d4
--- /dev/null
+++ b/utils.go
@@ -0,0 +1,31 @@
+package complete
+
+import (
+ "os"
+ "path/filepath"
+)
+
+// relativePath changes a file name to a relative name
+func relativePath(file string) string {
+ // get wording directory for relative name
+ workDir, err := os.Getwd()
+ if err != nil {
+ return file
+ }
+
+ abs, err := filepath.Abs(file)
+ if err != nil {
+ return file
+ }
+ rel, err := filepath.Rel(workDir, abs)
+ if err != nil {
+ return file
+ }
+ if rel != "." {
+ rel = "./" + rel
+ }
+ if info, err := os.Stat(rel); err == nil && info.IsDir() {
+ rel += "/"
+ }
+ return rel
+}