forked from carapace-sh/carapace
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinternalActions.go
150 lines (131 loc) · 4.41 KB
/
internalActions.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package carapace
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/rsteube/carapace/internal/env"
"github.com/rsteube/carapace/internal/pflagfork"
"github.com/rsteube/carapace/pkg/style"
"github.com/rsteube/carapace/pkg/util"
"github.com/spf13/cobra"
)
func actionPath(fileSuffixes []string, dirOnly bool) Action {
return ActionCallback(func(c Context) Action {
if len(c.Value) == 2 && util.HasVolumePrefix(c.Value) {
// TODO should be fixed in Abs or wherever this is happening
return ActionValues(c.Value + "/") // prevent `C:` -> `C:.`
}
abs, err := c.Abs(c.Value)
if err != nil {
return ActionMessage(err.Error())
}
displayFolder := filepath.ToSlash(filepath.Dir(c.Value))
if displayFolder == "." {
displayFolder = ""
} else if !strings.HasSuffix(displayFolder, "/") {
displayFolder = displayFolder + "/"
}
actualFolder := filepath.ToSlash(filepath.Dir(abs))
files, err := ioutil.ReadDir(actualFolder)
if err != nil {
return ActionMessage(err.Error())
}
showHidden := !strings.HasSuffix(abs, "/") && strings.HasPrefix(filepath.Base(abs), ".")
vals := make([]string, 0, len(files)*2)
for _, file := range files {
if !showHidden && strings.HasPrefix(file.Name(), ".") {
continue
}
resolvedFile := file
if resolved, err := filepath.EvalSymlinks(actualFolder + file.Name()); err == nil {
if stat, err := os.Stat(resolved); err == nil {
resolvedFile = stat
}
}
if resolvedFile.IsDir() {
vals = append(vals, displayFolder+file.Name()+"/", style.ForPath(filepath.Clean(actualFolder+"/"+file.Name()+"/"), c))
} else if !dirOnly {
if len(fileSuffixes) == 0 {
fileSuffixes = []string{""}
}
for _, suffix := range fileSuffixes {
if strings.HasSuffix(file.Name(), suffix) {
vals = append(vals, displayFolder+file.Name(), style.ForPath(filepath.Clean(actualFolder+"/"+file.Name()), c))
break
}
}
}
}
if strings.HasPrefix(c.Value, "./") {
return ActionStyledValues(vals...).Invoke(Context{}).Prefix("./").ToA()
}
return ActionStyledValues(vals...)
})
}
func actionFlags(cmd *cobra.Command) Action {
return ActionCallback(func(c Context) Action {
cmd.InitDefaultHelpFlag()
cmd.InitDefaultVersionFlag()
flagSet := pflagfork.FlagSet{FlagSet: cmd.Flags()}
isShorthandSeries := flagSet.IsShorthandSeries(c.Value)
nospace := make([]rune, 0)
vals := make([]string, 0)
flagSet.VisitAll(func(f *pflagfork.Flag) {
switch {
case f.Hidden && !env.Hidden():
return // skip hidden flags
case f.Deprecated != "":
return // skip deprecated flags
case f.Changed && !f.IsRepeatable():
return // don't repeat flag
case flagSet.IsMutuallyExclusive(f.Flag):
return // skip flag of group already set
}
if isShorthandSeries {
if f.Shorthand != "" && f.ShorthandDeprecated == "" {
for _, shorthand := range c.Value[1:] {
if shorthandFlag := cmd.Flags().ShorthandLookup(string(shorthand)); shorthandFlag != nil && shorthandFlag.Value.Type() != "bool" && shorthandFlag.Value.Type() != "count" && shorthandFlag.NoOptDefVal == "" {
return // abort shorthand flag series if a previous one is not bool or count and requires an argument (no default value)
}
}
vals = append(vals, f.Shorthand, f.Usage, f.Style())
if f.IsOptarg() {
nospace = append(nospace, []rune(f.Shorthand)[0])
}
}
} else {
switch f.Mode() {
case pflagfork.NameAsShorthand:
vals = append(vals, "-"+f.Name, f.Usage, f.Style())
case pflagfork.Default:
vals = append(vals, "--"+f.Name, f.Usage, f.Style())
}
if f.Shorthand != "" && f.ShorthandDeprecated == "" {
vals = append(vals, "-"+f.Shorthand, f.Usage, f.Style())
}
}
})
if isShorthandSeries {
if len(nospace) > 0 {
return ActionStyledValuesDescribed(vals...).Prefix(c.Value).NoSpace(nospace...)
}
return ActionStyledValuesDescribed(vals...).Prefix(c.Value)
}
return ActionStyledValuesDescribed(vals...).MultiParts(".") // multiparts completion for flags grouped with `.`
}).Tag("flags")
}
func initHelpCompletion(cmd *cobra.Command) {
helpCmd, _, err := cmd.Find([]string{"help"})
if err != nil {
return
}
if helpCmd.Name() != "help" ||
helpCmd.Short != "Help about any command" ||
!strings.HasPrefix(helpCmd.Long, `Help provides help for any command in the application.`) {
return
}
Gen(helpCmd).PositionalAnyCompletion(
ActionCommands(cmd),
)
}