add vendor

This commit is contained in:
Malar Invention
2022-04-03 09:37:16 +05:30
parent f96ba5f172
commit 00ebcd295e
2339 changed files with 705854 additions and 0 deletions

4
vendor/github.com/posener/complete/.gitignore generated vendored Normal file
View File

@ -0,0 +1,4 @@
.idea
coverage.txt
gocomplete/gocomplete
example/self/self

16
vendor/github.com/posener/complete/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,16 @@
language: go
sudo: false
go:
- 1.11
- 1.10.x
- 1.9
- 1.8
before_install:
- go get -u -t ./...
script:
- GO111MODULE=on ./test.sh
after_success:
- bash <(curl -s https://codecov.io/bash)

21
vendor/github.com/posener/complete/LICENSE.txt generated vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License
Copyright (c) 2017 Eyal Posener
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

111
vendor/github.com/posener/complete/args.go generated vendored Normal file
View File

@ -0,0 +1,111 @@
package complete
import (
"os"
"path/filepath"
"strings"
"unicode"
)
// Args describes command line arguments
type Args struct {
// All lists of all arguments in command line (not including the command itself)
All []string
// Completed lists of all completed arguments in command line,
// If the last one is still being typed - no space after it,
// it won't appear in this list of arguments.
Completed []string
// Last argument in command line, the one being typed, if the last
// character in the command line is a space, this argument will be empty,
// otherwise this would be the last word.
Last string
// LastCompleted is the last argument that was fully typed.
// If the last character in the command line is space, this would be the
// last word, otherwise, it would be the word before that.
LastCompleted string
}
// Directory gives the directory of the current written
// last argument if it represents a file name being written.
// in case that it is not, we fall back to the current directory.
func (a Args) Directory() string {
if info, err := os.Stat(a.Last); err == nil && info.IsDir() {
return fixPathForm(a.Last, a.Last)
}
dir := filepath.Dir(a.Last)
if info, err := os.Stat(dir); err != nil || !info.IsDir() {
return "./"
}
return fixPathForm(a.Last, dir)
}
func newArgs(line string) Args {
var (
all []string
completed []string
)
parts := splitFields(line)
if len(parts) > 0 {
all = parts[1:]
completed = removeLast(parts[1:])
}
return Args{
All: all,
Completed: completed,
Last: last(parts),
LastCompleted: last(completed),
}
}
// splitFields returns a list of fields from the given command line.
// If the last character is space, it appends an empty field in the end
// indicating that the field before it was completed.
// If the last field is of the form "a=b", it splits it to two fields: "a", "b",
// So it can be completed.
func splitFields(line string) []string {
parts := strings.Fields(line)
// Add empty field if the last field was completed.
if len(line) > 0 && unicode.IsSpace(rune(line[len(line)-1])) {
parts = append(parts, "")
}
// Treat the last field if it is of the form "a=b"
parts = splitLastEqual(parts)
return parts
}
func splitLastEqual(line []string) []string {
if len(line) == 0 {
return line
}
parts := strings.Split(line[len(line)-1], "=")
return append(line[:len(line)-1], parts...)
}
func (a Args) from(i int) Args {
if i > len(a.All) {
i = len(a.All)
}
a.All = a.All[i:]
if i > len(a.Completed) {
i = len(a.Completed)
}
a.Completed = a.Completed[i:]
return a
}
func removeLast(a []string) []string {
if len(a) > 0 {
return a[:len(a)-1]
}
return a
}
func last(args []string) string {
if len(args) == 0 {
return ""
}
return args[len(args)-1]
}

128
vendor/github.com/posener/complete/cmd/cmd.go generated vendored Normal file
View File

@ -0,0 +1,128 @@
// Package cmd used for command line options for the complete tool
package cmd
import (
"errors"
"flag"
"fmt"
"os"
"strings"
"github.com/posener/complete/cmd/install"
)
// CLI for command line
type CLI struct {
Name string
InstallName string
UninstallName string
install bool
uninstall bool
yes bool
}
const (
defaultInstallName = "install"
defaultUninstallName = "uninstall"
)
// Run is used when running complete in command line mode.
// this is used when the complete is not completing words, but to
// install it or uninstall it.
func (f *CLI) Run() bool {
err := f.validate()
if err != nil {
os.Stderr.WriteString(err.Error() + "\n")
os.Exit(1)
}
switch {
case f.install:
f.prompt()
err = install.Install(f.Name)
case f.uninstall:
f.prompt()
err = install.Uninstall(f.Name)
default:
// non of the action flags matched,
// returning false should make the real program execute
return false
}
if err != nil {
fmt.Printf("%s failed! %s\n", f.action(), err)
os.Exit(3)
}
fmt.Println("Done!")
return true
}
// prompt use for approval
// exit if approval was not given
func (f *CLI) prompt() {
defer fmt.Println(f.action() + "ing...")
if f.yes {
return
}
fmt.Printf("%s completion for %s? ", f.action(), f.Name)
var answer string
fmt.Scanln(&answer)
switch strings.ToLower(answer) {
case "y", "yes":
return
default:
fmt.Println("Cancelling...")
os.Exit(1)
}
}
// AddFlags adds the CLI flags to the flag set.
// If flags is nil, the default command line flags will be taken.
// Pass non-empty strings as installName and uninstallName to override the default
// flag names.
func (f *CLI) AddFlags(flags *flag.FlagSet) {
if flags == nil {
flags = flag.CommandLine
}
if f.InstallName == "" {
f.InstallName = defaultInstallName
}
if f.UninstallName == "" {
f.UninstallName = defaultUninstallName
}
if flags.Lookup(f.InstallName) == nil {
flags.BoolVar(&f.install, f.InstallName, false,
fmt.Sprintf("Install completion for %s command", f.Name))
}
if flags.Lookup(f.UninstallName) == nil {
flags.BoolVar(&f.uninstall, f.UninstallName, false,
fmt.Sprintf("Uninstall completion for %s command", f.Name))
}
if flags.Lookup("y") == nil {
flags.BoolVar(&f.yes, "y", false, "Don't prompt user for typing 'yes' when installing completion")
}
}
// validate the CLI
func (f *CLI) validate() error {
if f.install && f.uninstall {
return errors.New("Install and uninstall are mutually exclusive")
}
return nil
}
// action name according to the CLI values.
func (f *CLI) action() string {
switch {
case f.install:
return "Install"
case f.uninstall:
return "Uninstall"
default:
return "unknown"
}
}

32
vendor/github.com/posener/complete/cmd/install/bash.go generated vendored Normal file
View File

@ -0,0 +1,32 @@
package install
import "fmt"
// (un)install in bash
// basically adds/remove from .bashrc:
//
// complete -C </path/to/completion/command> <command>
type bash struct {
rc string
}
func (b bash) Install(cmd, bin string) error {
completeCmd := b.cmd(cmd, bin)
if lineInFile(b.rc, completeCmd) {
return fmt.Errorf("already installed in %s", b.rc)
}
return appendToFile(b.rc, completeCmd)
}
func (b bash) Uninstall(cmd, bin string) error {
completeCmd := b.cmd(cmd, bin)
if !lineInFile(b.rc, completeCmd) {
return fmt.Errorf("does not installed in %s", b.rc)
}
return removeFromFile(b.rc, completeCmd)
}
func (bash) cmd(cmd, bin string) string {
return fmt.Sprintf("complete -C %s %s", bin, cmd)
}

56
vendor/github.com/posener/complete/cmd/install/fish.go generated vendored Normal file
View File

@ -0,0 +1,56 @@
package install
import (
"bytes"
"fmt"
"os"
"path/filepath"
"text/template"
)
// (un)install in fish
type fish struct {
configDir string
}
func (f fish) Install(cmd, bin string) error {
completionFile := filepath.Join(f.configDir, "completions", fmt.Sprintf("%s.fish", cmd))
completeCmd, err := f.cmd(cmd, bin)
if err != nil {
return err
}
if _, err := os.Stat(completionFile); err == nil {
return fmt.Errorf("already installed at %s", completionFile)
}
return createFile(completionFile, completeCmd)
}
func (f fish) Uninstall(cmd, bin string) error {
completionFile := filepath.Join(f.configDir, "completions", fmt.Sprintf("%s.fish", cmd))
if _, err := os.Stat(completionFile); err != nil {
return fmt.Errorf("does not installed in %s", f.configDir)
}
return os.Remove(completionFile)
}
func (f fish) cmd(cmd, bin string) (string, error) {
var buf bytes.Buffer
params := struct{ Cmd, Bin string }{cmd, bin}
tmpl := template.Must(template.New("cmd").Parse(`
function __complete_{{.Cmd}}
set -lx COMP_LINE (string join ' ' (commandline -o))
test (commandline -ct) = ""
and set COMP_LINE "$COMP_LINE "
{{.Bin}}
end
complete -c {{.Cmd}} -a "(__complete_{{.Cmd}})"
`))
err := tmpl.Execute(&buf, params)
if err != nil {
return "", err
}
return buf.String(), nil
}

View File

@ -0,0 +1,119 @@
package install
import (
"errors"
"os"
"os/user"
"path/filepath"
"github.com/hashicorp/go-multierror"
)
type installer interface {
Install(cmd, bin string) error
Uninstall(cmd, bin string) error
}
// Install complete command given:
// cmd: is the command name
func Install(cmd string) error {
is := installers()
if len(is) == 0 {
return errors.New("Did not find any shells to install")
}
bin, err := getBinaryPath()
if err != nil {
return err
}
for _, i := range is {
errI := i.Install(cmd, bin)
if errI != nil {
err = multierror.Append(err, errI)
}
}
return err
}
// Uninstall complete command given:
// cmd: is the command name
func Uninstall(cmd string) error {
is := installers()
if len(is) == 0 {
return errors.New("Did not find any shells to uninstall")
}
bin, err := getBinaryPath()
if err != nil {
return err
}
for _, i := range is {
errI := i.Uninstall(cmd, bin)
if errI != nil {
err = multierror.Append(err, errI)
}
}
return err
}
func installers() (i []installer) {
for _, rc := range [...]string{".bashrc", ".bash_profile", ".bash_login", ".profile"} {
if f := rcFile(rc); f != "" {
i = append(i, bash{f})
break
}
}
if f := rcFile(".zshrc"); f != "" {
i = append(i, zsh{f})
}
if d := fishConfigDir(); d != "" {
i = append(i, fish{d})
}
return
}
func fishConfigDir() string {
configDir := filepath.Join(getConfigHomePath(), "fish")
if configDir == "" {
return ""
}
if info, err := os.Stat(configDir); err != nil || !info.IsDir() {
return ""
}
return configDir
}
func getConfigHomePath() string {
u, err := user.Current()
if err != nil {
return ""
}
configHome := os.Getenv("XDG_CONFIG_HOME")
if configHome == "" {
return filepath.Join(u.HomeDir, ".config")
}
return configHome
}
func getBinaryPath() (string, error) {
bin, err := os.Executable()
if err != nil {
return "", err
}
return filepath.Abs(bin)
}
func rcFile(name string) string {
u, err := user.Current()
if err != nil {
return ""
}
path := filepath.Join(u.HomeDir, name)
if _, err := os.Stat(path); err != nil {
return ""
}
return path
}

140
vendor/github.com/posener/complete/cmd/install/utils.go generated vendored Normal file
View File

@ -0,0 +1,140 @@
package install
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
)
func lineInFile(name string, lookFor string) bool {
f, err := os.Open(name)
if err != nil {
return false
}
defer f.Close()
r := bufio.NewReader(f)
prefix := []byte{}
for {
line, isPrefix, err := r.ReadLine()
if err == io.EOF {
return false
}
if err != nil {
return false
}
if isPrefix {
prefix = append(prefix, line...)
continue
}
line = append(prefix, line...)
if string(line) == lookFor {
return true
}
prefix = prefix[:0]
}
}
func createFile(name string, content string) error {
// make sure file directory exists
if err := os.MkdirAll(filepath.Dir(name), 0775); err != nil {
return err
}
// create the file
f, err := os.Create(name)
if err != nil {
return err
}
defer f.Close()
// write file content
_, err = f.WriteString(fmt.Sprintf("%s\n", content))
return err
}
func appendToFile(name string, content string) error {
f, err := os.OpenFile(name, os.O_RDWR|os.O_APPEND, 0)
if err != nil {
return err
}
defer f.Close()
_, err = f.WriteString(fmt.Sprintf("\n%s\n", content))
return err
}
func removeFromFile(name string, content string) error {
backup := name + ".bck"
err := copyFile(name, backup)
if err != nil {
return err
}
temp, err := removeContentToTempFile(name, content)
if err != nil {
return err
}
err = copyFile(temp, name)
if err != nil {
return err
}
return os.Remove(backup)
}
func removeContentToTempFile(name, content string) (string, error) {
rf, err := os.Open(name)
if err != nil {
return "", err
}
defer rf.Close()
wf, err := ioutil.TempFile("/tmp", "complete-")
if err != nil {
return "", err
}
defer wf.Close()
r := bufio.NewReader(rf)
prefix := []byte{}
for {
line, isPrefix, err := r.ReadLine()
if err == io.EOF {
break
}
if err != nil {
return "", err
}
if isPrefix {
prefix = append(prefix, line...)
continue
}
line = append(prefix, line...)
str := string(line)
if str == content {
continue
}
_, err = wf.WriteString(str + "\n")
if err != nil {
return "", err
}
prefix = prefix[:0]
}
return wf.Name(), nil
}
func copyFile(src string, dst string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, in)
return err
}

39
vendor/github.com/posener/complete/cmd/install/zsh.go generated vendored Normal file
View File

@ -0,0 +1,39 @@
package install
import "fmt"
// (un)install in zsh
// basically adds/remove from .zshrc:
//
// autoload -U +X bashcompinit && bashcompinit"
// complete -C </path/to/completion/command> <command>
type zsh struct {
rc string
}
func (z zsh) Install(cmd, bin string) error {
completeCmd := z.cmd(cmd, bin)
if lineInFile(z.rc, completeCmd) {
return fmt.Errorf("already installed in %s", z.rc)
}
bashCompInit := "autoload -U +X bashcompinit && bashcompinit"
if !lineInFile(z.rc, bashCompInit) {
completeCmd = bashCompInit + "\n" + completeCmd
}
return appendToFile(z.rc, completeCmd)
}
func (z zsh) Uninstall(cmd, bin string) error {
completeCmd := z.cmd(cmd, bin)
if !lineInFile(z.rc, completeCmd) {
return fmt.Errorf("does not installed in %s", z.rc)
}
return removeFromFile(z.rc, completeCmd)
}
func (zsh) cmd(cmd, bin string) string {
return fmt.Sprintf("complete -o nospace -C %s %s", bin, cmd)
}

111
vendor/github.com/posener/complete/command.go generated vendored Normal file
View File

@ -0,0 +1,111 @@
package complete
// Command represents a command line
// It holds the data that enables auto completion of command line
// Command can also be a sub command.
type Command struct {
// Sub is map of sub commands of the current command
// The key refer to the sub command name, and the value is it's
// Command descriptive struct.
Sub Commands
// Flags is a map of flags that the command accepts.
// The key is the flag name, and the value is it's predictions.
Flags Flags
// GlobalFlags is a map of flags that the command accepts.
// Global flags that can appear also after a sub command.
GlobalFlags Flags
// Args are extra arguments that the command accepts, those who are
// given without any flag before.
Args Predictor
}
// Predict returns all possible predictions for args according to the command struct
func (c *Command) Predict(a Args) []string {
options, _ := c.predict(a)
return options
}
// Commands is the type of Sub member, it maps a command name to a command struct
type Commands map[string]Command
// Predict completion of sub command names names according to command line arguments
func (c Commands) Predict(a Args) (prediction []string) {
for sub := range c {
prediction = append(prediction, sub)
}
return
}
// Flags is the type Flags of the Flags member, it maps a flag name to the flag predictions.
type Flags map[string]Predictor
// Predict completion of flags names according to command line arguments
func (f Flags) Predict(a Args) (prediction []string) {
for flag := range f {
// If the flag starts with a hyphen, we avoid emitting the prediction
// unless the last typed arg contains a hyphen as well.
flagHyphenStart := len(flag) != 0 && flag[0] == '-'
lastHyphenStart := len(a.Last) != 0 && a.Last[0] == '-'
if flagHyphenStart && !lastHyphenStart {
continue
}
prediction = append(prediction, flag)
}
return
}
// predict options
// only is set to true if no more options are allowed to be returned
// those are in cases of special flag that has specific completion arguments,
// and other flags or sub commands can't come after it.
func (c *Command) predict(a Args) (options []string, only bool) {
// search sub commands for predictions first
subCommandFound := false
for i, arg := range a.Completed {
if cmd, ok := c.Sub[arg]; ok {
subCommandFound = true
// recursive call for sub command
options, only = cmd.predict(a.from(i))
if only {
return
}
// We matched so stop searching. Continuing to search can accidentally
// match a subcommand with current set of commands, see issue #46.
break
}
}
// if last completed word is a global flag that we need to complete
if predictor, ok := c.GlobalFlags[a.LastCompleted]; ok && predictor != nil {
Log("Predicting according to global flag %s", a.LastCompleted)
return predictor.Predict(a), true
}
options = append(options, c.GlobalFlags.Predict(a)...)
// if a sub command was entered, we won't add the parent command
// completions and we return here.
if subCommandFound {
return
}
// if last completed word is a command flag that we need to complete
if predictor, ok := c.Flags[a.LastCompleted]; ok && predictor != nil {
Log("Predicting according to flag %s", a.LastCompleted)
return predictor.Predict(a), true
}
options = append(options, c.Sub.Predict(a)...)
options = append(options, c.Flags.Predict(a)...)
if c.Args != nil {
options = append(options, c.Args.Predict(a)...)
}
return
}

109
vendor/github.com/posener/complete/complete.go generated vendored Normal file
View File

@ -0,0 +1,109 @@
// 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.
package complete
import (
"flag"
"fmt"
"io"
"os"
"strconv"
"github.com/posener/complete/cmd"
"github.com/posener/complete/match"
)
const (
envLine = "COMP_LINE"
envPoint = "COMP_POINT"
envDebug = "COMP_DEBUG"
)
// Complete structs define completion for a command with CLI options
type Complete struct {
Command Command
cmd.CLI
Out io.Writer
}
// New creates a new complete command.
// 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},
Out: os.Stdout,
}
}
// Run runs the completion and add installation flags beforehand.
// The flags are added to the main flag CommandLine variable.
func (c *Complete) Run() bool {
c.AddFlags(nil)
flag.Parse()
return c.Complete()
}
// Complete a command from completion line in 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
// For installation: it assumes that flags were added and parsed before
// it was called.
func (c *Complete) Complete() bool {
line, point, ok := getEnv()
if !ok {
// make sure flags parsed,
// in case they were not added in the main program
return c.CLI.Run()
}
if point >= 0 && point < len(line) {
line = line[:point]
}
Log("Completing phrase: %s", line)
a := newArgs(line)
Log("Completing last field: %s", a.Last)
options := c.Command.Predict(a)
Log("Options: %s", options)
// filter only options that match the last argument
matches := []string{}
for _, option := range options {
if match.Prefix(option, a.Last) {
matches = append(matches, option)
}
}
Log("Matches: %s", matches)
c.output(matches)
return true
}
func getEnv() (line string, point int, ok bool) {
line = os.Getenv(envLine)
if line == "" {
return
}
point, err := strconv.Atoi(os.Getenv(envPoint))
if err != nil {
// If failed parsing point for some reason, set it to point
// on the end of the line.
Log("Failed parsing point %s: %v", os.Getenv(envPoint), err)
point = len(line)
}
return line, point, true
}
func (c *Complete) output(options []string) {
// stdout of program defines the complete options
for _, option := range options {
fmt.Fprintln(c.Out, option)
}
}

22
vendor/github.com/posener/complete/log.go generated vendored Normal file
View File

@ -0,0 +1,22 @@
package complete
import (
"io/ioutil"
"log"
"os"
)
// Log is used for debugging purposes
// since complete is running on tab completion, it is nice to
// have logs to the stderr (when writing your own completer)
// to write logs, set the COMP_DEBUG environment variable and
// use complete.Log in the complete program
var Log = getLogger()
func getLogger() func(format string, args ...interface{}) {
var logfile = ioutil.Discard
if os.Getenv(envDebug) != "" {
logfile = os.Stderr
}
return log.New(logfile, "complete ", log.Flags()).Printf
}

19
vendor/github.com/posener/complete/match/file.go generated vendored Normal file
View File

@ -0,0 +1,19 @@
package match
import "strings"
// File returns true if prefix can match the file
func File(file, prefix string) bool {
// special case for current directory completion
if file == "./" && (prefix == "." || prefix == "") {
return true
}
if prefix == "." && strings.HasPrefix(file, ".") {
return true
}
file = strings.TrimPrefix(file, "./")
prefix = strings.TrimPrefix(prefix, "./")
return strings.HasPrefix(file, prefix)
}

6
vendor/github.com/posener/complete/match/match.go generated vendored Normal file
View File

@ -0,0 +1,6 @@
package match
// Match matches two strings
// it is used for comparing a term to the last typed
// word, the prefix, and see if it is a possible auto complete option.
type Match func(term, prefix string) bool

9
vendor/github.com/posener/complete/match/prefix.go generated vendored Normal file
View File

@ -0,0 +1,9 @@
package match
import "strings"
// Prefix is a simple Matcher, if the word is it's prefix, there is a match
// Match returns true if a has the prefix as prefix
func Prefix(long, prefix string) bool {
return strings.HasPrefix(long, prefix)
}

41
vendor/github.com/posener/complete/predict.go generated vendored Normal file
View File

@ -0,0 +1,41 @@
package complete
// Predictor implements a predict method, in which given
// command line arguments returns a list of options it predicts.
type Predictor interface {
Predict(Args) []string
}
// PredictOr unions two predicate functions, so that the result predicate
// returns the union of their predication
func PredictOr(predictors ...Predictor) Predictor {
return PredictFunc(func(a Args) (prediction []string) {
for _, p := range predictors {
if p == nil {
continue
}
prediction = append(prediction, p.Predict(a)...)
}
return
})
}
// PredictFunc determines what terms can follow a command or a flag
// It is used for auto completion, given last - the last word in the already
// in the command line, what words can complete it.
type PredictFunc func(Args) []string
// Predict invokes the predict function and implements the Predictor interface
func (p PredictFunc) Predict(a Args) []string {
if p == nil {
return nil
}
return p(a)
}
// PredictNothing does not expect anything after.
var PredictNothing Predictor
// PredictAnything expects something, but nothing particular, such as a number
// or arbitrary name.
var PredictAnything = PredictFunc(func(Args) []string { return nil })

108
vendor/github.com/posener/complete/predict_files.go generated vendored Normal file
View File

@ -0,0 +1,108 @@
package complete
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/posener/complete/match"
)
// PredictDirs will search for directories in the given started to be typed
// path, if no path was started to be typed, it will complete to directories
// in the current working directory.
func PredictDirs(pattern string) Predictor {
return files(pattern, false)
}
// PredictFiles will search for files matching the given pattern in the started to
// be typed path, if no path was started to be typed, it will complete to files that
// match the pattern in the current working directory.
// To match any file, use "*" as pattern. To match go files use "*.go", and so on.
func PredictFiles(pattern string) Predictor {
return files(pattern, true)
}
func files(pattern string, allowFiles bool) PredictFunc {
// search for files according to arguments,
// if only one directory has matched the result, search recursively into
// this directory to give more results.
return func(a Args) (prediction []string) {
prediction = predictFiles(a, pattern, allowFiles)
// if the number of prediction is not 1, we either have many results or
// have no results, so we return it.
if len(prediction) != 1 {
return
}
// only try deeper, if the one item is a directory
if stat, err := os.Stat(prediction[0]); err != nil || !stat.IsDir() {
return
}
a.Last = prediction[0]
return predictFiles(a, pattern, allowFiles)
}
}
func predictFiles(a Args, pattern string, allowFiles bool) []string {
if strings.HasSuffix(a.Last, "/..") {
return nil
}
dir := a.Directory()
files := listFiles(dir, pattern, allowFiles)
// add dir if match
files = append(files, dir)
return PredictFilesSet(files).Predict(a)
}
// PredictFilesSet predict according to file rules to a given set of file names
func PredictFilesSet(files []string) PredictFunc {
return func(a Args) (prediction []string) {
// add all matching files to prediction
for _, f := range files {
f = fixPathForm(a.Last, f)
// test matching of file to the argument
if match.File(f, a.Last) {
prediction = append(prediction, f)
}
}
return
}
}
func listFiles(dir, pattern string, allowFiles bool) []string {
// set of all file names
m := map[string]bool{}
// list files
if files, err := filepath.Glob(filepath.Join(dir, pattern)); err == nil {
for _, f := range files {
if stat, err := os.Stat(f); err != nil || stat.IsDir() || allowFiles {
m[f] = true
}
}
}
// list directories
if dirs, err := ioutil.ReadDir(dir); err == nil {
for _, d := range dirs {
if d.IsDir() {
m[filepath.Join(dir, d.Name())] = true
}
}
}
list := make([]string, 0, len(m))
for k := range m {
list = append(list, k)
}
return list
}

12
vendor/github.com/posener/complete/predict_set.go generated vendored Normal file
View File

@ -0,0 +1,12 @@
package complete
// PredictSet expects specific set of terms, given in the options argument.
func PredictSet(options ...string) Predictor {
return predictSet(options)
}
type predictSet []string
func (p predictSet) Predict(a Args) []string {
return p
}

118
vendor/github.com/posener/complete/readme.md generated vendored Normal file
View File

@ -0,0 +1,118 @@
# complete
A tool for bash writing bash completion in go, and bash completion for the go command line.
[![Build Status](https://travis-ci.org/posener/complete.svg?branch=master)](https://travis-ci.org/posener/complete)
[![codecov](https://codecov.io/gh/posener/complete/branch/master/graph/badge.svg)](https://codecov.io/gh/posener/complete)
[![golangci](https://golangci.com/badges/github.com/posener/complete.svg)](https://golangci.com/r/github.com/posener/complete)
[![GoDoc](https://godoc.org/github.com/posener/complete?status.svg)](http://godoc.org/github.com/posener/complete)
[![Go Report Card](https://goreportcard.com/badge/github.com/posener/complete)](https://goreportcard.com/report/github.com/posener/complete)
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.
## go command bash completion
In [gocomplete](./gocomplete) there is an example for bash completion for the `go` command line.
This is an example that uses the `complete` package on the `go` command - the `complete` package
can also be used to implement any completions, see [Usage](#usage).
### Install
1. Type in your shell:
```
go get -u github.com/posener/complete/gocomplete
gocomplete -install
```
2. Restart your shell
Uninstall by `gocomplete -uninstall`
### Features
- Complete `go` command, including sub commands and all flags.
- Complete packages names or `.go` files when necessary.
- Complete test names after `-run` flag.
## complete package
Supported shells:
- [x] bash
- [x] zsh
- [x] fish
### Usage
Assuming you have program called `run` and you want to have bash completion
for it, meaning, if you type `run` then space, then press the `Tab` key,
the shell will suggest relevant complete options.
In that case, we will create a program called `runcomplete`, a go program,
with a `func main()` and so, that will make the completion of the `run`
program. Once the `runcomplete` will be in a binary form, we could
`runcomplete -install` and that will add to our shell all the bash completion
options for `run`.
So here it is:
```go
import "github.com/posener/complete"
func main() {
// create a Command object, that represents the command we want
// to complete.
run := complete.Command{
// Sub defines a list of sub commands of the program,
// this is recursive, since every command is of type command also.
Sub: complete.Commands{
// add a build sub command
"build": complete.Command {
// define flags of the build sub command
Flags: complete.Flags{
// build sub command has a flag '-cpus', which
// expects number of cpus after it. in that case
// anything could complete this flag.
"-cpus": complete.PredictAnything,
},
},
},
// define flags of the 'run' main command
Flags: complete.Flags{
// a flag -o, which expects a file ending with .out after
// it, the tab completion will auto complete for files matching
// the given pattern.
"-o": complete.PredictFiles("*.out"),
},
// define global flags of the 'run' main command
// those will show up also when a sub command was entered in the
// command line
GlobalFlags: complete.Flags{
// a flag '-h' which does not expects anything after it
"-h": complete.PredictNothing,
},
}
// run the command completion, as part of the main() function.
// this triggers the autocompletion when needed.
// name must be exactly as the binary that we want to complete.
complete.New("run", run).Run()
}
```
### Self completing program
In case that the program that we want to complete is written in go we
can make it self completing.
Here is an [example](./example/self/main.go)

12
vendor/github.com/posener/complete/test.sh generated vendored Normal file
View File

@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -e
echo "" > coverage.txt
for d in $(go list ./... | grep -v vendor); do
go test -v -race -coverprofile=profile.out -covermode=atomic $d
if [ -f profile.out ]; then
cat profile.out >> coverage.txt
rm profile.out
fi
done

46
vendor/github.com/posener/complete/utils.go generated vendored Normal file
View File

@ -0,0 +1,46 @@
package complete
import (
"os"
"path/filepath"
"strings"
)
// fixPathForm changes a file name to a relative name
func fixPathForm(last string, file string) string {
// get wording directory for relative name
workDir, err := os.Getwd()
if err != nil {
return file
}
abs, err := filepath.Abs(file)
if err != nil {
return file
}
// if last is absolute, return path as absolute
if filepath.IsAbs(last) {
return fixDirPath(abs)
}
rel, err := filepath.Rel(workDir, abs)
if err != nil {
return file
}
// fix ./ prefix of path
if rel != "." && strings.HasPrefix(last, ".") {
rel = "./" + rel
}
return fixDirPath(rel)
}
func fixDirPath(path string) string {
info, err := os.Stat(path)
if err == nil && info.IsDir() && !strings.HasSuffix(path, "/") {
path += "/"
}
return path
}