summaryrefslogtreecommitdiff
path: root/predict_files.go
diff options
context:
space:
mode:
authorEyal Posener <[email protected]>2019-07-05 17:33:47 +0300
committerGitHub <[email protected]>2019-07-05 17:33:47 +0300
commit2f2ff270a9f6adcef8351b1bdf5319b5d612b53f (patch)
tree0dbc83883d33ac239db651f19be3fe67fd3dc361 /predict_files.go
parent6ffe496ea9530c0638974624ed9dd429f9ad592e (diff)
parent72c5c945f0d5861ba1d4e51a0a5ac36a4bef3868 (diff)
Merge pull request #98 from posener/refactor
Some refactorings
Diffstat (limited to 'predict_files.go')
-rw-r--r--predict_files.go74
1 files changed, 70 insertions, 4 deletions
diff --git a/predict_files.go b/predict_files.go
index c8adf7e..25ae2d5 100644
--- a/predict_files.go
+++ b/predict_files.go
@@ -5,8 +5,6 @@ import (
"os"
"path/filepath"
"strings"
-
- "github.com/posener/complete/match"
)
// PredictDirs will search for directories in the given started to be typed
@@ -53,7 +51,7 @@ func predictFiles(a Args, pattern string, allowFiles bool) []string {
return nil
}
- dir := a.Directory()
+ dir := directory(a.Last)
files := listFiles(dir, pattern, allowFiles)
// add dir if match
@@ -62,6 +60,19 @@ func predictFiles(a Args, pattern string, allowFiles bool) []string {
return PredictFilesSet(files).Predict(a)
}
+// directory gives the directory of the given partial path
+// in case that it is not, we fall back to the current directory.
+func directory(path string) string {
+ if info, err := os.Stat(path); err == nil && info.IsDir() {
+ return fixPathForm(path, path)
+ }
+ dir := filepath.Dir(path)
+ if info, err := os.Stat(dir); err == nil && info.IsDir() {
+ return fixPathForm(path, dir)
+ }
+ return "./"
+}
+
// PredictFilesSet predict according to file rules to a given set of file names
func PredictFilesSet(files []string) PredictFunc {
return func(a Args) (prediction []string) {
@@ -70,7 +81,7 @@ func PredictFilesSet(files []string) PredictFunc {
f = fixPathForm(a.Last, f)
// test matching of file to the argument
- if match.File(f, a.Last) {
+ if matchFile(f, a.Last) {
prediction = append(prediction, f)
}
}
@@ -106,3 +117,58 @@ func listFiles(dir, pattern string, allowFiles bool) []string {
}
return list
}
+
+// MatchFile returns true if prefix can match the file
+func matchFile(file, prefix string) bool {
+ // special case for current directory completion
+ if file == "./" && (prefix == "." || prefix == "") {
+ return true
+ }
+ if prefix == "." && strings.HasPrefix(file, ".") {
+ return true
+ }
+
+ file = strings.TrimPrefix(file, "./")
+ prefix = strings.TrimPrefix(prefix, "./")
+
+ return strings.HasPrefix(file, prefix)
+}
+
+// fixPathForm changes a file name to a relative name
+func fixPathForm(last string, 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
+ }
+
+ // if last is absolute, return path as absolute
+ if filepath.IsAbs(last) {
+ return fixDirPath(abs)
+ }
+
+ rel, err := filepath.Rel(workDir, abs)
+ if err != nil {
+ return file
+ }
+
+ // fix ./ prefix of path
+ if rel != "." && strings.HasPrefix(last, ".") {
+ rel = "./" + rel
+ }
+
+ return fixDirPath(rel)
+}
+
+func fixDirPath(path string) string {
+ info, err := os.Stat(path)
+ if err == nil && info.IsDir() && !strings.HasSuffix(path, "/") {
+ path += "/"
+ }
+ return path
+}