summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gocomplete/complete.go2
-rw-r--r--gocomplete/pkgs.go90
-rw-r--r--gocomplete/tests_test.go10
3 files changed, 41 insertions, 61 deletions
diff --git a/gocomplete/complete.go b/gocomplete/complete.go
index bb3e92e..00392eb 100644
--- a/gocomplete/complete.go
+++ b/gocomplete/complete.go
@@ -44,7 +44,7 @@ func main() {
Flags: complete.Flags{
"-exec": complete.PredictAnything,
},
- Args: complete.PredictFunc(predictRunnableFiles),
+ Args: goFiles,
}
test := complete.Command{
diff --git a/gocomplete/pkgs.go b/gocomplete/pkgs.go
index 356a0fa..e8f5261 100644
--- a/gocomplete/pkgs.go
+++ b/gocomplete/pkgs.go
@@ -1,76 +1,66 @@
package main
import (
- "bytes"
- "encoding/json"
- "os/exec"
+ "go/build"
+ "io/ioutil"
+ "os"
"path/filepath"
- "regexp"
- "strings"
"github.com/posener/complete"
)
-const goListFormat = `{"Name": "{{.Name}}", "Path": "{{.Dir}}", "FilesString": "{{.GoFiles}}"}`
-
-// regexp matches a main function
-var reMainFunc = regexp.MustCompile("^main$")
-
func predictPackages(a complete.Args) (prediction []string) {
- dir := a.Directory()
- pkgs := listPackages(dir)
+ for {
+ prediction = complete.PredictFilesSet(listPackages(a)).Predict(a)
- files := make([]string, 0, len(pkgs))
- for _, p := range pkgs {
- files = append(files, p.Path)
- }
- return complete.PredictFilesSet(files).Predict(a)
-}
-
-func predictRunnableFiles(a complete.Args) (prediction []string) {
- dir := a.Directory()
- pkgs := listPackages(dir)
+ // if the number of prediction is not 1, we either have many results or
+ // have no results, so we return it.
+ if len(prediction) != 1 {
+ return
+ }
- files := []string{}
- for _, p := range pkgs {
- // filter non main pacakges
- if p.Name != "main" {
- continue
+ // if the result is only one item, we might want to recursively check
+ // for more accurate results.
+ if prediction[0] == a.Last {
+ return
}
- for _, f := range p.Files {
- path := filepath.Join(p.Path, f)
- if len(functionsInFile(path, reMainFunc)) > 0 {
- files = append(files, path)
- }
+
+ // only try deeper, if the one item is a directory
+ if stat, err := os.Stat(prediction[0]); err != nil || !stat.IsDir() {
+ return
}
+
+ a.Last = prediction[0]
}
- complete.Log("FILES: %s", files)
- return complete.PredictFilesSet(files).Predict(a)
}
-type pack struct {
- Name string
- Path string
- FilesString string
- Files []string
-}
+func listPackages(a complete.Args) (dirctories []string) {
+ dir := a.Directory()
+ complete.Log("listing packages in %s", dir)
+ // import current directory
+ pkg, err := build.ImportDir(dir, 0)
+ if err != nil {
+ complete.Log("failed importing directory %s: %s", dir, err)
+ return
+ }
+ dirctories = append(dirctories, pkg.Dir)
-func listPackages(dir string) (pkgs []pack) {
- dir = strings.TrimRight(dir, "/") + "/..."
- out, err := exec.Command("go", "list", "-f", goListFormat, dir).Output()
+ // import subdirectories
+ files, err := ioutil.ReadDir(dir)
if err != nil {
+ complete.Log("failed reading directory %s: %s", dir, err)
return
}
- lines := bytes.Split(out, []byte("\n"))
- for _, line := range lines {
- var p pack
- err := json.Unmarshal(line, &p)
+ for _, f := range files {
+ if !f.IsDir() {
+ continue
+ }
+ pkg, err := build.ImportDir(filepath.Join(dir, f.Name()), 0)
if err != nil {
+ complete.Log("failed importing subdirectory %s: %s", filepath.Join(dir, f.Name()), err)
continue
}
- // parse the FileString from a string "[file1 file2 file3]" to a list of files
- p.Files = strings.Split(strings.Trim(p.FilesString, "[]"), " ")
- pkgs = append(pkgs, p)
+ dirctories = append(dirctories, pkg.Dir)
}
return
}
diff --git a/gocomplete/tests_test.go b/gocomplete/tests_test.go
index a72f38f..5683d24 100644
--- a/gocomplete/tests_test.go
+++ b/gocomplete/tests_test.go
@@ -47,16 +47,6 @@ func TestPredictions(t *testing.T) {
predictor: complete.PredictFunc(predictPackages),
last: "X",
},
- {
- name: "predict runnable ok",
- predictor: complete.PredictFunc(predictRunnableFiles),
- completion: []string{"complete.go"},
- },
- {
- name: "predict runnable not found",
- predictor: complete.PredictFunc(predictRunnableFiles),
- last: "X",
- },
}
for _, tt := range tests {