From 04e78e42abea95d46d09f7de563ca50d78d3e108 Mon Sep 17 00:00:00 2001 From: Eyal Posener Date: Fri, 5 May 2017 16:57:22 +0300 Subject: Initial commit --- complete.go | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 complete.go (limited to 'complete.go') diff --git a/complete.go b/complete.go new file mode 100644 index 0000000..eedaa81 --- /dev/null +++ b/complete.go @@ -0,0 +1,73 @@ +package complete + +import ( + "fmt" + "os" + "strings" +) + +const ( + envComplete = "COMP_LINE" + envDebug = "COMP_DEBUG" +) + +type Completer struct { + Command + log func(format string, args ...interface{}) +} + +func New(c Command) *Completer { + return &Completer{ + Command: c, + log: logger(), + } +} + +func (c *Completer) Complete() { + args := getLine() + c.log("Completing args: %s", args) + + options := c.complete(args) + + c.log("Completion: %s", options) + output(options) +} + +func (c *Completer) complete(args []string) []string { + all, _ := c.options(args[:len(args)-1]) + return c.chooseRelevant(last(args), all) +} + +func (c *Completer) chooseRelevant(last string, list []string) (opts []string) { + if last == "" { + return list + } + for _, sub := range list { + if strings.HasPrefix(sub, last) { + opts = append(opts, sub) + } + } + return +} + +func getLine() []string { + line := os.Getenv(envComplete) + if line == "" { + panic("should be run as a complete script") + } + return strings.Split(line, " ") +} + +func last(args []string) (last string) { + if len(args) > 0 { + last = args[len(args)-1] + } + return +} + +func output(options []string) { + // stdout of program defines the complete options + for _, option := range options { + fmt.Println(option) + } +} -- cgit v1.2.3