1 // Package complete provides a tool for bash writing bash completion in go.
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.
15 "github.com/posener/complete/cmd"
16 "github.com/posener/complete/match"
21 envPoint = "COMP_POINT"
22 envDebug = "COMP_DEBUG"
25 // Complete structs define completion for a command with CLI options
26 type Complete struct {
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 {
40 CLI: cmd.CLI{Name: name},
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 {
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
59 func (c *Complete) Complete() bool {
60 line, point, ok := getEnv()
62 // make sure flags parsed,
63 // in case they were not added in the main program
67 if point >= 0 && point < len(line) {
71 Log("Completing phrase: %s", line)
73 Log("Completing last field: %s", a.Last)
74 options := c.Command.Predict(a)
75 Log("Options: %s", options)
77 // filter only options that match the last argument
79 for _, option := range options {
80 if match.Prefix(option, a.Last) {
81 matches = append(matches, option)
84 Log("Matches: %s", matches)
89 func getEnv() (line string, point int, ok bool) {
90 line = os.Getenv(envLine)
94 point, err := strconv.Atoi(os.Getenv(envPoint))
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)
101 return line, point, true
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)