]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/posener/complete/complete.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / posener / complete / complete.go
1 // Package complete provides a tool for bash writing bash completion in go.
2 //
3 // Writing bash completion scripts is a hard work. This package provides an easy way
4 // to create bash completion scripts for any command, and also an easy way to install/uninstall
5 // the completion of the command.
6 package complete
7
8 import (
9 "flag"
10 "fmt"
11 "io"
12 "os"
13 "strconv"
14
15 "github.com/posener/complete/cmd"
16 "github.com/posener/complete/match"
17 )
18
19 const (
20 envLine = "COMP_LINE"
21 envPoint = "COMP_POINT"
22 envDebug = "COMP_DEBUG"
23 )
24
25 // Complete structs define completion for a command with CLI options
26 type Complete struct {
27 Command Command
28 cmd.CLI
29 Out io.Writer
30 }
31
32 // New creates a new complete command.
33 // name is the name of command we want to auto complete.
34 // IMPORTANT: it must be the same name - if the auto complete
35 // completes the 'go' command, name must be equal to "go".
36 // command is the struct of the command completion.
37 func New(name string, command Command) *Complete {
38 return &Complete{
39 Command: command,
40 CLI: cmd.CLI{Name: name},
41 Out: os.Stdout,
42 }
43 }
44
45 // Run runs the completion and add installation flags beforehand.
46 // The flags are added to the main flag CommandLine variable.
47 func (c *Complete) Run() bool {
48 c.AddFlags(nil)
49 flag.Parse()
50 return c.Complete()
51 }
52
53 // Complete a command from completion line in environment variable,
54 // and print out the complete options.
55 // returns success if the completion ran or if the cli matched
56 // any of the given flags, false otherwise
57 // For installation: it assumes that flags were added and parsed before
58 // it was called.
59 func (c *Complete) Complete() bool {
60 line, point, ok := getEnv()
61 if !ok {
62 // make sure flags parsed,
63 // in case they were not added in the main program
64 return c.CLI.Run()
65 }
66
67 if point >= 0 && point < len(line) {
68 line = line[:point]
69 }
70
71 Log("Completing phrase: %s", line)
72 a := newArgs(line)
73 Log("Completing last field: %s", a.Last)
74 options := c.Command.Predict(a)
75 Log("Options: %s", options)
76
77 // filter only options that match the last argument
78 matches := []string{}
79 for _, option := range options {
80 if match.Prefix(option, a.Last) {
81 matches = append(matches, option)
82 }
83 }
84 Log("Matches: %s", matches)
85 c.output(matches)
86 return true
87 }
88
89 func getEnv() (line string, point int, ok bool) {
90 line = os.Getenv(envLine)
91 if line == "" {
92 return
93 }
94 point, err := strconv.Atoi(os.Getenv(envPoint))
95 if err != nil {
96 // If failed parsing point for some reason, set it to point
97 // on the end of the line.
98 Log("Failed parsing point %s: %v", os.Getenv(envPoint), err)
99 point = len(line)
100 }
101 return line, point, true
102 }
103
104 func (c *Complete) output(options []string) {
105 // stdout of program defines the complete options
106 for _, option := range options {
107 fmt.Fprintln(c.Out, option)
108 }
109 }