add vendor
This commit is contained in:
4
vendor/github.com/posener/complete/.gitignore
generated
vendored
Normal file
4
vendor/github.com/posener/complete/.gitignore
generated
vendored
Normal 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
16
vendor/github.com/posener/complete/.travis.yml
generated
vendored
Normal 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
21
vendor/github.com/posener/complete/LICENSE.txt
generated
vendored
Normal 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
111
vendor/github.com/posener/complete/args.go
generated
vendored
Normal 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
128
vendor/github.com/posener/complete/cmd/cmd.go
generated
vendored
Normal 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
32
vendor/github.com/posener/complete/cmd/install/bash.go
generated
vendored
Normal 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
56
vendor/github.com/posener/complete/cmd/install/fish.go
generated
vendored
Normal 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
|
||||
}
|
119
vendor/github.com/posener/complete/cmd/install/install.go
generated
vendored
Normal file
119
vendor/github.com/posener/complete/cmd/install/install.go
generated
vendored
Normal 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
140
vendor/github.com/posener/complete/cmd/install/utils.go
generated
vendored
Normal 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
39
vendor/github.com/posener/complete/cmd/install/zsh.go
generated
vendored
Normal 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
111
vendor/github.com/posener/complete/command.go
generated
vendored
Normal 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
109
vendor/github.com/posener/complete/complete.go
generated
vendored
Normal 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
22
vendor/github.com/posener/complete/log.go
generated
vendored
Normal 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
19
vendor/github.com/posener/complete/match/file.go
generated
vendored
Normal 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
6
vendor/github.com/posener/complete/match/match.go
generated
vendored
Normal 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
9
vendor/github.com/posener/complete/match/prefix.go
generated
vendored
Normal 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
41
vendor/github.com/posener/complete/predict.go
generated
vendored
Normal 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
108
vendor/github.com/posener/complete/predict_files.go
generated
vendored
Normal 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
12
vendor/github.com/posener/complete/predict_set.go
generated
vendored
Normal 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
118
vendor/github.com/posener/complete/readme.md
generated
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
# complete
|
||||
|
||||
A tool for bash writing bash completion in go, and bash completion for the go command line.
|
||||
|
||||
[](https://travis-ci.org/posener/complete)
|
||||
[](https://codecov.io/gh/posener/complete)
|
||||
[](https://golangci.com/r/github.com/posener/complete)
|
||||
[](http://godoc.org/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
12
vendor/github.com/posener/complete/test.sh
generated
vendored
Normal 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
46
vendor/github.com/posener/complete/utils.go
generated
vendored
Normal 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
|
||||
}
|
Reference in New Issue
Block a user