summaryrefslogtreecommitdiff
path: root/command.go
diff options
context:
space:
mode:
authorEyal Posener <[email protected]>2017-05-05 16:57:22 +0300
committerEyal Posener <[email protected]>2017-05-05 18:01:08 +0300
commit04e78e42abea95d46d09f7de563ca50d78d3e108 (patch)
treef67a4877c550eb9eafc8eb6314ebbaffe2beb87b /command.go
Initial commit
Diffstat (limited to 'command.go')
-rw-r--r--command.go58
1 files changed, 58 insertions, 0 deletions
diff --git a/command.go b/command.go
new file mode 100644
index 0000000..48dece3
--- /dev/null
+++ b/command.go
@@ -0,0 +1,58 @@
+package complete
+
+type Command struct {
+ Sub map[string]Command
+ Flags map[string]FlagOptions
+}
+
+// options returns all available complete options for the given command
+// args are all except the last command line arguments relevant to the command
+func (c *Command) options(args []string) (options []string, only bool) {
+
+ // remove the first argument, which is the command name
+ args = args[1:]
+
+ // if prev has something that needs to follow it,
+ // it is the most relevant completion
+ if options, ok := c.Flags[last(args)]; ok && options.HasFollow {
+ return options.FollowsOptions, true
+ }
+
+ sub, options, only := c.searchSub(args)
+ if only {
+ return
+ }
+
+ // if no subcommand was entered in any of the args, add the
+ // subcommands as complete options.
+ if sub == "" {
+ options = append(options, c.subCommands()...)
+ }
+
+ // add global available complete options
+ for flag := range c.Flags {
+ options = append(options, flag)
+ }
+
+ return
+}
+
+func (c *Command) searchSub(args []string) (sub string, all []string, only bool) {
+ for i, arg := range args {
+ if cmd, ok := c.Sub[arg]; ok {
+ sub = arg
+ all, only = cmd.options(args[i:])
+ return
+ }
+ }
+ return "", nil, false
+}
+
+func (c *Command) subCommands() []string {
+ subs := make([]string, 0, len(c.Sub))
+ for sub := range c.Sub {
+ subs = append(subs, sub)
+ }
+ return subs
+}
+