github.com/divan/complete@v0.0.0-20170515130636-337e95201af7/complete.go (about)

     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  	"fmt"
    10  	"os"
    11  	"strings"
    12  
    13  	"github.com/posener/complete/cmd"
    14  )
    15  
    16  const (
    17  	envComplete = "COMP_LINE"
    18  	envDebug    = "COMP_DEBUG"
    19  )
    20  
    21  // Complete structs define completion for a command with CLI options
    22  type Complete struct {
    23  	Command Command
    24  	cmd.CLI
    25  }
    26  
    27  // New creates a new complete command.
    28  // name is the name of command we want to auto complete.
    29  // IMPORTANT: it must be the same name - if the auto complete
    30  // completes the 'go' command, name must be equal to "go".
    31  // command is the struct of the command completion.
    32  func New(name string, command Command) *Complete {
    33  	return &Complete{
    34  		Command: command,
    35  		CLI:     cmd.CLI{Name: name},
    36  	}
    37  }
    38  
    39  // Run get a command, get the typed arguments from environment
    40  // variable, and print out the complete options
    41  // returns success if the completion ran or if the cli matched
    42  // any of the given flags, false otherwise
    43  func (c *Complete) Run() bool {
    44  	line, ok := getLine()
    45  	if !ok {
    46  		// make sure flags parsed,
    47  		// in case they were not added in the main program
    48  		return c.CLI.Run()
    49  	}
    50  	Log("Completing line: %s", line)
    51  
    52  	a := newArgs(line)
    53  
    54  	options := c.Command.Predict(a)
    55  
    56  	Log("Completion: %s", options)
    57  	output(options)
    58  	return true
    59  }
    60  
    61  func getLine() ([]string, bool) {
    62  	line := os.Getenv(envComplete)
    63  	if line == "" {
    64  		return nil, false
    65  	}
    66  	return strings.Split(line, " "), true
    67  }
    68  
    69  func output(options []string) {
    70  	Log("")
    71  	// stdout of program defines the complete options
    72  	for _, option := range options {
    73  		fmt.Println(option)
    74  	}
    75  }