]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/posener/complete/complete.go
deps: github.com/hashicorp/terraform@sdk-v0.11-with-go-modules
[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
14 "github.com/posener/complete/cmd"
15 "github.com/posener/complete/match"
16 )
17
18 const (
19 envComplete = "COMP_LINE"
20 envDebug = "COMP_DEBUG"
21 )
22
23 // Complete structs define completion for a command with CLI options
24 type Complete struct {
25 Command Command
26 cmd.CLI
27 Out io.Writer
28 }
29
30 // New creates a new complete command.
31 // name is the name of command we want to auto complete.
32 // IMPORTANT: it must be the same name - if the auto complete
33 // completes the 'go' command, name must be equal to "go".
34 // command is the struct of the command completion.
35 func New(name string, command Command) *Complete {
36 return &Complete{
37 Command: command,
38 CLI: cmd.CLI{Name: name},
39 Out: os.Stdout,
40 }
41 }
42
43 // Run runs the completion and add installation flags beforehand.
44 // The flags are added to the main flag CommandLine variable.
45 func (c *Complete) Run() bool {
46 c.AddFlags(nil)
47 flag.Parse()
48 return c.Complete()
49 }
50
51 // Complete a command from completion line in environment variable,
52 // and print out the complete options.
53 // returns success if the completion ran or if the cli matched
54 // any of the given flags, false otherwise
55 // For installation: it assumes that flags were added and parsed before
56 // it was called.
57 func (c *Complete) Complete() bool {
58 line, ok := getLine()
59 if !ok {
60 // make sure flags parsed,
61 // in case they were not added in the main program
62 return c.CLI.Run()
63 }
64 Log("Completing line: %s", line)
65 a := newArgs(line)
66 Log("Completing last field: %s", a.Last)
67 options := c.Command.Predict(a)
68 Log("Options: %s", options)
69
70 // filter only options that match the last argument
71 matches := []string{}
72 for _, option := range options {
73 if match.Prefix(option, a.Last) {
74 matches = append(matches, option)
75 }
76 }
77 Log("Matches: %s", matches)
78 c.output(matches)
79 return true
80 }
81
82 func getLine() (string, bool) {
83 line := os.Getenv(envComplete)
84 if line == "" {
85 return "", false
86 }
87 return line, true
88 }
89
90 func (c *Complete) output(options []string) {
91 // stdout of program defines the complete options
92 for _, option := range options {
93 fmt.Fprintln(c.Out, option)
94 }
95 }