]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/posener/complete/command.go
Merge pull request #27 from terraform-providers/go-modules-2019-02-22
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / posener / complete / command.go
1 package complete
2
3 // Command represents a command line
4 // It holds the data that enables auto completion of command line
5 // Command can also be a sub command.
6 type Command struct {
7 // Sub is map of sub commands of the current command
8 // The key refer to the sub command name, and the value is it's
9 // Command descriptive struct.
10 Sub Commands
11
12 // Flags is a map of flags that the command accepts.
13 // The key is the flag name, and the value is it's predictions.
14 Flags Flags
15
16 // GlobalFlags is a map of flags that the command accepts.
17 // Global flags that can appear also after a sub command.
18 GlobalFlags Flags
19
20 // Args are extra arguments that the command accepts, those who are
21 // given without any flag before.
22 Args Predictor
23 }
24
25 // Predict returns all possible predictions for args according to the command struct
26 func (c *Command) Predict(a Args) []string {
27 options, _ := c.predict(a)
28 return options
29 }
30
31 // Commands is the type of Sub member, it maps a command name to a command struct
32 type Commands map[string]Command
33
34 // Predict completion of sub command names names according to command line arguments
35 func (c Commands) Predict(a Args) (prediction []string) {
36 for sub := range c {
37 prediction = append(prediction, sub)
38 }
39 return
40 }
41
42 // Flags is the type Flags of the Flags member, it maps a flag name to the flag predictions.
43 type Flags map[string]Predictor
44
45 // Predict completion of flags names according to command line arguments
46 func (f Flags) Predict(a Args) (prediction []string) {
47 for flag := range f {
48 // If the flag starts with a hyphen, we avoid emitting the prediction
49 // unless the last typed arg contains a hyphen as well.
50 flagHyphenStart := len(flag) != 0 && flag[0] == '-'
51 lastHyphenStart := len(a.Last) != 0 && a.Last[0] == '-'
52 if flagHyphenStart && !lastHyphenStart {
53 continue
54 }
55 prediction = append(prediction, flag)
56 }
57 return
58 }
59
60 // predict options
61 // only is set to true if no more options are allowed to be returned
62 // those are in cases of special flag that has specific completion arguments,
63 // and other flags or sub commands can't come after it.
64 func (c *Command) predict(a Args) (options []string, only bool) {
65
66 // search sub commands for predictions first
67 subCommandFound := false
68 for i, arg := range a.Completed {
69 if cmd, ok := c.Sub[arg]; ok {
70 subCommandFound = true
71
72 // recursive call for sub command
73 options, only = cmd.predict(a.from(i))
74 if only {
75 return
76 }
77
78 // We matched so stop searching. Continuing to search can accidentally
79 // match a subcommand with current set of commands, see issue #46.
80 break
81 }
82 }
83
84 // if last completed word is a global flag that we need to complete
85 if predictor, ok := c.GlobalFlags[a.LastCompleted]; ok && predictor != nil {
86 Log("Predicting according to global flag %s", a.LastCompleted)
87 return predictor.Predict(a), true
88 }
89
90 options = append(options, c.GlobalFlags.Predict(a)...)
91
92 // if a sub command was entered, we won't add the parent command
93 // completions and we return here.
94 if subCommandFound {
95 return
96 }
97
98 // if last completed word is a command flag that we need to complete
99 if predictor, ok := c.Flags[a.LastCompleted]; ok && predictor != nil {
100 Log("Predicting according to flag %s", a.LastCompleted)
101 return predictor.Predict(a), true
102 }
103
104 options = append(options, c.Sub.Predict(a)...)
105 options = append(options, c.Flags.Predict(a)...)
106 if c.Args != nil {
107 options = append(options, c.Args.Predict(a)...)
108 }
109
110 return
111 }