-
-
Notifications
You must be signed in to change notification settings - Fork 43
/
funcs.go
75 lines (66 loc) · 1.67 KB
/
funcs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package golang
import (
"bufio"
"io/fs"
"os"
"path/filepath"
"regexp"
"strings"
"github.com/carapace-sh/carapace"
"github.com/carapace-sh/carapace/pkg/util"
)
func readFuncs(path string) []string {
// TODO optimize performance
if file, err := os.Open(path); err == nil {
defer file.Close()
r := regexp.MustCompile(`^func (\([^)]+\) )?(?P<func>[^([]+).*$`)
scanner := bufio.NewScanner(file)
names := make([]string, 0)
for scanner.Scan() {
if s := scanner.Text(); strings.HasPrefix(s, "func ") {
if matches := r.FindStringSubmatch(s); matches != nil {
names = append(names, matches[2])
}
}
}
return names
}
return []string{}
}
// ActionFuncs completes go funcs
//
// main
// ActionFuncs
func ActionFuncs(files ...string) carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
root := c.Dir
if path, err := util.FindReverse(root, "go.mod"); err == nil {
root = path
} else if path, err = util.FindReverse(root, ".git"); err == nil {
root = path
}
names := make(map[string]bool)
// TODO optimize performance - goroutines?
if len(files) == 0 {
filepath.Walk(filepath.Dir(root), func(path string, info fs.FileInfo, err error) error {
if !info.IsDir() && strings.HasSuffix(path, ".go") && !strings.HasSuffix(path, "_test.go") {
for _, name := range readFuncs(path) {
names[name] = true
}
}
return nil
})
} else {
for _, file := range files {
for _, name := range readFuncs(file) {
names[name] = true
}
}
}
vals := make([]string, 0, len(names))
for name := range names {
vals = append(vals, name)
}
return carapace.ActionValues(vals...)
})
}