commit
6c02dfed24
18
args.go
18
args.go
|
@ -28,18 +28,23 @@ type Args struct {
|
||||||
// in case that it is not, we fall back to the current directory.
|
// in case that it is not, we fall back to the current directory.
|
||||||
func (a Args) Directory() string {
|
func (a Args) Directory() string {
|
||||||
if info, err := os.Stat(a.Last); err == nil && info.IsDir() {
|
if info, err := os.Stat(a.Last); err == nil && info.IsDir() {
|
||||||
|
if !filepath.IsAbs(a.Last) {
|
||||||
|
return relativePath(a.Last)
|
||||||
|
}
|
||||||
return a.Last
|
return a.Last
|
||||||
}
|
}
|
||||||
dir := filepath.Dir(a.Last)
|
dir := filepath.Dir(a.Last)
|
||||||
_, err := os.Stat(dir)
|
if info, err := os.Stat(dir); err != nil || !info.IsDir() {
|
||||||
if err != nil {
|
|
||||||
return "./"
|
return "./"
|
||||||
}
|
}
|
||||||
|
if !filepath.IsAbs(dir) {
|
||||||
|
dir = relativePath(dir)
|
||||||
|
}
|
||||||
return dir
|
return dir
|
||||||
}
|
}
|
||||||
|
|
||||||
func newArgs(line []string) Args {
|
func newArgs(line []string) Args {
|
||||||
completed := removeLast(line)
|
completed := removeLast(line[1:])
|
||||||
return Args{
|
return Args{
|
||||||
All: line[1:],
|
All: line[1:],
|
||||||
Completed: completed,
|
Completed: completed,
|
||||||
|
@ -49,7 +54,14 @@ func newArgs(line []string) Args {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a Args) from(i int) Args {
|
func (a Args) from(i int) Args {
|
||||||
|
if i > len(a.All) {
|
||||||
|
i = len(a.All)
|
||||||
|
}
|
||||||
a.All = a.All[i:]
|
a.All = a.All[i:]
|
||||||
|
|
||||||
|
if i > len(a.Completed) {
|
||||||
|
i = len(a.Completed)
|
||||||
|
}
|
||||||
a.Completed = a.Completed[i:]
|
a.Completed = a.Completed[i:]
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -78,7 +78,7 @@ func PredictFilesSet(files []string) PredictFunc {
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
// change file name to relative if necessary
|
// change file name to relative if necessary
|
||||||
if rel {
|
if rel {
|
||||||
f = toRel(f)
|
f = relativePath(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// test matching of file to the argument
|
// test matching of file to the argument
|
||||||
|
@ -119,27 +119,3 @@ func listFiles(dir, pattern string, allowFiles bool) []string {
|
||||||
return list
|
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
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue