complete/complete.go

76 lines
1.8 KiB
Go
Raw Normal View History

2017-05-06 14:06:49 -05:00
// Package complete provides a tool for bash writing bash completion in go.
//
// Writing bash completion scripts is a hard work. This package provides an easy way
// to create bash completion scripts for any command, and also an easy way to install/uninstall
// the completion of the command.
2017-05-05 08:57:22 -05:00
package complete
import (
"fmt"
"os"
"strings"
2017-05-06 14:06:49 -05:00
"github.com/posener/complete/cmd"
2017-05-05 08:57:22 -05:00
)
const (
envComplete = "COMP_LINE"
envDebug = "COMP_DEBUG"
)
// Complete structs define completion for a command with CLI options
type Complete struct {
Command Command
cmd.CLI
}
// New creates a new complete command.
2017-05-06 23:59:42 -05:00
// name is the name of command we want to auto complete.
// IMPORTANT: it must be the same name - if the auto complete
// completes the 'go' command, name must be equal to "go".
// command is the struct of the command completion.
func New(name string, command Command) *Complete {
return &Complete{
Command: command,
CLI: cmd.CLI{Name: name},
}
}
// Run get a command, get the typed arguments from environment
// variable, and print out the complete options
// returns success if the completion ran or if the cli matched
// any of the given flags, false otherwise
func (c *Complete) Run() bool {
2017-05-11 10:49:59 -05:00
line, ok := getLine()
if !ok {
// make sure flags parsed,
// in case they were not added in the main program
return c.CLI.Run()
}
2017-05-11 10:49:59 -05:00
Log("Completing line: %s", line)
2017-05-05 08:57:22 -05:00
2017-05-11 10:49:59 -05:00
a := newArgs(line)
2017-05-11 12:28:31 -05:00
options := c.Command.Predict(a)
2017-05-05 08:57:22 -05:00
2017-05-05 16:25:27 -05:00
Log("Completion: %s", options)
2017-05-05 08:57:22 -05:00
output(options)
return true
2017-05-05 08:57:22 -05:00
}
func getLine() ([]string, bool) {
2017-05-05 08:57:22 -05:00
line := os.Getenv(envComplete)
if line == "" {
return nil, false
2017-05-05 08:57:22 -05:00
}
return strings.Split(line, " "), true
2017-05-05 08:57:22 -05:00
}
func output(options []string) {
Log("")
2017-05-05 08:57:22 -05:00
// stdout of program defines the complete options
for _, option := range options {
fmt.Println(option)
}
}