mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-20 08:03:53 +08:00
vendor added.
This commit is contained in:
154
Gopkg.lock
generated
Normal file
154
Gopkg.lock
generated
Normal file
@@ -0,0 +1,154 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/c-bata/go-prompt"
|
||||
packages = ["."]
|
||||
revision = "c52492ff1b386e5c0ba5271b5eaad165fab09eca"
|
||||
version = "v0.2.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/fatih/color"
|
||||
packages = ["."]
|
||||
revision = "5b77d2a35fb0ede96d138fc9a99f5c9b6aef11b4"
|
||||
version = "v1.7.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/golang-plus/errors"
|
||||
packages = ["."]
|
||||
revision = "a61c34ead85085f3e1b87b8c04e49bbf60c99fb1"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/golang-plus/uuid"
|
||||
packages = [
|
||||
".",
|
||||
"internal",
|
||||
"internal/dcesecurity",
|
||||
"internal/namebased",
|
||||
"internal/namebased/md5",
|
||||
"internal/namebased/sha1",
|
||||
"internal/random",
|
||||
"internal/timebased"
|
||||
]
|
||||
revision = "a0510c37ef1f49c8290c3a9911d0f7f9ed24d335"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-colorable"
|
||||
packages = ["."]
|
||||
revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
|
||||
version = "v0.0.9"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-isatty"
|
||||
packages = ["."]
|
||||
revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
|
||||
version = "v0.0.3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mattn/go-runewidth"
|
||||
packages = ["."]
|
||||
revision = "ce7b0b5c7b45a81508558cd1dba6bb1e4ddb51bb"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mattn/go-tty"
|
||||
packages = ["."]
|
||||
revision = "931426f7535ac39720c8909d70ece5a41a2502a6"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mgutz/ansi"
|
||||
packages = ["."]
|
||||
revision = "9520e82c474b0a04dd04f8a40959027271bab992"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/moul/http2curl"
|
||||
packages = ["."]
|
||||
revision = "9ac6cf4d929b2fa8fd2d2e6dec5bb0feb4f4911d"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/pkg/term"
|
||||
packages = ["termios"]
|
||||
revision = "cda20d4ac917ad418d86e151eff439648b06185b"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/sirupsen/logrus"
|
||||
packages = ["."]
|
||||
revision = "3e01752db0189b9157070a0e1668a620f9a85da2"
|
||||
version = "v1.0.6"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/yunionio/jsonutils"
|
||||
packages = ["."]
|
||||
revision = "7cd91af9430db0aeb6b67cfe4dacfc7de91151d7"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/yunionio/log"
|
||||
packages = [
|
||||
".",
|
||||
"hooks"
|
||||
]
|
||||
revision = "d2fe137411c230927e28dd82b1a3bcb618dbb28d"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/yunionio/mcclient"
|
||||
packages = [
|
||||
".",
|
||||
"modules"
|
||||
]
|
||||
revision = "3d730c039309cb732abc9946a08fcb1924f51123"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/yunionio/pkg"
|
||||
packages = [
|
||||
"appctx",
|
||||
"gotypes",
|
||||
"httperrors",
|
||||
"prettytable",
|
||||
"trace",
|
||||
"util/httputils",
|
||||
"util/printjson",
|
||||
"util/reflectutils",
|
||||
"util/regutils",
|
||||
"util/timeutils",
|
||||
"util/version",
|
||||
"utils"
|
||||
]
|
||||
revision = "a9fe773152c59ad791606358e2d16564971e2d52"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/yunionio/structarg"
|
||||
packages = ["."]
|
||||
revision = "7c3bbf8a77dc7b33ccad90087a296f3e34399d09"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = ["ssh/terminal"]
|
||||
revision = "c126467f60eb25f8f27e5a981f32a87e3965053f"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = [
|
||||
"unix",
|
||||
"windows"
|
||||
]
|
||||
revision = "e072cadbbdc8dd3d3ffa82b8b4b9304c261d9311"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "a8e21ab20315647cbb38a160c9591d9567ff029229416f50892a45d84692ee3c"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
54
Gopkg.toml
Normal file
54
Gopkg.toml
Normal file
@@ -0,0 +1,54 @@
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
#
|
||||
# [prune]
|
||||
# non-go = false
|
||||
# go-tests = true
|
||||
# unused-packages = true
|
||||
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/c-bata/go-prompt"
|
||||
version = "0.2.2"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/yunionio/jsonutils"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/yunionio/log"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/yunionio/mcclient"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/yunionio/pkg"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/yunionio/structarg"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
25
vendor/github.com/c-bata/go-prompt/.gitignore
generated
vendored
Normal file
25
vendor/github.com/c-bata/go-prompt/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
pkg/
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
|
||||
# Glide
|
||||
vendor/
|
||||
62
vendor/github.com/c-bata/go-prompt/CHANGELOG.md
generated
vendored
Normal file
62
vendor/github.com/c-bata/go-prompt/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
# Change Log
|
||||
|
||||
## v0.3.0 (2018/??/??)
|
||||
|
||||
next release.
|
||||
|
||||
## v0.2.2 (2018/06/28)
|
||||
|
||||
### What's new?
|
||||
|
||||
* Support CJK(Chinese, Japanese and Korean) and Cyrillic characters.
|
||||
* Add OptionCompletionWordSeparator(x string) to customize insertion points for completions.
|
||||
* To support this, text query functions by arbitrary word separator are added in Document (please see [here](https://github.com/c-bata/go-prompt/pull/79) for more details).
|
||||
* Add FilePathCompleter to complete file path on your system.
|
||||
* Add option to customize ascii code key bindings.
|
||||
* Add GetWordAfterCursor method in Document.
|
||||
|
||||
### Removed or Deprecated
|
||||
|
||||
* SetColor method in ConsoleWriter is deprecated. Please use SetDisplayAttributes instead.
|
||||
* prompt.Choose shortcut function is deprecated.
|
||||
|
||||
## v0.2.1 (2018/02/14)
|
||||
|
||||
### What's New?
|
||||
|
||||
* ~~It seems that windows support is almost perfect.~~
|
||||
* A critical bug is found :( When you change a terminal window size, the layout will be broken because current implementation cannot catch signal for updating window size on Windows.
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix a Shift+Tab handling on Windows.
|
||||
* Fix 4-dimension arrow keys handling on Windows.
|
||||
|
||||
## v0.2.0 (2018/02/13)
|
||||
|
||||
### What's New?
|
||||
|
||||
* Supports scrollbar when there are too many matched suggestions
|
||||
* Windows support (but please caution because this is still not perfect).
|
||||
* Add OptionLivePrefix to update the prefix dynamically
|
||||
* Implement clear screen by `Ctrl+L`.
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix the behavior of `Ctrl+W` keybind.
|
||||
* Fix the panic because when running on a docker container (please see [here](https://github.com/c-bata/go-prompt/pull/32) for details).
|
||||
* Fix panic when making terminal window small size after input 2 lines of texts. See [here](https://github.com/c-bata/go-prompt/issues/37) for details).
|
||||
* And also fixed many bugs that layout is broken when using Terminal.app, GNU Terminal and a Goland(IntelliJ).
|
||||
|
||||
### News
|
||||
|
||||
New core developers are joined (alphabetical order).
|
||||
|
||||
* Nao Yonashiro (Github @orisano)
|
||||
* Ryoma Abe (Github @Allajah)
|
||||
* Yusuke Nakamura (Github @unasuke)
|
||||
|
||||
|
||||
## v0.1.0 (2017/08/15)
|
||||
|
||||
Initial Release
|
||||
45
vendor/github.com/c-bata/go-prompt/Gopkg.lock
generated
vendored
Normal file
45
vendor/github.com/c-bata/go-prompt/Gopkg.lock
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-colorable"
|
||||
packages = ["."]
|
||||
revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
|
||||
version = "v0.0.9"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-isatty"
|
||||
packages = ["."]
|
||||
revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
|
||||
version = "v0.0.3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mattn/go-runewidth"
|
||||
packages = ["."]
|
||||
revision = "ce7b0b5c7b45a81508558cd1dba6bb1e4ddb51bb"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mattn/go-tty"
|
||||
packages = ["."]
|
||||
revision = "931426f7535ac39720c8909d70ece5a41a2502a6"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/pkg/term"
|
||||
packages = ["termios"]
|
||||
revision = "cda20d4ac917ad418d86e151eff439648b06185b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
revision = "ad87a3a340fa7f3bed189293fbfa7a9b7e021ae1"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "d6a0ea9e49092cfd8cb3d6077c97a938de7c39195b83828dae2a0befdd207ffd"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
38
vendor/github.com/c-bata/go-prompt/Gopkg.toml
generated
vendored
Normal file
38
vendor/github.com/c-bata/go-prompt/Gopkg.toml
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/mattn/go-colorable"
|
||||
version = "0.0.9"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/mattn/go-tty"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/pkg/term"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/mattn/go-runewidth"
|
||||
21
vendor/github.com/c-bata/go-prompt/LICENSE
generated
vendored
Normal file
21
vendor/github.com/c-bata/go-prompt/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Masashi SHIBATA
|
||||
|
||||
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.
|
||||
36
vendor/github.com/c-bata/go-prompt/Makefile
generated
vendored
Normal file
36
vendor/github.com/c-bata/go-prompt/Makefile
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
.PHONY: setup
|
||||
setup: ## Setup for required tools.
|
||||
go get github.com/golang/lint/golint
|
||||
go get golang.org/x/tools/cmd/goimports
|
||||
go get golang.org/x/tools/cmd/stringer
|
||||
go get -u github.com/golang/dep/cmd/dep
|
||||
dep ensure
|
||||
|
||||
.PHONY: fmt
|
||||
fmt: ## Formatting source codes.
|
||||
@goimports -w .
|
||||
|
||||
.PHONY: lint
|
||||
lint: ## Run golint and go vet.
|
||||
@golint .
|
||||
@go vet .
|
||||
|
||||
.PHONY: test
|
||||
test: ## Run the tests.
|
||||
@go test .
|
||||
|
||||
.PHONY: coverage
|
||||
cover: ## Run the tests.
|
||||
@go test -coverprofile=coverage.o
|
||||
@go tool cover -func=coverage.o
|
||||
|
||||
.PHONY: race-test
|
||||
race-test: ## Checking the race condition.
|
||||
@go test -race .
|
||||
|
||||
.PHONY: help
|
||||
help: ## Show help text
|
||||
@echo "Commands:"
|
||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-10s\033[0m %s\n", $$1, $$2}'
|
||||
110
vendor/github.com/c-bata/go-prompt/README.md
generated
vendored
Normal file
110
vendor/github.com/c-bata/go-prompt/README.md
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
# go-prompt
|
||||
|
||||
[](https://goreportcard.com/report/github.com/c-bata/go-prompt)
|
||||

|
||||
|
||||
A library for building powerful interactive prompts inspired by [python-prompt-toolkit](https://github.com/jonathanslenders/python-prompt-toolkit),
|
||||
making it easier to build cross-platform command line tools using Go.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/c-bata/go-prompt"
|
||||
)
|
||||
|
||||
func completer(d prompt.Document) []prompt.Suggest {
|
||||
s := []prompt.Suggest{
|
||||
{Text: "users", Description: "Store the username and age"},
|
||||
{Text: "articles", Description: "Store the article text posted by user"},
|
||||
{Text: "comments", Description: "Store the text commented to articles"},
|
||||
}
|
||||
return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("Please select table.")
|
||||
t := prompt.Input("> ", completer)
|
||||
fmt.Println("You selected " + t)
|
||||
}
|
||||
```
|
||||
|
||||
#### Projects using go-prompt
|
||||
|
||||
* [c-bata/kube-prompt : An interactive kubernetes client featuring auto-complete written in Go.](https://github.com/c-bata/kube-prompt)
|
||||
* [rancher/cli : The Rancher Command Line Interface (CLI)is a unified tool to manage your Rancher server](https://github.com/rancher/cli)
|
||||
* [kubicorn/kubicorn : Simple, cloud native infrastructure for Kubernetes.](https://github.com/kubicorn/kubicorn)
|
||||
* [cch123/asm-cli : Interactive shell of assembly language(X86/X64) based on unicorn and rasm2](https://github.com/cch123/asm-cli)
|
||||
* [ktr0731/evans : more expressive universal gRPC client](https://github.com/ktr0731/evans)
|
||||
* [CrushedPixel/moshpit: A Command-line tool for datamoshing.](https://github.com/CrushedPixel/moshpit)
|
||||
* (If you create a CLI utility using go-prompt and want your own project to be listed here, please submit a GitHub issue.)
|
||||
|
||||
## Features
|
||||
|
||||
### Powerful auto-completion
|
||||
|
||||
[](https://github.com/c-bata/kube-prompt)
|
||||
|
||||
(This is a GIF animation of kube-prompt.)
|
||||
|
||||
### Flexible options
|
||||
|
||||
go-prompt provides many options. Please check [option section of GoDoc](https://godoc.org/github.com/c-bata/go-prompt#Option) for more details.
|
||||
|
||||
[](#flexible-options)
|
||||
|
||||
### Keyboard Shortcuts
|
||||
|
||||
Emacs-like keyboard shortcuts are available by default (these also are the default shortcuts in Bash shell).
|
||||
You can customize and expand these shortcuts.
|
||||
|
||||
[](#keyboard-shortcuts)
|
||||
|
||||
Key Binding | Description
|
||||
---------------------|---------------------------------------------------------
|
||||
<kbd>Ctrl + A</kbd> | Go to the beginning of the line (Home)
|
||||
<kbd>Ctrl + E</kbd> | Go to the end of the line (End)
|
||||
<kbd>Ctrl + P</kbd> | Previous command (Up arrow)
|
||||
<kbd>Ctrl + N</kbd> | Next command (Down arrow)
|
||||
<kbd>Ctrl + F</kbd> | Forward one character
|
||||
<kbd>Ctrl + B</kbd> | Backward one character
|
||||
<kbd>Ctrl + D</kbd> | Delete character under the cursor
|
||||
<kbd>Ctrl + H</kbd> | Delete character before the cursor (Backspace)
|
||||
<kbd>Ctrl + W</kbd> | Cut the word before the cursor to the clipboard
|
||||
<kbd>Ctrl + K</kbd> | Cut the line after the cursor to the clipboard
|
||||
<kbd>Ctrl + U</kbd> | Cut the line before the cursor to the clipboard
|
||||
<kbd>Ctrl + L</kbd> | Clear the screen
|
||||
|
||||
### History
|
||||
|
||||
You can use <kbd>Up arrow</kbd> and <kbd>Down arrow</kbd> to walk through the history of commands executed.
|
||||
|
||||
[](#history)
|
||||
|
||||
### Multiple platform support
|
||||
|
||||
We have confirmed go-prompt works fine in the following terminals:
|
||||
|
||||
* iTerm2 (macOS)
|
||||
* Terminal.app (macOS)
|
||||
* Command Prompt (Windows)
|
||||
* gnome-terminal (Ubuntu)
|
||||
|
||||
## Links
|
||||
|
||||
* [Change Log](./CHANGELOG.md)
|
||||
* [GoDoc](http://godoc.org/github.com/c-bata/go-prompt)
|
||||
* [gocover.io](https://gocover.io/github.com/c-bata/go-prompt)
|
||||
|
||||
## Author
|
||||
|
||||
Masashi Shibata
|
||||
|
||||
* Twitter: [@c\_bata\_](https://twitter.com/c_bata_/)
|
||||
* Github: [@c-bata](https://github.com/c-bata/)
|
||||
* Facebook: [Masashi Shibata](https://www.facebook.com/masashi.cbata)
|
||||
|
||||
## License
|
||||
|
||||
This software is licensed under the MIT license, see [LICENSE](./LICENSE) for more information.
|
||||
206
vendor/github.com/c-bata/go-prompt/buffer.go
generated
vendored
Normal file
206
vendor/github.com/c-bata/go-prompt/buffer.go
generated
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Buffer emulates the console buffer.
|
||||
type Buffer struct {
|
||||
workingLines []string // The working lines. Similar to history
|
||||
workingIndex int
|
||||
cursorPosition int
|
||||
cacheDocument *Document
|
||||
preferredColumn int // Remember the original column for the next up/down movement.
|
||||
}
|
||||
|
||||
// Text returns string of the current line.
|
||||
func (b *Buffer) Text() string {
|
||||
return b.workingLines[b.workingIndex]
|
||||
}
|
||||
|
||||
// Document method to return document instance from the current text and cursor position.
|
||||
func (b *Buffer) Document() (d *Document) {
|
||||
if b.cacheDocument == nil ||
|
||||
b.cacheDocument.Text != b.Text() ||
|
||||
b.cacheDocument.cursorPosition != b.cursorPosition {
|
||||
b.cacheDocument = &Document{
|
||||
Text: b.Text(),
|
||||
cursorPosition: b.cursorPosition,
|
||||
}
|
||||
}
|
||||
return b.cacheDocument
|
||||
}
|
||||
|
||||
// DisplayCursorPosition returns the cursor position on rendered text on terminal emulators.
|
||||
// So if Document is "日本(cursor)語", DisplayedCursorPosition returns 4 because '日' and '本' are double width characters.
|
||||
func (b *Buffer) DisplayCursorPosition() int {
|
||||
return b.Document().DisplayCursorPosition()
|
||||
}
|
||||
|
||||
// InsertText insert string from current line.
|
||||
func (b *Buffer) InsertText(v string, overwrite bool, moveCursor bool) {
|
||||
or := []rune(b.Text())
|
||||
oc := b.cursorPosition
|
||||
|
||||
if overwrite {
|
||||
overwritten := string(or[oc : oc+len(v)])
|
||||
if strings.Contains(overwritten, "\n") {
|
||||
i := strings.IndexAny(overwritten, "\n")
|
||||
overwritten = overwritten[:i]
|
||||
}
|
||||
b.setText(string(or[:oc]) + v + string(or[oc+len(overwritten):]))
|
||||
} else {
|
||||
b.setText(string(or[:oc]) + v + string(or[oc:]))
|
||||
}
|
||||
|
||||
if moveCursor {
|
||||
b.cursorPosition += len([]rune(v))
|
||||
}
|
||||
}
|
||||
|
||||
// SetText method to set text and update cursorPosition.
|
||||
// (When doing this, make sure that the cursor_position is valid for this text.
|
||||
// text/cursor_position should be consistent at any time, otherwise set a Document instead.)
|
||||
func (b *Buffer) setText(v string) {
|
||||
if b.cursorPosition > len([]rune(v)) {
|
||||
log.Print("[ERROR] The length of input value should be shorter than the position of cursor.")
|
||||
}
|
||||
o := b.workingLines[b.workingIndex]
|
||||
b.workingLines[b.workingIndex] = v
|
||||
|
||||
if o != v {
|
||||
// Text is changed.
|
||||
// TODO: Call callback function triggered by text changed. And also history search text should reset.
|
||||
// https://github.com/jonathanslenders/python-prompt-toolkit/blob/master/prompt_toolkit/buffer.py#L380-L384
|
||||
}
|
||||
}
|
||||
|
||||
// Set cursor position. Return whether it changed.
|
||||
func (b *Buffer) setCursorPosition(p int) {
|
||||
o := b.cursorPosition
|
||||
if p > 0 {
|
||||
b.cursorPosition = p
|
||||
} else {
|
||||
b.cursorPosition = 0
|
||||
}
|
||||
if p != o {
|
||||
// Cursor position is changed.
|
||||
// TODO: Call a onCursorPositionChanged function.
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Buffer) setDocument(d *Document) {
|
||||
b.cacheDocument = d
|
||||
b.setCursorPosition(d.cursorPosition) // Call before setText because setText check the relation between cursorPosition and line length.
|
||||
b.setText(d.Text)
|
||||
}
|
||||
|
||||
// CursorLeft move to left on the current line.
|
||||
func (b *Buffer) CursorLeft(count int) {
|
||||
l := b.Document().GetCursorLeftPosition(count)
|
||||
b.cursorPosition += l
|
||||
return
|
||||
}
|
||||
|
||||
// CursorRight move to right on the current line.
|
||||
func (b *Buffer) CursorRight(count int) {
|
||||
l := b.Document().GetCursorRightPosition(count)
|
||||
b.cursorPosition += l
|
||||
return
|
||||
}
|
||||
|
||||
// CursorUp move cursor to the previous line.
|
||||
// (for multi-line edit).
|
||||
func (b *Buffer) CursorUp(count int) {
|
||||
orig := b.preferredColumn
|
||||
if b.preferredColumn == -1 { // -1 means nil
|
||||
orig = b.Document().CursorPositionCol()
|
||||
}
|
||||
b.cursorPosition += b.Document().GetCursorUpPosition(count, orig)
|
||||
|
||||
// Remember the original column for the next up/down movement.
|
||||
b.preferredColumn = orig
|
||||
}
|
||||
|
||||
// CursorDown move cursor to the next line.
|
||||
// (for multi-line edit).
|
||||
func (b *Buffer) CursorDown(count int) {
|
||||
orig := b.preferredColumn
|
||||
if b.preferredColumn == -1 { // -1 means nil
|
||||
orig = b.Document().CursorPositionCol()
|
||||
}
|
||||
b.cursorPosition += b.Document().GetCursorDownPosition(count, orig)
|
||||
|
||||
// Remember the original column for the next up/down movement.
|
||||
b.preferredColumn = orig
|
||||
}
|
||||
|
||||
// DeleteBeforeCursor delete specified number of characters before cursor and return the deleted text.
|
||||
func (b *Buffer) DeleteBeforeCursor(count int) (deleted string) {
|
||||
if count <= 0 {
|
||||
log.Print("[ERROR] The count argument on DeleteBeforeCursor should grater than 0.")
|
||||
}
|
||||
r := []rune(b.Text())
|
||||
|
||||
if b.cursorPosition > 0 {
|
||||
start := b.cursorPosition - count
|
||||
if start < 0 {
|
||||
start = 0
|
||||
}
|
||||
deleted = string(r[start:b.cursorPosition])
|
||||
b.setDocument(&Document{
|
||||
Text: string(r[:start]) + string(r[b.cursorPosition:]),
|
||||
cursorPosition: b.cursorPosition - len([]rune(deleted)),
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// NewLine means CR.
|
||||
func (b *Buffer) NewLine(copyMargin bool) {
|
||||
if copyMargin {
|
||||
b.InsertText("\n"+b.Document().leadingWhitespaceInCurrentLine(), false, true)
|
||||
} else {
|
||||
b.InsertText("\n", false, true)
|
||||
}
|
||||
}
|
||||
|
||||
// Delete specified number of characters and Return the deleted text.
|
||||
func (b *Buffer) Delete(count int) (deleted string) {
|
||||
r := []rune(b.Text())
|
||||
if b.cursorPosition < len(r) {
|
||||
deleted = b.Document().TextAfterCursor()[:count]
|
||||
b.setText(string(r[:b.cursorPosition]) + string(r[b.cursorPosition+len(deleted):]))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// JoinNextLine joins the next line to the current one by deleting the line ending after the current line.
|
||||
func (b *Buffer) JoinNextLine(separator string) {
|
||||
if !b.Document().OnLastLine() {
|
||||
b.cursorPosition += b.Document().GetEndOfLinePosition()
|
||||
b.Delete(1)
|
||||
// Remove spaces
|
||||
b.setText(b.Document().TextBeforeCursor() + separator + strings.TrimLeft(b.Document().TextAfterCursor(), " "))
|
||||
}
|
||||
}
|
||||
|
||||
// SwapCharactersBeforeCursor swaps the last two characters before the cursor.
|
||||
func (b *Buffer) SwapCharactersBeforeCursor() {
|
||||
if b.cursorPosition >= 2 {
|
||||
x := b.Text()[b.cursorPosition-2 : b.cursorPosition-1]
|
||||
y := b.Text()[b.cursorPosition-1 : b.cursorPosition]
|
||||
b.setText(b.Text()[:b.cursorPosition-2] + y + x + b.Text()[b.cursorPosition:])
|
||||
}
|
||||
}
|
||||
|
||||
// NewBuffer is constructor of Buffer struct.
|
||||
func NewBuffer() (b *Buffer) {
|
||||
b = &Buffer{
|
||||
workingLines: []string{""},
|
||||
workingIndex: 0,
|
||||
preferredColumn: -1, // -1 means nil
|
||||
}
|
||||
return
|
||||
}
|
||||
194
vendor/github.com/c-bata/go-prompt/completion.go
generated
vendored
Normal file
194
vendor/github.com/c-bata/go-prompt/completion.go
generated
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/mattn/go-runewidth"
|
||||
)
|
||||
|
||||
const (
|
||||
shortenSuffix = "..."
|
||||
leftPrefix = " "
|
||||
leftSuffix = " "
|
||||
rightPrefix = " "
|
||||
rightSuffix = " "
|
||||
)
|
||||
|
||||
var (
|
||||
leftMargin = runewidth.StringWidth(leftPrefix + leftSuffix)
|
||||
rightMargin = runewidth.StringWidth(rightPrefix + rightSuffix)
|
||||
completionMargin = leftMargin + rightMargin
|
||||
)
|
||||
|
||||
// Suggest is printed when completing.
|
||||
type Suggest struct {
|
||||
Text string
|
||||
Description string
|
||||
}
|
||||
|
||||
// CompletionManager manages which suggestion is now selected.
|
||||
type CompletionManager struct {
|
||||
selected int // -1 means nothing one is selected.
|
||||
tmp []Suggest
|
||||
max uint16
|
||||
completer Completer
|
||||
|
||||
verticalScroll int
|
||||
wordSeparator string
|
||||
}
|
||||
|
||||
// GetSelectedSuggestion returns the selected item.
|
||||
func (c *CompletionManager) GetSelectedSuggestion() (s Suggest, ok bool) {
|
||||
if c.selected == -1 {
|
||||
return Suggest{}, false
|
||||
} else if c.selected < -1 {
|
||||
log.Printf("[ERROR] shoud be reached here, selected=%d", c.selected)
|
||||
c.selected = -1
|
||||
return Suggest{}, false
|
||||
}
|
||||
return c.tmp[c.selected], true
|
||||
}
|
||||
|
||||
// GetSuggestions returns the list of suggestion.
|
||||
func (c *CompletionManager) GetSuggestions() []Suggest {
|
||||
return c.tmp
|
||||
}
|
||||
|
||||
// Reset to select nothing.
|
||||
func (c *CompletionManager) Reset() {
|
||||
c.selected = -1
|
||||
c.verticalScroll = 0
|
||||
c.Update(*NewDocument())
|
||||
return
|
||||
}
|
||||
|
||||
// Update to update the suggestions.
|
||||
func (c *CompletionManager) Update(in Document) {
|
||||
c.tmp = c.completer(in)
|
||||
return
|
||||
}
|
||||
|
||||
// Previous to select the previous suggestion item.
|
||||
func (c *CompletionManager) Previous() {
|
||||
if c.verticalScroll == c.selected && c.selected > 0 {
|
||||
c.verticalScroll--
|
||||
}
|
||||
c.selected--
|
||||
c.update()
|
||||
return
|
||||
}
|
||||
|
||||
// Next to select the next suggestion item.
|
||||
func (c *CompletionManager) Next() {
|
||||
if c.verticalScroll+int(c.max)-1 == c.selected {
|
||||
c.verticalScroll++
|
||||
}
|
||||
c.selected++
|
||||
c.update()
|
||||
return
|
||||
}
|
||||
|
||||
// Completing returns whether the CompletionManager selects something one.
|
||||
func (c *CompletionManager) Completing() bool {
|
||||
return c.selected != -1
|
||||
}
|
||||
|
||||
func (c *CompletionManager) update() {
|
||||
max := int(c.max)
|
||||
if len(c.tmp) < max {
|
||||
max = len(c.tmp)
|
||||
}
|
||||
|
||||
if c.selected >= len(c.tmp) {
|
||||
c.Reset()
|
||||
} else if c.selected < -1 {
|
||||
c.selected = len(c.tmp) - 1
|
||||
c.verticalScroll = len(c.tmp) - max
|
||||
}
|
||||
}
|
||||
|
||||
func deleteBreakLineCharacters(s string) string {
|
||||
s = strings.Replace(s, "\n", "", -1)
|
||||
s = strings.Replace(s, "\r", "", -1)
|
||||
return s
|
||||
}
|
||||
|
||||
func formatTexts(o []string, max int, prefix, suffix string) (new []string, width int) {
|
||||
l := len(o)
|
||||
n := make([]string, l)
|
||||
|
||||
lenPrefix := runewidth.StringWidth(prefix)
|
||||
lenSuffix := runewidth.StringWidth(suffix)
|
||||
lenShorten := runewidth.StringWidth(shortenSuffix)
|
||||
min := lenPrefix + lenSuffix + lenShorten
|
||||
for i := 0; i < l; i++ {
|
||||
o[i] = deleteBreakLineCharacters(o[i])
|
||||
|
||||
w := runewidth.StringWidth(o[i])
|
||||
if width < w {
|
||||
width = w
|
||||
}
|
||||
}
|
||||
|
||||
if width == 0 {
|
||||
return n, 0
|
||||
}
|
||||
if min >= max {
|
||||
log.Println("[WARN] formatTexts: max is lower than length of prefix and suffix.")
|
||||
return n, 0
|
||||
}
|
||||
if lenPrefix+width+lenSuffix > max {
|
||||
width = max - lenPrefix - lenSuffix
|
||||
}
|
||||
|
||||
for i := 0; i < l; i++ {
|
||||
x := runewidth.StringWidth(o[i])
|
||||
if x <= width {
|
||||
spaces := strings.Repeat(" ", width-x)
|
||||
n[i] = prefix + o[i] + spaces + suffix
|
||||
} else if x > width {
|
||||
x := runewidth.Truncate(o[i], width, shortenSuffix)
|
||||
// When calling runewidth.Truncate("您好xxx您好xxx", 11, "...") returns "您好xxx..."
|
||||
// But the length of this result is 10. So we need fill right using runewidth.FillRight.
|
||||
n[i] = prefix + runewidth.FillRight(x, width) + suffix
|
||||
}
|
||||
}
|
||||
return n, lenPrefix + width + lenSuffix
|
||||
}
|
||||
|
||||
func formatSuggestions(suggests []Suggest, max int) (new []Suggest, width int) {
|
||||
num := len(suggests)
|
||||
new = make([]Suggest, num)
|
||||
|
||||
left := make([]string, num)
|
||||
for i := 0; i < num; i++ {
|
||||
left[i] = suggests[i].Text
|
||||
}
|
||||
right := make([]string, num)
|
||||
for i := 0; i < num; i++ {
|
||||
right[i] = suggests[i].Description
|
||||
}
|
||||
|
||||
left, leftWidth := formatTexts(left, max, leftPrefix, leftSuffix)
|
||||
if leftWidth == 0 {
|
||||
return []Suggest{}, 0
|
||||
}
|
||||
right, rightWidth := formatTexts(right, max-leftWidth, rightPrefix, rightSuffix)
|
||||
|
||||
for i := 0; i < num; i++ {
|
||||
new[i] = Suggest{Text: left[i], Description: right[i]}
|
||||
}
|
||||
return new, leftWidth + rightWidth
|
||||
}
|
||||
|
||||
// NewCompletionManager returns initialized CompletionManager object.
|
||||
func NewCompletionManager(completer Completer, max uint16) *CompletionManager {
|
||||
return &CompletionManager{
|
||||
selected: -1,
|
||||
max: max,
|
||||
completer: completer,
|
||||
|
||||
verticalScroll: 0,
|
||||
}
|
||||
}
|
||||
533
vendor/github.com/c-bata/go-prompt/document.go
generated
vendored
Normal file
533
vendor/github.com/c-bata/go-prompt/document.go
generated
vendored
Normal file
@@ -0,0 +1,533 @@
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/mattn/go-runewidth"
|
||||
)
|
||||
|
||||
// Document has text displayed in terminal and cursor position.
|
||||
type Document struct {
|
||||
Text string
|
||||
// This represents a index in a rune array of Document.Text.
|
||||
// So if Document is "日本(cursor)語", cursorPosition is 2.
|
||||
// But DisplayedCursorPosition returns 4 because '日' and '本' are double width characters.
|
||||
cursorPosition int
|
||||
}
|
||||
|
||||
// NewDocument return the new empty document.
|
||||
func NewDocument() *Document {
|
||||
return &Document{
|
||||
Text: "",
|
||||
cursorPosition: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// DisplayCursorPosition returns the cursor position on rendered text on terminal emulators.
|
||||
// So if Document is "日本(cursor)語", DisplayedCursorPosition returns 4 because '日' and '本' are double width characters.
|
||||
func (d *Document) DisplayCursorPosition() int {
|
||||
var position int
|
||||
runes := []rune(d.Text)[:d.cursorPosition]
|
||||
for i := range runes {
|
||||
position += runewidth.RuneWidth(runes[i])
|
||||
}
|
||||
return position
|
||||
}
|
||||
|
||||
// GetCharRelativeToCursor return character relative to cursor position, or empty string
|
||||
func (d *Document) GetCharRelativeToCursor(offset int) (r rune) {
|
||||
s := d.Text
|
||||
cnt := 0
|
||||
|
||||
for len(s) > 0 {
|
||||
cnt++
|
||||
r, size := utf8.DecodeRuneInString(s)
|
||||
if cnt == d.cursorPosition+offset {
|
||||
return r
|
||||
}
|
||||
s = s[size:]
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// TextBeforeCursor returns the text before the cursor.
|
||||
func (d *Document) TextBeforeCursor() string {
|
||||
r := []rune(d.Text)
|
||||
return string(r[:d.cursorPosition])
|
||||
}
|
||||
|
||||
// TextAfterCursor returns the text after the cursor.
|
||||
func (d *Document) TextAfterCursor() string {
|
||||
r := []rune(d.Text)
|
||||
return string(r[d.cursorPosition:])
|
||||
}
|
||||
|
||||
// GetWordBeforeCursor returns the word before the cursor.
|
||||
// If we have whitespace before the cursor this returns an empty string.
|
||||
func (d *Document) GetWordBeforeCursor() string {
|
||||
x := d.TextBeforeCursor()
|
||||
return x[d.FindStartOfPreviousWord():]
|
||||
}
|
||||
|
||||
// GetWordAfterCursor returns the word after the cursor.
|
||||
// If we have whitespace after the cursor this returns an empty string.
|
||||
func (d *Document) GetWordAfterCursor() string {
|
||||
x := d.TextAfterCursor()
|
||||
return x[:d.FindEndOfCurrentWord()]
|
||||
}
|
||||
|
||||
// GetWordBeforeCursorWithSpace returns the word before the cursor.
|
||||
// Unlike GetWordBeforeCursor, it returns string containing space
|
||||
func (d *Document) GetWordBeforeCursorWithSpace() string {
|
||||
x := d.TextBeforeCursor()
|
||||
return x[d.FindStartOfPreviousWordWithSpace():]
|
||||
}
|
||||
|
||||
// GetWordAfterCursorWithSpace returns the word after the cursor.
|
||||
// Unlike GetWordAfterCursor, it returns string containing space
|
||||
func (d *Document) GetWordAfterCursorWithSpace() string {
|
||||
x := d.TextAfterCursor()
|
||||
return x[:d.FindEndOfCurrentWordWithSpace()]
|
||||
}
|
||||
|
||||
// GetWordBeforeCursorUntilSeparator returns the text before the cursor until next separator.
|
||||
func (d *Document) GetWordBeforeCursorUntilSeparator(sep string) string {
|
||||
x := d.TextBeforeCursor()
|
||||
return x[d.FindStartOfPreviousWordUntilSeparator(sep):]
|
||||
}
|
||||
|
||||
// GetWordAfterCursorUntilSeparator returns the text after the cursor until next separator.
|
||||
func (d *Document) GetWordAfterCursorUntilSeparator(sep string) string {
|
||||
x := d.TextAfterCursor()
|
||||
return x[:d.FindEndOfCurrentWordUntilSeparator(sep)]
|
||||
}
|
||||
|
||||
// GetWordBeforeCursorUntilSeparatorIgnoreNextToCursor returns the word before the cursor.
|
||||
// Unlike GetWordBeforeCursor, it returns string containing space
|
||||
func (d *Document) GetWordBeforeCursorUntilSeparatorIgnoreNextToCursor(sep string) string {
|
||||
x := d.TextBeforeCursor()
|
||||
return x[d.FindStartOfPreviousWordUntilSeparatorIgnoreNextToCursor(sep):]
|
||||
}
|
||||
|
||||
// GetWordAfterCursorUntilSeparatorIgnoreNextToCursor returns the word after the cursor.
|
||||
// Unlike GetWordAfterCursor, it returns string containing space
|
||||
func (d *Document) GetWordAfterCursorUntilSeparatorIgnoreNextToCursor(sep string) string {
|
||||
x := d.TextAfterCursor()
|
||||
return x[:d.FindEndOfCurrentWordUntilSeparatorIgnoreNextToCursor(sep)]
|
||||
}
|
||||
|
||||
// FindStartOfPreviousWord returns an index relative to the cursor position
|
||||
// pointing to the start of the previous word. Return 0 if nothing was found.
|
||||
func (d *Document) FindStartOfPreviousWord() int {
|
||||
x := d.TextBeforeCursor()
|
||||
i := strings.LastIndexByte(x, ' ')
|
||||
if i != -1 {
|
||||
return i + 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// FindStartOfPreviousWordWithSpace is almost the same as FindStartOfPreviousWord.
|
||||
// The only difference is to ignore contiguous spaces.
|
||||
func (d *Document) FindStartOfPreviousWordWithSpace() int {
|
||||
x := d.TextBeforeCursor()
|
||||
end := lastIndexByteNot(x, ' ')
|
||||
if end == -1 {
|
||||
return 0
|
||||
}
|
||||
|
||||
start := strings.LastIndexByte(x[:end], ' ')
|
||||
if start == -1 {
|
||||
return 0
|
||||
}
|
||||
return start + 1
|
||||
}
|
||||
|
||||
// FindStartOfPreviousWordUntilSeparator is almost the same as FindStartOfPreviousWord.
|
||||
// But this can specify Separator. Return 0 if nothing was found.
|
||||
func (d *Document) FindStartOfPreviousWordUntilSeparator(sep string) int {
|
||||
if sep == "" {
|
||||
return d.FindStartOfPreviousWord()
|
||||
}
|
||||
|
||||
x := d.TextBeforeCursor()
|
||||
i := strings.LastIndexAny(x, sep)
|
||||
if i != -1 {
|
||||
return i + 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// FindStartOfPreviousWordUntilSeparatorIgnoreNextToCursor is almost the same as FindStartOfPreviousWordWithSpace.
|
||||
// But this can specify Separator. Return 0 if nothing was found.
|
||||
func (d *Document) FindStartOfPreviousWordUntilSeparatorIgnoreNextToCursor(sep string) int {
|
||||
if sep == "" {
|
||||
return d.FindStartOfPreviousWordWithSpace()
|
||||
}
|
||||
|
||||
x := d.TextBeforeCursor()
|
||||
end := lastIndexAnyNot(x, sep)
|
||||
if end == -1 {
|
||||
return 0
|
||||
}
|
||||
start := strings.LastIndexAny(x[:end], sep)
|
||||
if start == -1 {
|
||||
return 0
|
||||
}
|
||||
return start + 1
|
||||
}
|
||||
|
||||
// FindEndOfCurrentWord returns an index relative to the cursor position.
|
||||
// pointing to the end of the current word. Return 0 if nothing was found.
|
||||
func (d *Document) FindEndOfCurrentWord() int {
|
||||
x := d.TextAfterCursor()
|
||||
i := strings.IndexByte(x, ' ')
|
||||
if i != -1 {
|
||||
return i
|
||||
}
|
||||
return len(x)
|
||||
}
|
||||
|
||||
// FindEndOfCurrentWordWithSpace is almost the same as FindEndOfCurrentWord.
|
||||
// The only difference is to ignore contiguous spaces.
|
||||
func (d *Document) FindEndOfCurrentWordWithSpace() int {
|
||||
x := d.TextAfterCursor()
|
||||
|
||||
start := indexByteNot(x, ' ')
|
||||
if start == -1 {
|
||||
return len(x)
|
||||
}
|
||||
|
||||
end := strings.IndexByte(x[start:], ' ')
|
||||
if end == -1 {
|
||||
return len(x)
|
||||
}
|
||||
|
||||
return start + end
|
||||
}
|
||||
|
||||
// FindEndOfCurrentWordUntilSeparator is almost the same as FindEndOfCurrentWord.
|
||||
// But this can specify Separator. Return 0 if nothing was found.
|
||||
func (d *Document) FindEndOfCurrentWordUntilSeparator(sep string) int {
|
||||
if sep == "" {
|
||||
return d.FindEndOfCurrentWord()
|
||||
}
|
||||
|
||||
x := d.TextAfterCursor()
|
||||
i := strings.IndexAny(x, sep)
|
||||
if i != -1 {
|
||||
return i
|
||||
}
|
||||
return len(x)
|
||||
}
|
||||
|
||||
// FindEndOfCurrentWordUntilSeparatorIgnoreNextToCursor is almost the same as FindEndOfCurrentWordWithSpace.
|
||||
// But this can specify Separator. Return 0 if nothing was found.
|
||||
func (d *Document) FindEndOfCurrentWordUntilSeparatorIgnoreNextToCursor(sep string) int {
|
||||
if sep == "" {
|
||||
return d.FindEndOfCurrentWordWithSpace()
|
||||
}
|
||||
|
||||
x := d.TextAfterCursor()
|
||||
|
||||
start := indexAnyNot(x, sep)
|
||||
if start == -1 {
|
||||
return len(x)
|
||||
}
|
||||
|
||||
end := strings.IndexAny(x[start:], sep)
|
||||
if end == -1 {
|
||||
return len(x)
|
||||
}
|
||||
|
||||
return start + end
|
||||
}
|
||||
|
||||
// CurrentLineBeforeCursor returns the text from the start of the line until the cursor.
|
||||
func (d *Document) CurrentLineBeforeCursor() string {
|
||||
s := strings.Split(d.TextBeforeCursor(), "\n")
|
||||
return s[len(s)-1]
|
||||
}
|
||||
|
||||
// CurrentLineAfterCursor returns the text from the cursor until the end of the line.
|
||||
func (d *Document) CurrentLineAfterCursor() string {
|
||||
return strings.Split(d.TextAfterCursor(), "\n")[0]
|
||||
}
|
||||
|
||||
// CurrentLine return the text on the line where the cursor is. (when the input
|
||||
// consists of just one line, it equals `text`.
|
||||
func (d *Document) CurrentLine() string {
|
||||
return d.CurrentLineBeforeCursor() + d.CurrentLineAfterCursor()
|
||||
}
|
||||
|
||||
// Array pointing to the start indexes of all the lines.
|
||||
func (d *Document) lineStartIndexes() []int {
|
||||
// TODO: Cache, because this is often reused.
|
||||
// (If it is used, it's often used many times.
|
||||
// And this has to be fast for editing big documents!)
|
||||
lc := d.LineCount()
|
||||
lengths := make([]int, lc)
|
||||
for i, l := range d.Lines() {
|
||||
lengths[i] = len(l)
|
||||
}
|
||||
|
||||
// Calculate cumulative sums.
|
||||
indexes := make([]int, lc+1)
|
||||
indexes[0] = 0 // https://github.com/jonathanslenders/python-prompt-toolkit/blob/master/prompt_toolkit/document.py#L189
|
||||
pos := 0
|
||||
for i, l := range lengths {
|
||||
pos += l + 1
|
||||
indexes[i+1] = pos
|
||||
}
|
||||
if lc > 1 {
|
||||
// Pop the last item. (This is not a new line.)
|
||||
indexes = indexes[:lc]
|
||||
}
|
||||
return indexes
|
||||
}
|
||||
|
||||
// For the index of a character at a certain line, calculate the index of
|
||||
// the first character on that line.
|
||||
func (d *Document) findLineStartIndex(index int) (pos int, lineStartIndex int) {
|
||||
indexes := d.lineStartIndexes()
|
||||
pos = bisectRight(indexes, index) - 1
|
||||
lineStartIndex = indexes[pos]
|
||||
return
|
||||
}
|
||||
|
||||
// CursorPositionRow returns the current row. (0-based.)
|
||||
func (d *Document) CursorPositionRow() (row int) {
|
||||
row, _ = d.findLineStartIndex(d.cursorPosition)
|
||||
return
|
||||
}
|
||||
|
||||
// CursorPositionCol returns the current column. (0-based.)
|
||||
func (d *Document) CursorPositionCol() (col int) {
|
||||
// Don't use self.text_before_cursor to calculate this. Creating substrings
|
||||
// and splitting is too expensive for getting the cursor position.
|
||||
_, index := d.findLineStartIndex(d.cursorPosition)
|
||||
col = d.cursorPosition - index
|
||||
return
|
||||
}
|
||||
|
||||
// GetCursorLeftPosition returns the relative position for cursor left.
|
||||
func (d *Document) GetCursorLeftPosition(count int) int {
|
||||
if count < 0 {
|
||||
return d.GetCursorRightPosition(-count)
|
||||
}
|
||||
if d.CursorPositionCol() > count {
|
||||
return -count
|
||||
}
|
||||
return -d.CursorPositionCol()
|
||||
}
|
||||
|
||||
// GetCursorRightPosition returns relative position for cursor right.
|
||||
func (d *Document) GetCursorRightPosition(count int) int {
|
||||
if count < 0 {
|
||||
return d.GetCursorLeftPosition(-count)
|
||||
}
|
||||
if len(d.CurrentLineAfterCursor()) > count {
|
||||
return count
|
||||
}
|
||||
return len(d.CurrentLineAfterCursor())
|
||||
}
|
||||
|
||||
// GetCursorUpPosition return the relative cursor position (character index) where we would be
|
||||
// if the user pressed the arrow-up button.
|
||||
func (d *Document) GetCursorUpPosition(count int, preferredColumn int) int {
|
||||
var col int
|
||||
if preferredColumn == -1 { // -1 means nil
|
||||
col = d.CursorPositionCol()
|
||||
} else {
|
||||
col = preferredColumn
|
||||
}
|
||||
|
||||
row := d.CursorPositionRow() - count
|
||||
if row < 0 {
|
||||
row = 0
|
||||
}
|
||||
return d.TranslateRowColToIndex(row, col) - d.cursorPosition
|
||||
}
|
||||
|
||||
// GetCursorDownPosition return the relative cursor position (character index) where we would be if the
|
||||
// user pressed the arrow-down button.
|
||||
func (d *Document) GetCursorDownPosition(count int, preferredColumn int) int {
|
||||
var col int
|
||||
if preferredColumn == -1 { // -1 means nil
|
||||
col = d.CursorPositionCol()
|
||||
} else {
|
||||
col = preferredColumn
|
||||
}
|
||||
row := d.CursorPositionRow() + count
|
||||
return d.TranslateRowColToIndex(row, col) - d.cursorPosition
|
||||
}
|
||||
|
||||
// Lines returns the array of all the lines.
|
||||
func (d *Document) Lines() []string {
|
||||
// TODO: Cache, because this one is reused very often.
|
||||
return strings.Split(d.Text, "\n")
|
||||
}
|
||||
|
||||
// LineCount return the number of lines in this document. If the document ends
|
||||
// with a trailing \n, that counts as the beginning of a new line.
|
||||
func (d *Document) LineCount() int {
|
||||
return len(d.Lines())
|
||||
}
|
||||
|
||||
// TranslateIndexToPosition given an index for the text, return the corresponding (row, col) tuple.
|
||||
// (0-based. Returns (0, 0) for index=0.)
|
||||
func (d *Document) TranslateIndexToPosition(index int) (row int, col int) {
|
||||
row, rowIndex := d.findLineStartIndex(index)
|
||||
col = index - rowIndex
|
||||
return
|
||||
}
|
||||
|
||||
// TranslateRowColToIndex given a (row, col), return the corresponding index.
|
||||
// (Row and col params are 0-based.)
|
||||
func (d *Document) TranslateRowColToIndex(row int, column int) (index int) {
|
||||
indexes := d.lineStartIndexes()
|
||||
if row < 0 {
|
||||
row = 0
|
||||
} else if row > len(indexes) {
|
||||
row = len(indexes) - 1
|
||||
}
|
||||
index = indexes[row]
|
||||
line := d.Lines()[row]
|
||||
|
||||
// python) result += max(0, min(col, len(line)))
|
||||
if column > 0 || len(line) > 0 {
|
||||
if column > len(line) {
|
||||
index += len(line)
|
||||
} else {
|
||||
index += column
|
||||
}
|
||||
}
|
||||
|
||||
// Keep in range. (len(self.text) is included, because the cursor can be
|
||||
// right after the end of the text as well.)
|
||||
// python) result = max(0, min(result, len(self.text)))
|
||||
if index > len(d.Text) {
|
||||
index = len(d.Text)
|
||||
}
|
||||
if index < 0 {
|
||||
index = 0
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
// OnLastLine returns true when we are at the last line.
|
||||
func (d *Document) OnLastLine() bool {
|
||||
return d.CursorPositionRow() == (d.LineCount() - 1)
|
||||
}
|
||||
|
||||
// GetEndOfLinePosition returns relative position for the end of this line.
|
||||
func (d *Document) GetEndOfLinePosition() int {
|
||||
return len([]rune(d.CurrentLineAfterCursor()))
|
||||
}
|
||||
|
||||
func (d *Document) leadingWhitespaceInCurrentLine() (margin string) {
|
||||
trimmed := strings.TrimSpace(d.CurrentLine())
|
||||
margin = d.CurrentLine()[:len(d.CurrentLine())-len(trimmed)]
|
||||
return
|
||||
}
|
||||
|
||||
// bisectRight to Locate the insertion point for v in a to maintain sorted order.
|
||||
func bisectRight(a []int, v int) int {
|
||||
return bisectRightRange(a, v, 0, len(a))
|
||||
}
|
||||
|
||||
func bisectRightRange(a []int, v int, lo, hi int) int {
|
||||
s := a[lo:hi]
|
||||
return sort.Search(len(s), func(i int) bool {
|
||||
return s[i] > v
|
||||
})
|
||||
}
|
||||
|
||||
func indexByteNot(s string, c byte) int {
|
||||
n := len(s)
|
||||
for i := 0; i < n; i++ {
|
||||
if s[i] != c {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func lastIndexByteNot(s string, c byte) int {
|
||||
for i := len(s) - 1; i >= 0; i-- {
|
||||
if s[i] != c {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
type asciiSet [8]uint32
|
||||
|
||||
func (as *asciiSet) notContains(c byte) bool {
|
||||
return (as[c>>5] & (1 << uint(c&31))) == 0
|
||||
}
|
||||
|
||||
func makeASCIISet(chars string) (as asciiSet, ok bool) {
|
||||
for i := 0; i < len(chars); i++ {
|
||||
c := chars[i]
|
||||
if c >= utf8.RuneSelf {
|
||||
return as, false
|
||||
}
|
||||
as[c>>5] |= 1 << uint(c&31)
|
||||
}
|
||||
return as, true
|
||||
}
|
||||
|
||||
func indexAnyNot(s, chars string) int {
|
||||
if len(chars) > 0 {
|
||||
if len(s) > 8 {
|
||||
if as, isASCII := makeASCIISet(chars); isASCII {
|
||||
for i := 0; i < len(s); i++ {
|
||||
if as.notContains(s[i]) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(s); {
|
||||
// I don't know why strings.IndexAny doesn't add rune count here.
|
||||
r, size := utf8.DecodeRuneInString(s[i:])
|
||||
i += size
|
||||
for _, c := range chars {
|
||||
if r != c {
|
||||
return i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func lastIndexAnyNot(s, chars string) int {
|
||||
if len(chars) > 0 {
|
||||
if len(s) > 8 {
|
||||
if as, isASCII := makeASCIISet(chars); isASCII {
|
||||
for i := len(s) - 1; i >= 0; i-- {
|
||||
if as.notContains(s[i]) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
}
|
||||
for i := len(s); i > 0; {
|
||||
r, size := utf8.DecodeLastRuneInString(s[:i])
|
||||
i -= size
|
||||
for _, c := range chars {
|
||||
if r != c {
|
||||
return i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
119
vendor/github.com/c-bata/go-prompt/emacs.go
generated
vendored
Normal file
119
vendor/github.com/c-bata/go-prompt/emacs.go
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
package prompt
|
||||
|
||||
/*
|
||||
|
||||
========
|
||||
PROGRESS
|
||||
========
|
||||
|
||||
Moving the cursor
|
||||
-----------------
|
||||
|
||||
* [x] Ctrl + a Go to the beginning of the line (Home)
|
||||
* [x] Ctrl + e Go to the End of the line (End)
|
||||
* [x] Ctrl + p Previous command (Up arrow)
|
||||
* [x] Ctrl + n Next command (Down arrow)
|
||||
* [x] Ctrl + f Forward one character
|
||||
* [x] Ctrl + b Backward one character
|
||||
* [x] Ctrl + xx Toggle between the start of line and current cursor position
|
||||
|
||||
Editing
|
||||
-------
|
||||
|
||||
* [x] Ctrl + L Clear the Screen, similar to the clear command
|
||||
* [x] Ctrl + d Delete character under the cursor
|
||||
* [x] Ctrl + h Delete character before the cursor (Backspace)
|
||||
|
||||
* [x] Ctrl + w Cut the Word before the cursor to the clipboard.
|
||||
* [x] Ctrl + k Cut the Line after the cursor to the clipboard.
|
||||
* [x] Ctrl + u Cut/delete the Line before the cursor to the clipboard.
|
||||
|
||||
* [ ] Ctrl + t Swap the last two characters before the cursor (typo).
|
||||
* [ ] Esc + t Swap the last two words before the cursor.
|
||||
|
||||
* [ ] ctrl + y Paste the last thing to be cut (yank)
|
||||
* [ ] ctrl + _ Undo
|
||||
|
||||
*/
|
||||
|
||||
var emacsKeyBindings = []KeyBind{
|
||||
// Go to the End of the line
|
||||
{
|
||||
Key: ControlE,
|
||||
Fn: func(buf *Buffer) {
|
||||
x := []rune(buf.Document().TextAfterCursor())
|
||||
buf.CursorRight(len(x))
|
||||
},
|
||||
},
|
||||
// Go to the beginning of the line
|
||||
{
|
||||
Key: ControlA,
|
||||
Fn: func(buf *Buffer) {
|
||||
x := []rune(buf.Document().TextBeforeCursor())
|
||||
buf.CursorLeft(len(x))
|
||||
},
|
||||
},
|
||||
// Cut the Line after the cursor
|
||||
{
|
||||
Key: ControlK,
|
||||
Fn: func(buf *Buffer) {
|
||||
x := []rune(buf.Document().TextAfterCursor())
|
||||
buf.Delete(len(x))
|
||||
},
|
||||
},
|
||||
// Cut/delete the Line before the cursor
|
||||
{
|
||||
Key: ControlU,
|
||||
Fn: func(buf *Buffer) {
|
||||
x := []rune(buf.Document().TextBeforeCursor())
|
||||
buf.DeleteBeforeCursor(len(x))
|
||||
},
|
||||
},
|
||||
// Delete character under the cursor
|
||||
{
|
||||
Key: ControlD,
|
||||
Fn: func(buf *Buffer) {
|
||||
if buf.Text() != "" {
|
||||
buf.Delete(1)
|
||||
}
|
||||
},
|
||||
},
|
||||
// Backspace
|
||||
{
|
||||
Key: ControlH,
|
||||
Fn: func(buf *Buffer) {
|
||||
buf.DeleteBeforeCursor(1)
|
||||
},
|
||||
},
|
||||
// Right allow: Forward one character
|
||||
{
|
||||
Key: ControlF,
|
||||
Fn: func(buf *Buffer) {
|
||||
buf.CursorRight(1)
|
||||
},
|
||||
},
|
||||
// Left allow: Backward one character
|
||||
{
|
||||
Key: ControlB,
|
||||
Fn: func(buf *Buffer) {
|
||||
buf.CursorLeft(1)
|
||||
},
|
||||
},
|
||||
// Cut the Word before the cursor.
|
||||
{
|
||||
Key: ControlW,
|
||||
Fn: func(buf *Buffer) {
|
||||
buf.DeleteBeforeCursor(len([]rune(buf.Document().GetWordBeforeCursorWithSpace())))
|
||||
},
|
||||
},
|
||||
// Clear the Screen, similar to the clear command
|
||||
{
|
||||
Key: ControlL,
|
||||
Fn: func(buf *Buffer) {
|
||||
out := NewStandardOutputWriter()
|
||||
out.EraseScreen()
|
||||
out.CursorGoTo(0, 0)
|
||||
out.Flush()
|
||||
},
|
||||
},
|
||||
}
|
||||
72
vendor/github.com/c-bata/go-prompt/filter.go
generated
vendored
Normal file
72
vendor/github.com/c-bata/go-prompt/filter.go
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
package prompt
|
||||
|
||||
import "strings"
|
||||
|
||||
// Filter is the type to filter the prompt.Suggestion array.
|
||||
type Filter func([]Suggest, string, bool) []Suggest
|
||||
|
||||
// FilterHasPrefix checks whether the string completions.Text begins with sub.
|
||||
func FilterHasPrefix(completions []Suggest, sub string, ignoreCase bool) []Suggest {
|
||||
if sub == "" {
|
||||
return completions
|
||||
}
|
||||
if ignoreCase {
|
||||
sub = strings.ToUpper(sub)
|
||||
}
|
||||
|
||||
ret := make([]Suggest, 0, len(completions))
|
||||
for i := range completions {
|
||||
c := completions[i].Text
|
||||
if ignoreCase {
|
||||
c = strings.ToUpper(c)
|
||||
}
|
||||
if strings.HasPrefix(c, sub) {
|
||||
ret = append(ret, completions[i])
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// FilterHasSuffix checks whether the completion.Text ends with sub.
|
||||
func FilterHasSuffix(completions []Suggest, sub string, ignoreCase bool) []Suggest {
|
||||
if sub == "" {
|
||||
return completions
|
||||
}
|
||||
if ignoreCase {
|
||||
sub = strings.ToUpper(sub)
|
||||
}
|
||||
|
||||
ret := make([]Suggest, 0, len(completions))
|
||||
for i := range completions {
|
||||
c := completions[i].Text
|
||||
if ignoreCase {
|
||||
c = strings.ToUpper(c)
|
||||
}
|
||||
if strings.HasSuffix(c, sub) {
|
||||
ret = append(ret, completions[i])
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// FilterContains checks whether the completion.Text contains sub.
|
||||
func FilterContains(completions []Suggest, sub string, ignoreCase bool) []Suggest {
|
||||
if sub == "" {
|
||||
return completions
|
||||
}
|
||||
if ignoreCase {
|
||||
sub = strings.ToUpper(sub)
|
||||
}
|
||||
|
||||
ret := make([]Suggest, 0, len(completions))
|
||||
for i := range completions {
|
||||
c := completions[i].Text
|
||||
if ignoreCase {
|
||||
c = strings.ToUpper(c)
|
||||
}
|
||||
if strings.Contains(c, sub) {
|
||||
ret = append(ret, completions[i])
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
61
vendor/github.com/c-bata/go-prompt/history.go
generated
vendored
Normal file
61
vendor/github.com/c-bata/go-prompt/history.go
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
package prompt
|
||||
|
||||
// History stores the texts that are entered.
|
||||
type History struct {
|
||||
histories []string
|
||||
tmp []string
|
||||
selected int
|
||||
}
|
||||
|
||||
// Add to add text in history.
|
||||
func (h *History) Add(input string) {
|
||||
h.histories = append(h.histories, input)
|
||||
h.Clear()
|
||||
}
|
||||
|
||||
// Clear to clear the history.
|
||||
func (h *History) Clear() {
|
||||
h.tmp = make([]string, len(h.histories))
|
||||
for i := range h.histories {
|
||||
h.tmp[i] = h.histories[i]
|
||||
}
|
||||
h.tmp = append(h.tmp, "")
|
||||
h.selected = len(h.tmp) - 1
|
||||
}
|
||||
|
||||
// Older saves a buffer of current line and get a buffer of previous line by up-arrow.
|
||||
// The changes of line buffers are stored until new history is created.
|
||||
func (h *History) Older(buf *Buffer) (new *Buffer, changed bool) {
|
||||
if len(h.tmp) == 1 || h.selected == 0 {
|
||||
return buf, false
|
||||
}
|
||||
h.tmp[h.selected] = buf.Text()
|
||||
|
||||
h.selected--
|
||||
new = NewBuffer()
|
||||
new.InsertText(h.tmp[h.selected], false, true)
|
||||
return new, true
|
||||
}
|
||||
|
||||
// Newer saves a buffer of current line and get a buffer of next line by up-arrow.
|
||||
// The changes of line buffers are stored until new history is created.
|
||||
func (h *History) Newer(buf *Buffer) (new *Buffer, changed bool) {
|
||||
if h.selected >= len(h.tmp)-1 {
|
||||
return buf, false
|
||||
}
|
||||
h.tmp[h.selected] = buf.Text()
|
||||
|
||||
h.selected++
|
||||
new = NewBuffer()
|
||||
new.InsertText(h.tmp[h.selected], false, true)
|
||||
return new, true
|
||||
}
|
||||
|
||||
// NewHistory returns new history object.
|
||||
func NewHistory() *History {
|
||||
return &History{
|
||||
histories: []string{},
|
||||
tmp: []string{""},
|
||||
selected: 0,
|
||||
}
|
||||
}
|
||||
158
vendor/github.com/c-bata/go-prompt/input.go
generated
vendored
Normal file
158
vendor/github.com/c-bata/go-prompt/input.go
generated
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
package prompt
|
||||
|
||||
// WinSize represents the width and height of terminal.
|
||||
type WinSize struct {
|
||||
Row uint16
|
||||
Col uint16
|
||||
}
|
||||
|
||||
// ConsoleParser is an interface to abstract input layer.
|
||||
type ConsoleParser interface {
|
||||
// Setup should be called before starting input
|
||||
Setup() error
|
||||
// TearDown should be called after stopping input
|
||||
TearDown() error
|
||||
// GetKey returns Key correspond to input byte codes.
|
||||
GetKey(b []byte) Key
|
||||
// GetWinSize returns WinSize object to represent width and height of terminal.
|
||||
GetWinSize() *WinSize
|
||||
// Read returns byte array.
|
||||
Read() ([]byte, error)
|
||||
}
|
||||
|
||||
var asciiSequences = []*ASCIICode{
|
||||
{Key: Escape, ASCIICode: []byte{0x1b}},
|
||||
|
||||
{Key: ControlSpace, ASCIICode: []byte{0x00}},
|
||||
{Key: ControlA, ASCIICode: []byte{0x1}},
|
||||
{Key: ControlB, ASCIICode: []byte{0x2}},
|
||||
{Key: ControlC, ASCIICode: []byte{0x3}},
|
||||
{Key: ControlD, ASCIICode: []byte{0x4}},
|
||||
{Key: ControlE, ASCIICode: []byte{0x5}},
|
||||
{Key: ControlF, ASCIICode: []byte{0x6}},
|
||||
{Key: ControlG, ASCIICode: []byte{0x7}},
|
||||
{Key: ControlH, ASCIICode: []byte{0x8}},
|
||||
//{Key: ControlI, ASCIICode: []byte{0x9}},
|
||||
//{Key: ControlJ, ASCIICode: []byte{0xa}},
|
||||
{Key: ControlK, ASCIICode: []byte{0xb}},
|
||||
{Key: ControlL, ASCIICode: []byte{0xc}},
|
||||
{Key: ControlM, ASCIICode: []byte{0xd}},
|
||||
{Key: ControlN, ASCIICode: []byte{0xe}},
|
||||
{Key: ControlO, ASCIICode: []byte{0xf}},
|
||||
{Key: ControlP, ASCIICode: []byte{0x10}},
|
||||
{Key: ControlQ, ASCIICode: []byte{0x11}},
|
||||
{Key: ControlR, ASCIICode: []byte{0x12}},
|
||||
{Key: ControlS, ASCIICode: []byte{0x13}},
|
||||
{Key: ControlT, ASCIICode: []byte{0x14}},
|
||||
{Key: ControlU, ASCIICode: []byte{0x15}},
|
||||
{Key: ControlV, ASCIICode: []byte{0x16}},
|
||||
{Key: ControlW, ASCIICode: []byte{0x17}},
|
||||
{Key: ControlX, ASCIICode: []byte{0x18}},
|
||||
{Key: ControlY, ASCIICode: []byte{0x19}},
|
||||
{Key: ControlZ, ASCIICode: []byte{0x1a}},
|
||||
|
||||
{Key: ControlBackslash, ASCIICode: []byte{0x1c}},
|
||||
{Key: ControlSquareClose, ASCIICode: []byte{0x1d}},
|
||||
{Key: ControlCircumflex, ASCIICode: []byte{0x1e}},
|
||||
{Key: ControlUnderscore, ASCIICode: []byte{0x1f}},
|
||||
{Key: Backspace, ASCIICode: []byte{0x7f}},
|
||||
|
||||
{Key: Up, ASCIICode: []byte{0x1b, 0x5b, 0x41}},
|
||||
{Key: Down, ASCIICode: []byte{0x1b, 0x5b, 0x42}},
|
||||
{Key: Right, ASCIICode: []byte{0x1b, 0x5b, 0x43}},
|
||||
{Key: Left, ASCIICode: []byte{0x1b, 0x5b, 0x44}},
|
||||
{Key: Home, ASCIICode: []byte{0x1b, 0x5b, 0x48}},
|
||||
{Key: Home, ASCIICode: []byte{0x1b, 0x30, 0x48}},
|
||||
{Key: End, ASCIICode: []byte{0x1b, 0x5b, 0x46}},
|
||||
{Key: End, ASCIICode: []byte{0x1b, 0x30, 0x46}},
|
||||
|
||||
{Key: Enter, ASCIICode: []byte{0xa}},
|
||||
{Key: Delete, ASCIICode: []byte{0x1b, 0x5b, 0x33, 0x7e}},
|
||||
{Key: ShiftDelete, ASCIICode: []byte{0x1b, 0x5b, 0x33, 0x3b, 0x32, 0x7e}},
|
||||
{Key: ControlDelete, ASCIICode: []byte{0x1b, 0x5b, 0x33, 0x3b, 0x35, 0x7e}},
|
||||
{Key: Home, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x7e}},
|
||||
{Key: End, ASCIICode: []byte{0x1b, 0x5b, 0x34, 0x7e}},
|
||||
{Key: PageUp, ASCIICode: []byte{0x1b, 0x5b, 0x35, 0x7e}},
|
||||
{Key: PageDown, ASCIICode: []byte{0x1b, 0x5b, 0x36, 0x7e}},
|
||||
{Key: Home, ASCIICode: []byte{0x1b, 0x5b, 0x37, 0x7e}},
|
||||
{Key: End, ASCIICode: []byte{0x1b, 0x5b, 0x38, 0x7e}},
|
||||
{Key: Tab, ASCIICode: []byte{0x9}},
|
||||
{Key: BackTab, ASCIICode: []byte{0x1b, 0x5b, 0x5a}},
|
||||
{Key: Insert, ASCIICode: []byte{0x1b, 0x5b, 0x32, 0x7e}},
|
||||
|
||||
{Key: F1, ASCIICode: []byte{0x1b, 0x4f, 0x50}},
|
||||
{Key: F2, ASCIICode: []byte{0x1b, 0x4f, 0x51}},
|
||||
{Key: F3, ASCIICode: []byte{0x1b, 0x4f, 0x52}},
|
||||
{Key: F4, ASCIICode: []byte{0x1b, 0x4f, 0x53}},
|
||||
|
||||
{Key: F1, ASCIICode: []byte{0x1b, 0x4f, 0x50, 0x41}}, // Linux console
|
||||
{Key: F2, ASCIICode: []byte{0x1b, 0x5b, 0x5b, 0x42}}, // Linux console
|
||||
{Key: F3, ASCIICode: []byte{0x1b, 0x5b, 0x5b, 0x43}}, // Linux console
|
||||
{Key: F4, ASCIICode: []byte{0x1b, 0x5b, 0x5b, 0x44}}, // Linux console
|
||||
{Key: F5, ASCIICode: []byte{0x1b, 0x5b, 0x5b, 0x45}}, // Linux console
|
||||
|
||||
{Key: F1, ASCIICode: []byte{0x1b, 0x5b, 0x11, 0x7e}}, // rxvt-unicode
|
||||
{Key: F2, ASCIICode: []byte{0x1b, 0x5b, 0x12, 0x7e}}, // rxvt-unicode
|
||||
{Key: F3, ASCIICode: []byte{0x1b, 0x5b, 0x13, 0x7e}}, // rxvt-unicode
|
||||
{Key: F4, ASCIICode: []byte{0x1b, 0x5b, 0x14, 0x7e}}, // rxvt-unicode
|
||||
|
||||
{Key: F5, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x35, 0x7e}},
|
||||
{Key: F6, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x37, 0x7e}},
|
||||
{Key: F7, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x38, 0x7e}},
|
||||
{Key: F8, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x39, 0x7e}},
|
||||
{Key: F9, ASCIICode: []byte{0x1b, 0x5b, 0x32, 0x30, 0x7e}},
|
||||
{Key: F10, ASCIICode: []byte{0x1b, 0x5b, 0x32, 0x31, 0x7e}},
|
||||
{Key: F11, ASCIICode: []byte{0x1b, 0x5b, 0x32, 0x32, 0x7e}},
|
||||
{Key: F12, ASCIICode: []byte{0x1b, 0x5b, 0x32, 0x34, 0x7e, 0x8}},
|
||||
{Key: F13, ASCIICode: []byte{0x1b, 0x5b, 0x25, 0x7e}},
|
||||
{Key: F14, ASCIICode: []byte{0x1b, 0x5b, 0x26, 0x7e}},
|
||||
{Key: F15, ASCIICode: []byte{0x1b, 0x5b, 0x28, 0x7e}},
|
||||
{Key: F16, ASCIICode: []byte{0x1b, 0x5b, 0x29, 0x7e}},
|
||||
{Key: F17, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x7e}},
|
||||
{Key: F18, ASCIICode: []byte{0x1b, 0x5b, 0x32, 0x7e}},
|
||||
{Key: F19, ASCIICode: []byte{0x1b, 0x5b, 0x33, 0x7e}},
|
||||
{Key: F20, ASCIICode: []byte{0x1b, 0x5b, 0x34, 0x7e}},
|
||||
|
||||
// Xterm
|
||||
{Key: F13, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x3b, 0x32, 0x50}},
|
||||
{Key: F14, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x3b, 0x32, 0x51}},
|
||||
// &ASCIICode{Key: F15, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x3b, 0x32, 0x52}}, // Conflicts with CPR response
|
||||
{Key: F16, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x3b, 0x32, 0x52}},
|
||||
{Key: F17, ASCIICode: []byte{0x1b, 0x5b, 0x15, 0x3b, 0x32, 0x7e}},
|
||||
{Key: F18, ASCIICode: []byte{0x1b, 0x5b, 0x17, 0x3b, 0x32, 0x7e}},
|
||||
{Key: F19, ASCIICode: []byte{0x1b, 0x5b, 0x18, 0x3b, 0x32, 0x7e}},
|
||||
{Key: F20, ASCIICode: []byte{0x1b, 0x5b, 0x19, 0x3b, 0x32, 0x7e}},
|
||||
{Key: F21, ASCIICode: []byte{0x1b, 0x5b, 0x20, 0x3b, 0x32, 0x7e}},
|
||||
{Key: F22, ASCIICode: []byte{0x1b, 0x5b, 0x21, 0x3b, 0x32, 0x7e}},
|
||||
{Key: F23, ASCIICode: []byte{0x1b, 0x5b, 0x23, 0x3b, 0x32, 0x7e}},
|
||||
{Key: F24, ASCIICode: []byte{0x1b, 0x5b, 0x24, 0x3b, 0x32, 0x7e}},
|
||||
|
||||
{Key: ControlUp, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x3b, 0x35, 0x41}},
|
||||
{Key: ControlDown, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x3b, 0x35, 0x42}},
|
||||
{Key: ControlRight, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x3b, 0x35, 0x43}},
|
||||
{Key: ControlLeft, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x3b, 0x35, 0x44}},
|
||||
|
||||
{Key: ShiftUp, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x3b, 0x32, 0x41}},
|
||||
{Key: ShiftDown, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x3b, 0x32, 0x42}},
|
||||
{Key: ShiftRight, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x3b, 0x32, 0x43}},
|
||||
{Key: ShiftLeft, ASCIICode: []byte{0x1b, 0x5b, 0x31, 0x3b, 0x32, 0x44}},
|
||||
|
||||
// Tmux sends following keystrokes when control+arrow is pressed, but for
|
||||
// Emacs ansi-term sends the same sequences for normal arrow keys. Consider
|
||||
// it a normal arrow press, because that's more important.
|
||||
{Key: Up, ASCIICode: []byte{0x1b, 0x4f, 0x41}},
|
||||
{Key: Down, ASCIICode: []byte{0x1b, 0x4f, 0x42}},
|
||||
{Key: Right, ASCIICode: []byte{0x1b, 0x4f, 0x43}},
|
||||
{Key: Left, ASCIICode: []byte{0x1b, 0x4f, 0x44}},
|
||||
|
||||
{Key: ControlUp, ASCIICode: []byte{0x1b, 0x5b, 0x35, 0x41}},
|
||||
{Key: ControlDown, ASCIICode: []byte{0x1b, 0x5b, 0x35, 0x42}},
|
||||
{Key: ControlRight, ASCIICode: []byte{0x1b, 0x5b, 0x35, 0x43}},
|
||||
{Key: ControlLeft, ASCIICode: []byte{0x1b, 0x5b, 0x35, 0x44}},
|
||||
|
||||
{Key: ControlRight, ASCIICode: []byte{0x1b, 0x5b, 0x4f, 0x63}}, // rxvt
|
||||
{Key: ControlLeft, ASCIICode: []byte{0x1b, 0x5b, 0x4f, 0x64}}, // rxvt
|
||||
|
||||
{Key: Ignore, ASCIICode: []byte{0x1b, 0x5b, 0x45}}, // Xterm
|
||||
{Key: Ignore, ASCIICode: []byte{0x1b, 0x5b, 0x46}}, // Linux console
|
||||
}
|
||||
128
vendor/github.com/c-bata/go-prompt/input_posix.go
generated
vendored
Normal file
128
vendor/github.com/c-bata/go-prompt/input_posix.go
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
// +build !windows
|
||||
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/pkg/term/termios"
|
||||
)
|
||||
|
||||
const maxReadBytes = 1024
|
||||
|
||||
// PosixParser is a ConsoleParser implementation for POSIX environment.
|
||||
type PosixParser struct {
|
||||
fd int
|
||||
origTermios syscall.Termios
|
||||
}
|
||||
|
||||
// Setup should be called before starting input
|
||||
func (t *PosixParser) Setup() error {
|
||||
// Set NonBlocking mode because if syscall.Read block this goroutine, it cannot receive data from stopCh.
|
||||
if err := syscall.SetNonblock(t.fd, true); err != nil {
|
||||
log.Println("[ERROR] Cannot set non blocking mode.")
|
||||
return err
|
||||
}
|
||||
if err := t.setRawMode(); err != nil {
|
||||
log.Println("[ERROR] Cannot set raw mode.")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TearDown should be called after stopping input
|
||||
func (t *PosixParser) TearDown() error {
|
||||
if err := syscall.SetNonblock(t.fd, false); err != nil {
|
||||
log.Println("[ERROR] Cannot set blocking mode.")
|
||||
return err
|
||||
}
|
||||
if err := t.resetRawMode(); err != nil {
|
||||
log.Println("[ERROR] Cannot reset from raw mode.")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Read returns byte array.
|
||||
func (t *PosixParser) Read() ([]byte, error) {
|
||||
buf := make([]byte, maxReadBytes)
|
||||
n, err := syscall.Read(syscall.Stdin, buf)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
return buf[:n], nil
|
||||
}
|
||||
|
||||
func (t *PosixParser) setRawMode() error {
|
||||
x := t.origTermios.Lflag
|
||||
if x &^= syscall.ICANON; x != 0 && x == t.origTermios.Lflag {
|
||||
// fd is already raw mode
|
||||
return nil
|
||||
}
|
||||
var n syscall.Termios
|
||||
if err := termios.Tcgetattr(uintptr(t.fd), &t.origTermios); err != nil {
|
||||
return err
|
||||
}
|
||||
n = t.origTermios
|
||||
// "&^=" used like: https://play.golang.org/p/8eJw3JxS4O
|
||||
n.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.IEXTEN | syscall.ISIG
|
||||
n.Cc[syscall.VMIN] = 1
|
||||
n.Cc[syscall.VTIME] = 0
|
||||
termios.Tcsetattr(uintptr(t.fd), termios.TCSANOW, &n)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *PosixParser) resetRawMode() error {
|
||||
if t.origTermios.Lflag == 0 {
|
||||
return nil
|
||||
}
|
||||
return termios.Tcsetattr(uintptr(t.fd), termios.TCSANOW, &t.origTermios)
|
||||
}
|
||||
|
||||
// GetKey returns Key correspond to input byte codes.
|
||||
func (t *PosixParser) GetKey(b []byte) Key {
|
||||
for _, k := range asciiSequences {
|
||||
if bytes.Equal(k.ASCIICode, b) {
|
||||
return k.Key
|
||||
}
|
||||
}
|
||||
return NotDefined
|
||||
}
|
||||
|
||||
// winsize is winsize struct got from the ioctl(2) system call.
|
||||
type ioctlWinsize struct {
|
||||
Row uint16
|
||||
Col uint16
|
||||
X uint16 // pixel value
|
||||
Y uint16 // pixel value
|
||||
}
|
||||
|
||||
// GetWinSize returns WinSize object to represent width and height of terminal.
|
||||
func (t *PosixParser) GetWinSize() *WinSize {
|
||||
ws := &ioctlWinsize{}
|
||||
retCode, _, errno := syscall.Syscall(
|
||||
syscall.SYS_IOCTL,
|
||||
uintptr(t.fd),
|
||||
uintptr(syscall.TIOCGWINSZ),
|
||||
uintptr(unsafe.Pointer(ws)))
|
||||
|
||||
if int(retCode) == -1 {
|
||||
panic(errno)
|
||||
}
|
||||
return &WinSize{
|
||||
Row: ws.Row,
|
||||
Col: ws.Col,
|
||||
}
|
||||
}
|
||||
|
||||
var _ ConsoleParser = &PosixParser{}
|
||||
|
||||
// NewStandardInputParser returns ConsoleParser object to read from stdin.
|
||||
func NewStandardInputParser() *PosixParser {
|
||||
return &PosixParser{
|
||||
fd: syscall.Stdin,
|
||||
}
|
||||
}
|
||||
94
vendor/github.com/c-bata/go-prompt/input_windows.go
generated
vendored
Normal file
94
vendor/github.com/c-bata/go-prompt/input_windows.go
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
// +build windows
|
||||
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"syscall"
|
||||
"unicode/utf8"
|
||||
"unsafe"
|
||||
|
||||
"github.com/mattn/go-tty"
|
||||
)
|
||||
|
||||
const maxReadBytes = 1024
|
||||
|
||||
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
|
||||
var procGetNumberOfConsoleInputEvents = kernel32.NewProc("GetNumberOfConsoleInputEvents")
|
||||
|
||||
// WindowsParser is a ConsoleParser implementation for Win32 console.
|
||||
type WindowsParser struct {
|
||||
tty *tty.TTY
|
||||
}
|
||||
|
||||
// Setup should be called before starting input
|
||||
func (p *WindowsParser) Setup() error {
|
||||
t, err := tty.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.tty = t
|
||||
return nil
|
||||
}
|
||||
|
||||
// TearDown should be called after stopping input
|
||||
func (p *WindowsParser) TearDown() error {
|
||||
return p.tty.Close()
|
||||
}
|
||||
|
||||
// GetKey returns Key correspond to input byte codes.
|
||||
func (p *WindowsParser) GetKey(b []byte) Key {
|
||||
for _, k := range asciiSequences {
|
||||
if bytes.Compare(k.ASCIICode, b) == 0 {
|
||||
return k.Key
|
||||
}
|
||||
}
|
||||
return NotDefined
|
||||
}
|
||||
|
||||
// Read returns byte array.
|
||||
func (p *WindowsParser) Read() ([]byte, error) {
|
||||
var ev uint32
|
||||
r0, _, err := procGetNumberOfConsoleInputEvents.Call(p.tty.Input().Fd(), uintptr(unsafe.Pointer(&ev)))
|
||||
if r0 == 0 {
|
||||
return nil, err
|
||||
}
|
||||
if ev == 0 {
|
||||
return nil, errors.New("EAGAIN")
|
||||
}
|
||||
|
||||
r, err := p.tty.ReadRune()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf := make([]byte, maxReadBytes)
|
||||
n := utf8.EncodeRune(buf[:], r)
|
||||
for p.tty.Buffered() && n < maxReadBytes {
|
||||
r, err := p.tty.ReadRune()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
n += utf8.EncodeRune(buf[n:], r)
|
||||
}
|
||||
return buf[:n], nil
|
||||
}
|
||||
|
||||
// GetWinSize returns WinSize object to represent width and height of terminal.
|
||||
func (p *WindowsParser) GetWinSize() *WinSize {
|
||||
w, h, err := p.tty.Size()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &WinSize{
|
||||
Row: uint16(h),
|
||||
Col: uint16(w),
|
||||
}
|
||||
}
|
||||
|
||||
// NewStandardInputParser returns ConsoleParser object to read from stdin.
|
||||
func NewStandardInputParser() *WindowsParser {
|
||||
return &WindowsParser{}
|
||||
}
|
||||
127
vendor/github.com/c-bata/go-prompt/key.go
generated
vendored
Normal file
127
vendor/github.com/c-bata/go-prompt/key.go
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
// Code generated "This is a fake comment to avoid golint errors"; DO NOT EDIT.
|
||||
// FIXME: This is a little bit stupid, but there are many public constants which is no value for writing godoc comment.
|
||||
|
||||
package prompt
|
||||
|
||||
// Key is the type express the key inserted from user.
|
||||
type Key int
|
||||
|
||||
// ASCIICode is the type contains Key and it's ascii byte array.
|
||||
type ASCIICode struct {
|
||||
Key Key
|
||||
ASCIICode []byte
|
||||
}
|
||||
|
||||
const (
|
||||
Escape Key = iota
|
||||
|
||||
ControlA
|
||||
ControlB
|
||||
ControlC
|
||||
ControlD
|
||||
ControlE
|
||||
ControlF
|
||||
ControlG
|
||||
ControlH
|
||||
ControlI
|
||||
ControlJ
|
||||
ControlK
|
||||
ControlL
|
||||
ControlM
|
||||
ControlN
|
||||
ControlO
|
||||
ControlP
|
||||
ControlQ
|
||||
ControlR
|
||||
ControlS
|
||||
ControlT
|
||||
ControlU
|
||||
ControlV
|
||||
ControlW
|
||||
ControlX
|
||||
ControlY
|
||||
ControlZ
|
||||
|
||||
ControlSpace
|
||||
ControlBackslash
|
||||
ControlSquareClose
|
||||
ControlCircumflex
|
||||
ControlUnderscore
|
||||
ControlLeft
|
||||
ControlRight
|
||||
ControlUp
|
||||
ControlDown
|
||||
|
||||
Up
|
||||
Down
|
||||
Right
|
||||
Left
|
||||
|
||||
ShiftLeft
|
||||
ShiftUp
|
||||
ShiftDown
|
||||
ShiftRight
|
||||
|
||||
Home
|
||||
End
|
||||
Delete
|
||||
ShiftDelete
|
||||
ControlDelete
|
||||
PageUp
|
||||
PageDown
|
||||
BackTab
|
||||
Insert
|
||||
Backspace
|
||||
|
||||
// Aliases.
|
||||
Tab
|
||||
Enter
|
||||
// Actually Enter equals ControlM, not ControlJ,
|
||||
// However, in prompt_toolkit, we made the mistake of translating
|
||||
// \r into \n during the input, so everyone is now handling the
|
||||
// enter key by binding ControlJ.
|
||||
|
||||
// From now on, it's better to bind `ASCII_SEQUENCES.Enter` everywhere,
|
||||
// because that's future compatible, and will still work when we
|
||||
// stop replacing \r by \n.
|
||||
|
||||
F1
|
||||
F2
|
||||
F3
|
||||
F4
|
||||
F5
|
||||
F6
|
||||
F7
|
||||
F8
|
||||
F9
|
||||
F10
|
||||
F11
|
||||
F12
|
||||
F13
|
||||
F14
|
||||
F15
|
||||
F16
|
||||
F17
|
||||
F18
|
||||
F19
|
||||
F20
|
||||
F21
|
||||
F22
|
||||
F23
|
||||
F24
|
||||
|
||||
// Matches any key.
|
||||
Any
|
||||
|
||||
// Special
|
||||
CPRResponse
|
||||
Vt100MouseEvent
|
||||
WindowsMouseEvent
|
||||
BracketedPaste
|
||||
|
||||
// Key which is ignored. (The key binding for this key should not do anything.)
|
||||
Ignore
|
||||
|
||||
// Key is not defined
|
||||
NotDefined
|
||||
)
|
||||
59
vendor/github.com/c-bata/go-prompt/key_bind.go
generated
vendored
Normal file
59
vendor/github.com/c-bata/go-prompt/key_bind.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
package prompt
|
||||
|
||||
// KeyBindFunc receives buffer and processed it.
|
||||
type KeyBindFunc func(*Buffer)
|
||||
|
||||
// KeyBind represents which key should do what operation.
|
||||
type KeyBind struct {
|
||||
Key Key
|
||||
Fn KeyBindFunc
|
||||
}
|
||||
|
||||
// ASCIICodeBind represents which []byte should do what operation
|
||||
type ASCIICodeBind struct {
|
||||
ASCIICode []byte
|
||||
Fn KeyBindFunc
|
||||
}
|
||||
|
||||
// KeyBindMode to switch a key binding flexibly.
|
||||
type KeyBindMode string
|
||||
|
||||
const (
|
||||
// CommonKeyBind is a mode without any keyboard shortcut
|
||||
CommonKeyBind KeyBindMode = "common"
|
||||
// EmacsKeyBind is a mode to use emacs-like keyboard shortcut
|
||||
EmacsKeyBind KeyBindMode = "emacs"
|
||||
)
|
||||
|
||||
var commonKeyBindings = []KeyBind{
|
||||
// Go to the End of the line
|
||||
{
|
||||
Key: End,
|
||||
Fn: GoLineEnd,
|
||||
},
|
||||
// Go to the beginning of the line
|
||||
{
|
||||
Key: Home,
|
||||
Fn: GoLineBeginning,
|
||||
},
|
||||
// Delete character under the cursor
|
||||
{
|
||||
Key: Delete,
|
||||
Fn: DeleteChar,
|
||||
},
|
||||
// Backspace
|
||||
{
|
||||
Key: Backspace,
|
||||
Fn: DeleteBeforeChar,
|
||||
},
|
||||
// Right allow: Forward one character
|
||||
{
|
||||
Key: Right,
|
||||
Fn: GoRightChar,
|
||||
},
|
||||
// Left allow: Backward one character
|
||||
{
|
||||
Key: Left,
|
||||
Fn: GoLeftChar,
|
||||
},
|
||||
}
|
||||
48
vendor/github.com/c-bata/go-prompt/key_bind_func.go
generated
vendored
Normal file
48
vendor/github.com/c-bata/go-prompt/key_bind_func.go
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
package prompt
|
||||
|
||||
// GoLineEnd Go to the End of the line
|
||||
func GoLineEnd(buf *Buffer) {
|
||||
x := []rune(buf.Document().TextAfterCursor())
|
||||
buf.CursorRight(len(x))
|
||||
}
|
||||
|
||||
// GoLineBeginning Go to the beginning of the line
|
||||
func GoLineBeginning(buf *Buffer) {
|
||||
x := []rune(buf.Document().TextBeforeCursor())
|
||||
buf.CursorLeft(len(x))
|
||||
}
|
||||
|
||||
// DeleteChar Delete character under the cursor
|
||||
func DeleteChar(buf *Buffer) {
|
||||
buf.Delete(1)
|
||||
}
|
||||
|
||||
// DeleteWord Delete word before the cursor
|
||||
func DeleteWord(buf *Buffer) {
|
||||
buf.DeleteBeforeCursor(len([]rune(buf.Document().TextBeforeCursor())) - buf.Document().FindStartOfPreviousWordWithSpace())
|
||||
}
|
||||
|
||||
// DeleteBeforeChar Go to Backspace
|
||||
func DeleteBeforeChar(buf *Buffer) {
|
||||
buf.DeleteBeforeCursor(1)
|
||||
}
|
||||
|
||||
// GoRightChar Forward one character
|
||||
func GoRightChar(buf *Buffer) {
|
||||
buf.CursorRight(1)
|
||||
}
|
||||
|
||||
// GoLeftChar Backward one character
|
||||
func GoLeftChar(buf *Buffer) {
|
||||
buf.CursorLeft(1)
|
||||
}
|
||||
|
||||
// GoRightWord Forward one word
|
||||
func GoRightWord(buf *Buffer) {
|
||||
buf.CursorRight(buf.Document().FindEndOfCurrentWordWithSpace())
|
||||
}
|
||||
|
||||
// GoLeftWord Backward one word
|
||||
func GoLeftWord(buf *Buffer) {
|
||||
buf.CursorLeft(len([]rune(buf.Document().TextBeforeCursor())) - buf.Document().FindStartOfPreviousWordWithSpace())
|
||||
}
|
||||
16
vendor/github.com/c-bata/go-prompt/key_string.go
generated
vendored
Normal file
16
vendor/github.com/c-bata/go-prompt/key_string.go
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// Code generated by "stringer -type=Key"; DO NOT EDIT.
|
||||
|
||||
package prompt
|
||||
|
||||
import "strconv"
|
||||
|
||||
const _Key_name = "EscapeControlAControlBControlCControlDControlEControlFControlGControlHControlIControlJControlKControlLControlMControlNControlOControlPControlQControlRControlSControlTControlUControlVControlWControlXControlYControlZControlSpaceControlBackslashControlSquareCloseControlCircumflexControlUnderscoreControlLeftControlRightControlUpControlDownUpDownRightLeftShiftLeftShiftUpShiftDownShiftRightHomeEndDeleteShiftDeleteControlDeletePageUpPageDownBackTabInsertBackspaceTabEnterF1F2F3F4F5F6F7F8F9F10F11F12F13F14F15F16F17F18F19F20F21F22F23F24AnyCPRResponseVt100MouseEventWindowsMouseEventBracketedPasteIgnoreNotDefined"
|
||||
|
||||
var _Key_index = [...]uint16{0, 6, 14, 22, 30, 38, 46, 54, 62, 70, 78, 86, 94, 102, 110, 118, 126, 134, 142, 150, 158, 166, 174, 182, 190, 198, 206, 214, 226, 242, 260, 277, 294, 305, 317, 326, 337, 339, 343, 348, 352, 361, 368, 377, 387, 391, 394, 400, 411, 424, 430, 438, 445, 451, 460, 463, 468, 470, 472, 474, 476, 478, 480, 482, 484, 486, 489, 492, 495, 498, 501, 504, 507, 510, 513, 516, 519, 522, 525, 528, 531, 534, 545, 560, 577, 591, 597, 607}
|
||||
|
||||
func (i Key) String() string {
|
||||
if i < 0 || i >= Key(len(_Key_index)-1) {
|
||||
return "Key(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _Key_name[_Key_index[i]:_Key_index[i+1]]
|
||||
}
|
||||
266
vendor/github.com/c-bata/go-prompt/option.go
generated
vendored
Normal file
266
vendor/github.com/c-bata/go-prompt/option.go
generated
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
package prompt
|
||||
|
||||
// Option is the type to replace default parameters.
|
||||
// prompt.New accepts any number of options (this is functional option pattern).
|
||||
type Option func(prompt *Prompt) error
|
||||
|
||||
// OptionParser to set a custom ConsoleParser object. An argument should implement ConsoleParser interface.
|
||||
func OptionParser(x ConsoleParser) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.in = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionWriter to set a custom ConsoleWriter object. An argument should implement ConsoleWriter interface.
|
||||
func OptionWriter(x ConsoleWriter) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.out = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionTitle to set title displayed at the header bar of terminal.
|
||||
func OptionTitle(x string) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.title = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionPrefix to set prefix string.
|
||||
func OptionPrefix(x string) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.prefix = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionCompletionWordSeparator to set word separators. Enable only ' ' if empty.
|
||||
func OptionCompletionWordSeparator(x string) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.completion.wordSeparator = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionLivePrefix to change the prefix dynamically by callback function
|
||||
func OptionLivePrefix(f func() (prefix string, useLivePrefix bool)) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.livePrefixCallback = f
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionPrefixTextColor change a text color of prefix string
|
||||
func OptionPrefixTextColor(x Color) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.prefixTextColor = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionPrefixBackgroundColor to change a background color of prefix string
|
||||
func OptionPrefixBackgroundColor(x Color) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.prefixBGColor = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionInputTextColor to change a color of text which is input by user
|
||||
func OptionInputTextColor(x Color) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.inputTextColor = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionInputBGColor to change a color of background which is input by user
|
||||
func OptionInputBGColor(x Color) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.inputBGColor = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionPreviewSuggestionTextColor to change a text color which is completed
|
||||
func OptionPreviewSuggestionTextColor(x Color) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.previewSuggestionTextColor = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionPreviewSuggestionBGColor to change a background color which is completed
|
||||
func OptionPreviewSuggestionBGColor(x Color) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.previewSuggestionBGColor = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionSuggestionTextColor to change a text color in drop down suggestions.
|
||||
func OptionSuggestionTextColor(x Color) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.suggestionTextColor = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionSuggestionBGColor change a background color in drop down suggestions.
|
||||
func OptionSuggestionBGColor(x Color) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.suggestionBGColor = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionSelectedSuggestionTextColor to change a text color for completed text which is selected inside suggestions drop down box.
|
||||
func OptionSelectedSuggestionTextColor(x Color) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.selectedSuggestionTextColor = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionSelectedSuggestionBGColor to change a background color for completed text which is selected inside suggestions drop down box.
|
||||
func OptionSelectedSuggestionBGColor(x Color) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.selectedSuggestionBGColor = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionDescriptionTextColor to change a background color of description text in drop down suggestions.
|
||||
func OptionDescriptionTextColor(x Color) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.descriptionTextColor = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionDescriptionBGColor to change a background color of description text in drop down suggestions.
|
||||
func OptionDescriptionBGColor(x Color) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.descriptionBGColor = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionSelectedDescriptionTextColor to change a text color of description which is selected inside suggestions drop down box.
|
||||
func OptionSelectedDescriptionTextColor(x Color) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.selectedDescriptionTextColor = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionSelectedDescriptionBGColor to change a background color of description which is selected inside suggestions drop down box.
|
||||
func OptionSelectedDescriptionBGColor(x Color) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.selectedDescriptionBGColor = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionScrollbarThumbColor to change a thumb color on scrollbar.
|
||||
func OptionScrollbarThumbColor(x Color) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.scrollbarThumbColor = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionScrollbarBGColor to change a background color of scrollbar.
|
||||
func OptionScrollbarBGColor(x Color) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.renderer.scrollbarBGColor = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionMaxSuggestion specify the max number of displayed suggestions.
|
||||
func OptionMaxSuggestion(x uint16) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.completion.max = x
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionHistory to set history expressed by string array.
|
||||
func OptionHistory(x []string) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.history.histories = x
|
||||
p.history.Clear()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionSwitchKeyBindMode set a key bind mode.
|
||||
func OptionSwitchKeyBindMode(m KeyBindMode) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.keyBindMode = m
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// SwitchKeyBindMode to set a key bind mode.
|
||||
// Deprecated: Please use OptionSwitchKeyBindMode.
|
||||
var SwitchKeyBindMode = OptionSwitchKeyBindMode
|
||||
|
||||
// OptionAddKeyBind to set a custom key bind.
|
||||
func OptionAddKeyBind(b ...KeyBind) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.keyBindings = append(p.keyBindings, b...)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// OptionAddASCIICodeBind to set a custom key bind.
|
||||
func OptionAddASCIICodeBind(b ...ASCIICodeBind) Option {
|
||||
return func(p *Prompt) error {
|
||||
p.ASCIICodeBindings = append(p.ASCIICodeBindings, b...)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// New returns a Prompt with powerful auto-completion.
|
||||
func New(executor Executor, completer Completer, opts ...Option) *Prompt {
|
||||
pt := &Prompt{
|
||||
in: NewStandardInputParser(),
|
||||
renderer: &Render{
|
||||
prefix: "> ",
|
||||
out: NewStandardOutputWriter(),
|
||||
livePrefixCallback: func() (string, bool) { return "", false },
|
||||
prefixTextColor: Blue,
|
||||
prefixBGColor: DefaultColor,
|
||||
inputTextColor: DefaultColor,
|
||||
inputBGColor: DefaultColor,
|
||||
previewSuggestionTextColor: Green,
|
||||
previewSuggestionBGColor: DefaultColor,
|
||||
suggestionTextColor: White,
|
||||
suggestionBGColor: Cyan,
|
||||
selectedSuggestionTextColor: Black,
|
||||
selectedSuggestionBGColor: Turquoise,
|
||||
descriptionTextColor: Black,
|
||||
descriptionBGColor: Turquoise,
|
||||
selectedDescriptionTextColor: White,
|
||||
selectedDescriptionBGColor: Cyan,
|
||||
scrollbarThumbColor: DarkGray,
|
||||
scrollbarBGColor: Cyan,
|
||||
},
|
||||
buf: NewBuffer(),
|
||||
executor: executor,
|
||||
history: NewHistory(),
|
||||
completion: NewCompletionManager(completer, 6),
|
||||
keyBindMode: EmacsKeyBind, // All the above assume that bash is running in the default Emacs setting
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
if err := opt(pt); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return pt
|
||||
}
|
||||
148
vendor/github.com/c-bata/go-prompt/output.go
generated
vendored
Normal file
148
vendor/github.com/c-bata/go-prompt/output.go
generated
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
package prompt
|
||||
|
||||
// DisplayAttribute represents display attributes like Blinking, Bold, Italic and so on.
|
||||
type DisplayAttribute int
|
||||
|
||||
const (
|
||||
// DisplayReset reset all display attributes.
|
||||
DisplayReset DisplayAttribute = iota
|
||||
// DisplayBold set bold or increases intensity.
|
||||
DisplayBold
|
||||
// DisplayLowIntensity decreases intensity. Not widely supported.
|
||||
DisplayLowIntensity
|
||||
// DisplayItalic set italic. Not widely supported.
|
||||
DisplayItalic
|
||||
// DisplayUnderline set underline
|
||||
DisplayUnderline
|
||||
// DisplayBlink set blink (less than 150 per minute).
|
||||
DisplayBlink
|
||||
// DisplayRapidBlink set blink (more than 150 per minute). Not widely supported.
|
||||
DisplayRapidBlink
|
||||
// DisplayReverse swap foreground and background colors.
|
||||
DisplayReverse
|
||||
// DisplayInvisible set invisible. Not widely supported.
|
||||
DisplayInvisible
|
||||
// DisplayCrossedOut set characters legible, but marked for deletion. Not widely supported.
|
||||
DisplayCrossedOut
|
||||
// DisplayDefaultFont set primary(default) font
|
||||
DisplayDefaultFont
|
||||
)
|
||||
|
||||
// Color represents color on terminal.
|
||||
type Color int
|
||||
|
||||
const (
|
||||
// DefaultColor represents a default color.
|
||||
DefaultColor Color = iota
|
||||
|
||||
// Low intensity
|
||||
|
||||
// Black represents a black.
|
||||
Black
|
||||
// DarkRed represents a dark red.
|
||||
DarkRed
|
||||
// DarkGreen represents a dark green.
|
||||
DarkGreen
|
||||
// Brown represents a brown.
|
||||
Brown
|
||||
// DarkBlue represents a dark blue.
|
||||
DarkBlue
|
||||
// Purple represents a purple.
|
||||
Purple
|
||||
// Cyan represents a cyan.
|
||||
Cyan
|
||||
// LightGray represents a light gray.
|
||||
LightGray
|
||||
|
||||
// High intensity
|
||||
|
||||
// DarkGray represents a dark gray.
|
||||
DarkGray
|
||||
// Red represents a red.
|
||||
Red
|
||||
// Green represents a green.
|
||||
Green
|
||||
// Yellow represents a yellow.
|
||||
Yellow
|
||||
// Blue represents a blue.
|
||||
Blue
|
||||
// Fuchsia represents a fuchsia.
|
||||
Fuchsia
|
||||
// Turquoise represents a turquoise.
|
||||
Turquoise
|
||||
// White represents a white.
|
||||
White
|
||||
)
|
||||
|
||||
// ConsoleWriter is an interface to abstract output layer.
|
||||
type ConsoleWriter interface {
|
||||
/* Write */
|
||||
|
||||
// WriteRaw to write raw byte array.
|
||||
WriteRaw(data []byte)
|
||||
// Write to write safety byte array by removing control sequences.
|
||||
Write(data []byte)
|
||||
// WriteStr to write raw string.
|
||||
WriteRawStr(data string)
|
||||
// WriteStr to write safety string by removing control sequences.
|
||||
WriteStr(data string)
|
||||
// Flush to flush buffer.
|
||||
Flush() error
|
||||
|
||||
/* Erasing */
|
||||
|
||||
// EraseScreen erases the screen with the background colour and moves the cursor to home.
|
||||
EraseScreen()
|
||||
// EraseUp erases the screen from the current line up to the top of the screen.
|
||||
EraseUp()
|
||||
// EraseDown erases the screen from the current line down to the bottom of the screen.
|
||||
EraseDown()
|
||||
// EraseStartOfLine erases from the current cursor position to the start of the current line.
|
||||
EraseStartOfLine()
|
||||
// EraseEndOfLine erases from the current cursor position to the end of the current line.
|
||||
EraseEndOfLine()
|
||||
// EraseLine erases the entire current line.
|
||||
EraseLine()
|
||||
|
||||
/* Cursor */
|
||||
|
||||
// ShowCursor stops blinking cursor and show.
|
||||
ShowCursor()
|
||||
// HideCursor hides cursor.
|
||||
HideCursor()
|
||||
// CursorGoTo sets the cursor position where subsequent text will begin.
|
||||
CursorGoTo(row, col int)
|
||||
// CursorUp moves the cursor up by 'n' rows; the default count is 1.
|
||||
CursorUp(n int)
|
||||
// CursorDown moves the cursor down by 'n' rows; the default count is 1.
|
||||
CursorDown(n int)
|
||||
// CursorForward moves the cursor forward by 'n' columns; the default count is 1.
|
||||
CursorForward(n int)
|
||||
// CursorBackward moves the cursor backward by 'n' columns; the default count is 1.
|
||||
CursorBackward(n int)
|
||||
// AskForCPR asks for a cursor position report (CPR).
|
||||
AskForCPR()
|
||||
// SaveCursor saves current cursor position.
|
||||
SaveCursor()
|
||||
// UnSaveCursor restores cursor position after a Save Cursor.
|
||||
UnSaveCursor()
|
||||
|
||||
/* Scrolling */
|
||||
|
||||
// ScrollDown scrolls display down one line.
|
||||
ScrollDown()
|
||||
// ScrollUp scroll display up one line.
|
||||
ScrollUp()
|
||||
|
||||
/* Title */
|
||||
|
||||
// SetTitle sets a title of terminal window.
|
||||
SetTitle(title string)
|
||||
// ClearTitle clears a title of terminal window.
|
||||
ClearTitle()
|
||||
|
||||
/* Font */
|
||||
|
||||
// SetColor sets text and background colors. and specify whether text is bold.
|
||||
SetColor(fg, bg Color, bold bool)
|
||||
}
|
||||
35
vendor/github.com/c-bata/go-prompt/output_posix.go
generated
vendored
Normal file
35
vendor/github.com/c-bata/go-prompt/output_posix.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// +build !windows
|
||||
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// PosixWriter is a ConsoleWriter implementation for POSIX environment.
|
||||
// To control terminal emulator, this outputs VT100 escape sequences.
|
||||
type PosixWriter struct {
|
||||
VT100Writer
|
||||
fd int
|
||||
}
|
||||
|
||||
// Flush to flush buffer
|
||||
func (w *PosixWriter) Flush() error {
|
||||
_, err := syscall.Write(w.fd, w.buffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.buffer = []byte{}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ConsoleWriter = &PosixWriter{}
|
||||
|
||||
// NewStandardOutputWriter returns ConsoleWriter object to write to stdout.
|
||||
// This generates VT100 escape sequences because almost terminal emulators
|
||||
// in POSIX OS built on top of a VT100 specification.
|
||||
func NewStandardOutputWriter() *PosixWriter {
|
||||
return &PosixWriter{
|
||||
fd: syscall.Stdout,
|
||||
}
|
||||
}
|
||||
333
vendor/github.com/c-bata/go-prompt/output_vt100.go
generated
vendored
Normal file
333
vendor/github.com/c-bata/go-prompt/output_vt100.go
generated
vendored
Normal file
@@ -0,0 +1,333 @@
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// VT100Writer generates VT100 escape sequences.
|
||||
type VT100Writer struct {
|
||||
buffer []byte
|
||||
}
|
||||
|
||||
// WriteRaw to write raw byte array
|
||||
func (w *VT100Writer) WriteRaw(data []byte) {
|
||||
w.buffer = append(w.buffer, data...)
|
||||
return
|
||||
}
|
||||
|
||||
// Write to write safety byte array by removing control sequences.
|
||||
func (w *VT100Writer) Write(data []byte) {
|
||||
w.WriteRaw(bytes.Replace(data, []byte{0x1b}, []byte{'?'}, -1))
|
||||
return
|
||||
}
|
||||
|
||||
// WriteRawStr to write raw string
|
||||
func (w *VT100Writer) WriteRawStr(data string) {
|
||||
w.WriteRaw([]byte(data))
|
||||
return
|
||||
}
|
||||
|
||||
// WriteStr to write safety string by removing control sequences.
|
||||
func (w *VT100Writer) WriteStr(data string) {
|
||||
w.Write([]byte(data))
|
||||
return
|
||||
}
|
||||
|
||||
/* Erase */
|
||||
|
||||
// EraseScreen erases the screen with the background colour and moves the cursor to home.
|
||||
func (w *VT100Writer) EraseScreen() {
|
||||
w.WriteRaw([]byte{0x1b, '[', '2', 'J'})
|
||||
return
|
||||
}
|
||||
|
||||
// EraseUp erases the screen from the current line up to the top of the screen.
|
||||
func (w *VT100Writer) EraseUp() {
|
||||
w.WriteRaw([]byte{0x1b, '[', '1', 'J'})
|
||||
return
|
||||
}
|
||||
|
||||
// EraseDown erases the screen from the current line down to the bottom of the screen.
|
||||
func (w *VT100Writer) EraseDown() {
|
||||
w.WriteRaw([]byte{0x1b, '[', 'J'})
|
||||
return
|
||||
}
|
||||
|
||||
// EraseStartOfLine erases from the current cursor position to the start of the current line.
|
||||
func (w *VT100Writer) EraseStartOfLine() {
|
||||
w.WriteRaw([]byte{0x1b, '[', '1', 'K'})
|
||||
return
|
||||
}
|
||||
|
||||
// EraseEndOfLine erases from the current cursor position to the end of the current line.
|
||||
func (w *VT100Writer) EraseEndOfLine() {
|
||||
w.WriteRaw([]byte{0x1b, '[', 'K'})
|
||||
return
|
||||
}
|
||||
|
||||
// EraseLine erases the entire current line.
|
||||
func (w *VT100Writer) EraseLine() {
|
||||
w.WriteRaw([]byte{0x1b, '[', '2', 'K'})
|
||||
return
|
||||
}
|
||||
|
||||
/* Cursor */
|
||||
|
||||
// ShowCursor stops blinking cursor and show.
|
||||
func (w *VT100Writer) ShowCursor() {
|
||||
w.WriteRaw([]byte{0x1b, '[', '?', '1', '2', 'l', 0x1b, '[', '?', '2', '5', 'h'})
|
||||
}
|
||||
|
||||
// HideCursor hides cursor.
|
||||
func (w *VT100Writer) HideCursor() {
|
||||
w.WriteRaw([]byte{0x1b, '[', '?', '2', '5', 'l'})
|
||||
return
|
||||
}
|
||||
|
||||
// CursorGoTo sets the cursor position where subsequent text will begin.
|
||||
func (w *VT100Writer) CursorGoTo(row, col int) {
|
||||
if row == 0 && col == 0 {
|
||||
// If no row/column parameters are provided (ie. <ESC>[H), the cursor will move to the home position.
|
||||
w.WriteRaw([]byte{0x1b, '[', 'H'})
|
||||
return
|
||||
}
|
||||
r := strconv.Itoa(row)
|
||||
c := strconv.Itoa(col)
|
||||
w.WriteRaw([]byte{0x1b, '['})
|
||||
w.WriteRaw([]byte(r))
|
||||
w.WriteRaw([]byte{';'})
|
||||
w.WriteRaw([]byte(c))
|
||||
w.WriteRaw([]byte{'H'})
|
||||
return
|
||||
}
|
||||
|
||||
// CursorUp moves the cursor up by 'n' rows; the default count is 1.
|
||||
func (w *VT100Writer) CursorUp(n int) {
|
||||
if n == 0 {
|
||||
return
|
||||
} else if n < 0 {
|
||||
w.CursorDown(-n)
|
||||
return
|
||||
}
|
||||
s := strconv.Itoa(n)
|
||||
w.WriteRaw([]byte{0x1b, '['})
|
||||
w.WriteRaw([]byte(s))
|
||||
w.WriteRaw([]byte{'A'})
|
||||
return
|
||||
}
|
||||
|
||||
// CursorDown moves the cursor down by 'n' rows; the default count is 1.
|
||||
func (w *VT100Writer) CursorDown(n int) {
|
||||
if n == 0 {
|
||||
return
|
||||
} else if n < 0 {
|
||||
w.CursorUp(-n)
|
||||
return
|
||||
}
|
||||
s := strconv.Itoa(n)
|
||||
w.WriteRaw([]byte{0x1b, '['})
|
||||
w.WriteRaw([]byte(s))
|
||||
w.WriteRaw([]byte{'B'})
|
||||
return
|
||||
}
|
||||
|
||||
// CursorForward moves the cursor forward by 'n' columns; the default count is 1.
|
||||
func (w *VT100Writer) CursorForward(n int) {
|
||||
if n == 0 {
|
||||
return
|
||||
} else if n < 0 {
|
||||
w.CursorBackward(-n)
|
||||
return
|
||||
}
|
||||
s := strconv.Itoa(n)
|
||||
w.WriteRaw([]byte{0x1b, '['})
|
||||
w.WriteRaw([]byte(s))
|
||||
w.WriteRaw([]byte{'C'})
|
||||
return
|
||||
}
|
||||
|
||||
// CursorBackward moves the cursor backward by 'n' columns; the default count is 1.
|
||||
func (w *VT100Writer) CursorBackward(n int) {
|
||||
if n == 0 {
|
||||
return
|
||||
} else if n < 0 {
|
||||
w.CursorForward(-n)
|
||||
return
|
||||
}
|
||||
s := strconv.Itoa(n)
|
||||
w.WriteRaw([]byte{0x1b, '['})
|
||||
w.WriteRaw([]byte(s))
|
||||
w.WriteRaw([]byte{'D'})
|
||||
return
|
||||
}
|
||||
|
||||
// AskForCPR asks for a cursor position report (CPR).
|
||||
func (w *VT100Writer) AskForCPR() {
|
||||
// CPR: Cursor Position Request.
|
||||
w.WriteRaw([]byte{0x1b, '[', '6', 'n'})
|
||||
return
|
||||
}
|
||||
|
||||
// SaveCursor saves current cursor position.
|
||||
func (w *VT100Writer) SaveCursor() {
|
||||
w.WriteRaw([]byte{0x1b, '[', 's'})
|
||||
return
|
||||
}
|
||||
|
||||
// UnSaveCursor restores cursor position after a Save Cursor.
|
||||
func (w *VT100Writer) UnSaveCursor() {
|
||||
w.WriteRaw([]byte{0x1b, '[', 'u'})
|
||||
return
|
||||
}
|
||||
|
||||
/* Scrolling */
|
||||
|
||||
// ScrollDown scrolls display down one line.
|
||||
func (w *VT100Writer) ScrollDown() {
|
||||
w.WriteRaw([]byte{0x1b, 'D'})
|
||||
return
|
||||
}
|
||||
|
||||
// ScrollUp scroll display up one line.
|
||||
func (w *VT100Writer) ScrollUp() {
|
||||
w.WriteRaw([]byte{0x1b, 'M'})
|
||||
return
|
||||
}
|
||||
|
||||
/* Title */
|
||||
|
||||
// SetTitle sets a title of terminal window.
|
||||
func (w *VT100Writer) SetTitle(title string) {
|
||||
titleBytes := []byte(title)
|
||||
patterns := []struct {
|
||||
from []byte
|
||||
to []byte
|
||||
}{
|
||||
{
|
||||
from: []byte{0x13},
|
||||
to: []byte{},
|
||||
},
|
||||
{
|
||||
from: []byte{0x07},
|
||||
to: []byte{},
|
||||
},
|
||||
}
|
||||
for i := range patterns {
|
||||
titleBytes = bytes.Replace(titleBytes, patterns[i].from, patterns[i].to, -1)
|
||||
}
|
||||
|
||||
w.WriteRaw([]byte{0x1b, ']', '2', ';'})
|
||||
w.WriteRaw(titleBytes)
|
||||
w.WriteRaw([]byte{0x07})
|
||||
return
|
||||
}
|
||||
|
||||
// ClearTitle clears a title of terminal window.
|
||||
func (w *VT100Writer) ClearTitle() {
|
||||
w.WriteRaw([]byte{0x1b, ']', '2', ';', 0x07})
|
||||
return
|
||||
}
|
||||
|
||||
/* Font */
|
||||
|
||||
// SetColor sets text and background colors. and specify whether text is bold.
|
||||
func (w *VT100Writer) SetColor(fg, bg Color, bold bool) {
|
||||
if bold {
|
||||
w.SetDisplayAttributes(fg, bg, DisplayBold)
|
||||
} else {
|
||||
w.SetDisplayAttributes(fg, bg, DisplayDefaultFont)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SetDisplayAttributes to set VT100 display attributes.
|
||||
func (w *VT100Writer) SetDisplayAttributes(fg, bg Color, attrs ...DisplayAttribute) {
|
||||
w.WriteRaw([]byte{0x1b, '['}) // control sequence introducer
|
||||
defer w.WriteRaw([]byte{'m'}) // final character
|
||||
|
||||
var separator byte = ';'
|
||||
for i := range attrs {
|
||||
p, ok := displayAttributeParameters[attrs[i]]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
w.WriteRaw(p)
|
||||
w.WriteRaw([]byte{separator})
|
||||
}
|
||||
|
||||
f, ok := foregroundANSIColors[fg]
|
||||
if !ok {
|
||||
f = foregroundANSIColors[DefaultColor]
|
||||
}
|
||||
w.WriteRaw(f)
|
||||
w.WriteRaw([]byte{separator})
|
||||
b, ok := backgroundANSIColors[bg]
|
||||
if !ok {
|
||||
b = backgroundANSIColors[DefaultColor]
|
||||
}
|
||||
w.WriteRaw(b)
|
||||
return
|
||||
}
|
||||
|
||||
var displayAttributeParameters = map[DisplayAttribute][]byte{
|
||||
DisplayReset: {'0'},
|
||||
DisplayBold: {'1'},
|
||||
DisplayLowIntensity: {'2'},
|
||||
DisplayItalic: {'3'},
|
||||
DisplayUnderline: {'4'},
|
||||
DisplayBlink: {'5'},
|
||||
DisplayRapidBlink: {'6'},
|
||||
DisplayReverse: {'7'},
|
||||
DisplayInvisible: {'8'},
|
||||
DisplayCrossedOut: {'9'},
|
||||
DisplayDefaultFont: {'1', '0'},
|
||||
}
|
||||
|
||||
var foregroundANSIColors = map[Color][]byte{
|
||||
DefaultColor: {'3', '9'},
|
||||
|
||||
// Low intensity.
|
||||
Black: {'3', '0'},
|
||||
DarkRed: {'3', '1'},
|
||||
DarkGreen: {'3', '2'},
|
||||
Brown: {'3', '3'},
|
||||
DarkBlue: {'3', '4'},
|
||||
Purple: {'3', '5'},
|
||||
Cyan: {'3', '6'},
|
||||
LightGray: {'3', '7'},
|
||||
|
||||
// High intensity.
|
||||
DarkGray: {'9', '0'},
|
||||
Red: {'9', '1'},
|
||||
Green: {'9', '2'},
|
||||
Yellow: {'9', '3'},
|
||||
Blue: {'9', '4'},
|
||||
Fuchsia: {'9', '5'},
|
||||
Turquoise: {'9', '6'},
|
||||
White: {'9', '7'},
|
||||
}
|
||||
|
||||
var backgroundANSIColors = map[Color][]byte{
|
||||
DefaultColor: {'4', '9'},
|
||||
|
||||
// Low intensity.
|
||||
Black: {'4', '0'},
|
||||
DarkRed: {'4', '1'},
|
||||
DarkGreen: {'4', '2'},
|
||||
Brown: {'4', '3'},
|
||||
DarkBlue: {'4', '4'},
|
||||
Purple: {'4', '5'},
|
||||
Cyan: {'4', '6'},
|
||||
LightGray: {'4', '7'},
|
||||
|
||||
// High intensity
|
||||
DarkGray: {'1', '0', '0'},
|
||||
Red: {'1', '0', '1'},
|
||||
Green: {'1', '0', '2'},
|
||||
Yellow: {'1', '0', '3'},
|
||||
Blue: {'1', '0', '4'},
|
||||
Fuchsia: {'1', '0', '5'},
|
||||
Turquoise: {'1', '0', '6'},
|
||||
White: {'1', '0', '7'},
|
||||
}
|
||||
36
vendor/github.com/c-bata/go-prompt/output_windows.go
generated
vendored
Normal file
36
vendor/github.com/c-bata/go-prompt/output_windows.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// +build windows
|
||||
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/mattn/go-colorable"
|
||||
)
|
||||
|
||||
// WindowsWriter is a ConsoleWriter implementation for Win32 console.
|
||||
// Output is converted from VT100 escape sequences by mattn/go-colorable.
|
||||
type WindowsWriter struct {
|
||||
VT100Writer
|
||||
out io.Writer
|
||||
}
|
||||
|
||||
// Flush to flush buffer
|
||||
func (w *WindowsWriter) Flush() error {
|
||||
_, err := w.out.Write(w.buffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.buffer = []byte{}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ConsoleWriter = &WindowsWriter{}
|
||||
|
||||
// NewStandardOutputWriter returns ConsoleWriter object to write to stdout.
|
||||
// This generates win32 control sequences.
|
||||
func NewStandardOutputWriter() *WindowsWriter {
|
||||
return &WindowsWriter{
|
||||
out: colorable.NewColorableStdout(),
|
||||
}
|
||||
}
|
||||
286
vendor/github.com/c-bata/go-prompt/prompt.go
generated
vendored
Normal file
286
vendor/github.com/c-bata/go-prompt/prompt.go
generated
vendored
Normal file
@@ -0,0 +1,286 @@
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
envDebugLogPath = "GO_PROMPT_LOG_PATH"
|
||||
)
|
||||
|
||||
// Executor is called when user input something text.
|
||||
type Executor func(string)
|
||||
|
||||
// Completer should return the suggest item from Document.
|
||||
type Completer func(Document) []Suggest
|
||||
|
||||
// Prompt is core struct of go-prompt.
|
||||
type Prompt struct {
|
||||
in ConsoleParser
|
||||
buf *Buffer
|
||||
renderer *Render
|
||||
executor Executor
|
||||
history *History
|
||||
completion *CompletionManager
|
||||
keyBindings []KeyBind
|
||||
ASCIICodeBindings []ASCIICodeBind
|
||||
keyBindMode KeyBindMode
|
||||
}
|
||||
|
||||
// Exec is the struct contains user input context.
|
||||
type Exec struct {
|
||||
input string
|
||||
}
|
||||
|
||||
// Run starts prompt.
|
||||
func (p *Prompt) Run() {
|
||||
if l := os.Getenv(envDebugLogPath); l == "" {
|
||||
log.SetOutput(ioutil.Discard)
|
||||
} else if f, err := os.OpenFile(l, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666); err != nil {
|
||||
log.SetOutput(ioutil.Discard)
|
||||
} else {
|
||||
defer f.Close()
|
||||
log.SetOutput(f)
|
||||
log.Println("[INFO] Logging is enabled.")
|
||||
}
|
||||
|
||||
p.setUp()
|
||||
defer p.tearDown()
|
||||
|
||||
p.renderer.Render(p.buf, p.completion)
|
||||
|
||||
bufCh := make(chan []byte, 128)
|
||||
stopReadBufCh := make(chan struct{})
|
||||
go p.readBuffer(bufCh, stopReadBufCh)
|
||||
|
||||
exitCh := make(chan int)
|
||||
winSizeCh := make(chan *WinSize)
|
||||
stopHandleSignalCh := make(chan struct{})
|
||||
go p.handleSignals(exitCh, winSizeCh, stopHandleSignalCh)
|
||||
|
||||
for {
|
||||
select {
|
||||
case b := <-bufCh:
|
||||
if shouldExit, e := p.feed(b); shouldExit {
|
||||
p.renderer.BreakLine(p.buf)
|
||||
stopReadBufCh <- struct{}{}
|
||||
stopHandleSignalCh <- struct{}{}
|
||||
return
|
||||
} else if e != nil {
|
||||
// Stop goroutine to run readBuffer function
|
||||
stopReadBufCh <- struct{}{}
|
||||
stopHandleSignalCh <- struct{}{}
|
||||
|
||||
// Unset raw mode
|
||||
// Reset to Blocking mode because returned EAGAIN when still set non-blocking mode.
|
||||
p.in.TearDown()
|
||||
p.executor(e.input)
|
||||
|
||||
p.completion.Update(*p.buf.Document())
|
||||
p.renderer.Render(p.buf, p.completion)
|
||||
|
||||
// Set raw mode
|
||||
p.in.Setup()
|
||||
go p.readBuffer(bufCh, stopReadBufCh)
|
||||
go p.handleSignals(exitCh, winSizeCh, stopHandleSignalCh)
|
||||
} else {
|
||||
p.completion.Update(*p.buf.Document())
|
||||
p.renderer.Render(p.buf, p.completion)
|
||||
}
|
||||
case w := <-winSizeCh:
|
||||
p.renderer.UpdateWinSize(w)
|
||||
p.renderer.Render(p.buf, p.completion)
|
||||
case code := <-exitCh:
|
||||
p.renderer.BreakLine(p.buf)
|
||||
p.tearDown()
|
||||
os.Exit(code)
|
||||
default:
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Prompt) feed(b []byte) (shouldExit bool, exec *Exec) {
|
||||
key := p.in.GetKey(b)
|
||||
|
||||
// completion
|
||||
completing := p.completion.Completing()
|
||||
p.handleCompletionKeyBinding(key, completing)
|
||||
|
||||
switch key {
|
||||
case Enter, ControlJ, ControlM:
|
||||
p.renderer.BreakLine(p.buf)
|
||||
|
||||
exec = &Exec{input: p.buf.Text()}
|
||||
log.Printf("[History] %s", p.buf.Text())
|
||||
p.buf = NewBuffer()
|
||||
if exec.input != "" {
|
||||
p.history.Add(exec.input)
|
||||
}
|
||||
case ControlC:
|
||||
p.renderer.BreakLine(p.buf)
|
||||
p.buf = NewBuffer()
|
||||
p.history.Clear()
|
||||
case Up, ControlP:
|
||||
if !completing { // Don't use p.completion.Completing() because it takes double operation when switch to selected=-1.
|
||||
if newBuf, changed := p.history.Older(p.buf); changed {
|
||||
p.buf = newBuf
|
||||
}
|
||||
}
|
||||
case Down, ControlN:
|
||||
if !completing { // Don't use p.completion.Completing() because it takes double operation when switch to selected=-1.
|
||||
if newBuf, changed := p.history.Newer(p.buf); changed {
|
||||
p.buf = newBuf
|
||||
}
|
||||
return
|
||||
}
|
||||
case ControlD:
|
||||
if p.buf.Text() == "" {
|
||||
shouldExit = true
|
||||
return
|
||||
}
|
||||
case NotDefined:
|
||||
if p.handleASCIICodeBinding(b) {
|
||||
return
|
||||
}
|
||||
p.buf.InsertText(string(b), false, true)
|
||||
}
|
||||
|
||||
p.handleKeyBinding(key)
|
||||
return
|
||||
}
|
||||
|
||||
func (p *Prompt) handleCompletionKeyBinding(key Key, completing bool) {
|
||||
switch key {
|
||||
case Down:
|
||||
if completing {
|
||||
p.completion.Next()
|
||||
}
|
||||
case Tab, ControlI:
|
||||
p.completion.Next()
|
||||
case Up:
|
||||
if completing {
|
||||
p.completion.Previous()
|
||||
}
|
||||
case BackTab:
|
||||
p.completion.Previous()
|
||||
default:
|
||||
if s, ok := p.completion.GetSelectedSuggestion(); ok {
|
||||
w := p.buf.Document().GetWordBeforeCursorUntilSeparator(p.completion.wordSeparator)
|
||||
if w != "" {
|
||||
p.buf.DeleteBeforeCursor(len([]rune(w)))
|
||||
}
|
||||
p.buf.InsertText(s.Text, false, true)
|
||||
}
|
||||
p.completion.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Prompt) handleKeyBinding(key Key) {
|
||||
for i := range commonKeyBindings {
|
||||
kb := commonKeyBindings[i]
|
||||
if kb.Key == key {
|
||||
kb.Fn(p.buf)
|
||||
}
|
||||
}
|
||||
|
||||
if p.keyBindMode == EmacsKeyBind {
|
||||
for i := range emacsKeyBindings {
|
||||
kb := emacsKeyBindings[i]
|
||||
if kb.Key == key {
|
||||
kb.Fn(p.buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Custom key bindings
|
||||
for i := range p.keyBindings {
|
||||
kb := p.keyBindings[i]
|
||||
if kb.Key == key {
|
||||
kb.Fn(p.buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Prompt) handleASCIICodeBinding(b []byte) bool {
|
||||
checked := false
|
||||
for _, kb := range p.ASCIICodeBindings {
|
||||
if bytes.Compare(kb.ASCIICode, b) == 0 {
|
||||
kb.Fn(p.buf)
|
||||
checked = true
|
||||
}
|
||||
}
|
||||
return checked
|
||||
}
|
||||
|
||||
// Input just returns user input text.
|
||||
func (p *Prompt) Input() string {
|
||||
if l := os.Getenv(envDebugLogPath); l == "" {
|
||||
log.SetOutput(ioutil.Discard)
|
||||
} else if f, err := os.OpenFile(l, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666); err != nil {
|
||||
log.SetOutput(ioutil.Discard)
|
||||
} else {
|
||||
defer f.Close()
|
||||
log.SetOutput(f)
|
||||
log.Println("[INFO] Logging is enabled.")
|
||||
}
|
||||
|
||||
p.setUp()
|
||||
defer p.tearDown()
|
||||
|
||||
p.renderer.Render(p.buf, p.completion)
|
||||
bufCh := make(chan []byte, 128)
|
||||
stopReadBufCh := make(chan struct{})
|
||||
go p.readBuffer(bufCh, stopReadBufCh)
|
||||
|
||||
for {
|
||||
select {
|
||||
case b := <-bufCh:
|
||||
if shouldExit, e := p.feed(b); shouldExit {
|
||||
p.renderer.BreakLine(p.buf)
|
||||
stopReadBufCh <- struct{}{}
|
||||
return ""
|
||||
} else if e != nil {
|
||||
// Stop goroutine to run readBuffer function
|
||||
stopReadBufCh <- struct{}{}
|
||||
return e.input
|
||||
} else {
|
||||
p.completion.Update(*p.buf.Document())
|
||||
p.renderer.Render(p.buf, p.completion)
|
||||
}
|
||||
default:
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Prompt) readBuffer(bufCh chan []byte, stopCh chan struct{}) {
|
||||
log.Printf("[INFO] readBuffer start")
|
||||
for {
|
||||
select {
|
||||
case <-stopCh:
|
||||
log.Print("[INFO] stop readBuffer")
|
||||
return
|
||||
default:
|
||||
if b, err := p.in.Read(); err == nil && !(len(b) == 1 && b[0] == 0) {
|
||||
bufCh <- b
|
||||
}
|
||||
}
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Prompt) setUp() {
|
||||
p.in.Setup()
|
||||
p.renderer.Setup()
|
||||
p.renderer.UpdateWinSize(p.in.GetWinSize())
|
||||
}
|
||||
|
||||
func (p *Prompt) tearDown() {
|
||||
p.in.TearDown()
|
||||
p.renderer.TearDown()
|
||||
}
|
||||
286
vendor/github.com/c-bata/go-prompt/render.go
generated
vendored
Normal file
286
vendor/github.com/c-bata/go-prompt/render.go
generated
vendored
Normal file
@@ -0,0 +1,286 @@
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"github.com/mattn/go-runewidth"
|
||||
)
|
||||
|
||||
// Render to render prompt information from state of Buffer.
|
||||
type Render struct {
|
||||
out ConsoleWriter
|
||||
prefix string
|
||||
livePrefixCallback func() (prefix string, useLivePrefix bool)
|
||||
title string
|
||||
row uint16
|
||||
col uint16
|
||||
|
||||
previousCursor int
|
||||
|
||||
// colors,
|
||||
prefixTextColor Color
|
||||
prefixBGColor Color
|
||||
inputTextColor Color
|
||||
inputBGColor Color
|
||||
previewSuggestionTextColor Color
|
||||
previewSuggestionBGColor Color
|
||||
suggestionTextColor Color
|
||||
suggestionBGColor Color
|
||||
selectedSuggestionTextColor Color
|
||||
selectedSuggestionBGColor Color
|
||||
descriptionTextColor Color
|
||||
descriptionBGColor Color
|
||||
selectedDescriptionTextColor Color
|
||||
selectedDescriptionBGColor Color
|
||||
scrollbarThumbColor Color
|
||||
scrollbarBGColor Color
|
||||
}
|
||||
|
||||
// Setup to initialize console output.
|
||||
func (r *Render) Setup() {
|
||||
if r.title != "" {
|
||||
r.out.SetTitle(r.title)
|
||||
r.out.Flush()
|
||||
}
|
||||
}
|
||||
|
||||
// getCurrentPrefix to get current prefix.
|
||||
// If live-prefix is enabled, return live-prefix.
|
||||
func (r *Render) getCurrentPrefix() string {
|
||||
if prefix, ok := r.livePrefixCallback(); ok {
|
||||
return prefix
|
||||
}
|
||||
return r.prefix
|
||||
}
|
||||
|
||||
func (r *Render) renderPrefix() {
|
||||
r.out.SetColor(r.prefixTextColor, r.prefixBGColor, false)
|
||||
r.out.WriteStr(r.getCurrentPrefix())
|
||||
r.out.SetColor(DefaultColor, DefaultColor, false)
|
||||
}
|
||||
|
||||
// TearDown to clear title and erasing.
|
||||
func (r *Render) TearDown() {
|
||||
r.out.ClearTitle()
|
||||
r.out.EraseDown()
|
||||
r.out.Flush()
|
||||
}
|
||||
|
||||
func (r *Render) prepareArea(lines int) {
|
||||
for i := 0; i < lines; i++ {
|
||||
r.out.ScrollDown()
|
||||
}
|
||||
for i := 0; i < lines; i++ {
|
||||
r.out.ScrollUp()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateWinSize called when window size is changed.
|
||||
func (r *Render) UpdateWinSize(ws *WinSize) {
|
||||
r.row = ws.Row
|
||||
r.col = ws.Col
|
||||
return
|
||||
}
|
||||
|
||||
func (r *Render) renderWindowTooSmall() {
|
||||
r.out.CursorGoTo(0, 0)
|
||||
r.out.EraseScreen()
|
||||
r.out.SetColor(DarkRed, White, false)
|
||||
r.out.WriteStr("Your console window is too small...")
|
||||
return
|
||||
}
|
||||
|
||||
func (r *Render) renderCompletion(buf *Buffer, completions *CompletionManager) {
|
||||
suggestions := completions.GetSuggestions()
|
||||
if len(completions.GetSuggestions()) == 0 {
|
||||
return
|
||||
}
|
||||
prefix := r.getCurrentPrefix()
|
||||
formatted, width := formatSuggestions(
|
||||
suggestions,
|
||||
int(r.col)-runewidth.StringWidth(prefix)-1, // -1 means a width of scrollbar
|
||||
)
|
||||
// +1 means a width of scrollbar.
|
||||
width++
|
||||
|
||||
windowHeight := len(formatted)
|
||||
if windowHeight > int(completions.max) {
|
||||
windowHeight = int(completions.max)
|
||||
}
|
||||
formatted = formatted[completions.verticalScroll : completions.verticalScroll+windowHeight]
|
||||
r.prepareArea(windowHeight)
|
||||
|
||||
cursor := runewidth.StringWidth(prefix) + runewidth.StringWidth(buf.Document().TextBeforeCursor())
|
||||
x, _ := r.toPos(cursor)
|
||||
if x+width >= int(r.col) {
|
||||
cursor = r.backward(cursor, x+width-int(r.col))
|
||||
}
|
||||
|
||||
contentHeight := len(completions.tmp)
|
||||
|
||||
fractionVisible := float64(windowHeight) / float64(contentHeight)
|
||||
fractionAbove := float64(completions.verticalScroll) / float64(contentHeight)
|
||||
|
||||
scrollbarHeight := int(clamp(float64(windowHeight), 1, float64(windowHeight)*fractionVisible))
|
||||
scrollbarTop := int(float64(windowHeight) * fractionAbove)
|
||||
|
||||
isScrollThumb := func(row int) bool {
|
||||
return scrollbarTop <= row && row <= scrollbarTop+scrollbarHeight
|
||||
}
|
||||
|
||||
selected := completions.selected - completions.verticalScroll
|
||||
r.out.SetColor(White, Cyan, false)
|
||||
for i := 0; i < windowHeight; i++ {
|
||||
r.out.CursorDown(1)
|
||||
if i == selected {
|
||||
r.out.SetColor(r.selectedSuggestionTextColor, r.selectedSuggestionBGColor, true)
|
||||
} else {
|
||||
r.out.SetColor(r.suggestionTextColor, r.suggestionBGColor, false)
|
||||
}
|
||||
r.out.WriteStr(formatted[i].Text)
|
||||
|
||||
if i == selected {
|
||||
r.out.SetColor(r.selectedDescriptionTextColor, r.selectedDescriptionBGColor, false)
|
||||
} else {
|
||||
r.out.SetColor(r.descriptionTextColor, r.descriptionBGColor, false)
|
||||
}
|
||||
r.out.WriteStr(formatted[i].Description)
|
||||
|
||||
if isScrollThumb(i) {
|
||||
r.out.SetColor(DefaultColor, r.scrollbarThumbColor, false)
|
||||
} else {
|
||||
r.out.SetColor(DefaultColor, r.scrollbarBGColor, false)
|
||||
}
|
||||
r.out.WriteStr(" ")
|
||||
r.out.SetColor(DefaultColor, DefaultColor, false)
|
||||
|
||||
r.lineWrap(cursor + width)
|
||||
r.backward(cursor+width, width)
|
||||
}
|
||||
|
||||
if x+width >= int(r.col) {
|
||||
r.out.CursorForward(x + width - int(r.col))
|
||||
}
|
||||
|
||||
r.out.CursorUp(windowHeight)
|
||||
r.out.SetColor(DefaultColor, DefaultColor, false)
|
||||
return
|
||||
}
|
||||
|
||||
// Render renders to the console.
|
||||
func (r *Render) Render(buffer *Buffer, completion *CompletionManager) {
|
||||
// In situations where a pseudo tty is allocated (e.g. within a docker container),
|
||||
// window size via TIOCGWINSZ is not immediately available and will result in 0,0 dimensions.
|
||||
if r.col == 0 {
|
||||
return
|
||||
}
|
||||
defer r.out.Flush()
|
||||
r.move(r.previousCursor, 0)
|
||||
|
||||
line := buffer.Text()
|
||||
prefix := r.getCurrentPrefix()
|
||||
cursor := runewidth.StringWidth(prefix) + runewidth.StringWidth(line)
|
||||
|
||||
// prepare area
|
||||
_, y := r.toPos(cursor)
|
||||
|
||||
h := y + 1 + int(completion.max)
|
||||
if h > int(r.row) || completionMargin > int(r.col) {
|
||||
r.renderWindowTooSmall()
|
||||
return
|
||||
}
|
||||
|
||||
// Rendering
|
||||
r.out.HideCursor()
|
||||
defer r.out.ShowCursor()
|
||||
|
||||
r.renderPrefix()
|
||||
r.out.SetColor(r.inputTextColor, r.inputBGColor, false)
|
||||
r.out.WriteStr(line)
|
||||
r.out.SetColor(DefaultColor, DefaultColor, false)
|
||||
r.lineWrap(cursor)
|
||||
|
||||
r.out.EraseDown()
|
||||
|
||||
cursor = r.backward(cursor, runewidth.StringWidth(line)-buffer.DisplayCursorPosition())
|
||||
|
||||
r.renderCompletion(buffer, completion)
|
||||
if suggest, ok := completion.GetSelectedSuggestion(); ok {
|
||||
cursor = r.backward(cursor, runewidth.StringWidth(buffer.Document().GetWordBeforeCursorUntilSeparator(completion.wordSeparator)))
|
||||
|
||||
r.out.SetColor(r.previewSuggestionTextColor, r.previewSuggestionBGColor, false)
|
||||
r.out.WriteStr(suggest.Text)
|
||||
r.out.SetColor(DefaultColor, DefaultColor, false)
|
||||
cursor += runewidth.StringWidth(suggest.Text)
|
||||
|
||||
rest := buffer.Document().TextAfterCursor()
|
||||
r.out.WriteStr(rest)
|
||||
cursor += runewidth.StringWidth(rest)
|
||||
r.lineWrap(cursor)
|
||||
|
||||
cursor = r.backward(cursor, runewidth.StringWidth(rest))
|
||||
}
|
||||
r.previousCursor = cursor
|
||||
}
|
||||
|
||||
// BreakLine to break line.
|
||||
func (r *Render) BreakLine(buffer *Buffer) {
|
||||
// Erasing and Render
|
||||
cursor := runewidth.StringWidth(buffer.Document().TextBeforeCursor()) + runewidth.StringWidth(r.getCurrentPrefix())
|
||||
r.clear(cursor)
|
||||
r.renderPrefix()
|
||||
r.out.SetColor(r.inputTextColor, r.inputBGColor, false)
|
||||
r.out.WriteStr(buffer.Document().Text + "\n")
|
||||
r.out.SetColor(DefaultColor, DefaultColor, false)
|
||||
r.out.Flush()
|
||||
|
||||
r.previousCursor = 0
|
||||
}
|
||||
|
||||
// clear erases the screen from a beginning of input
|
||||
// even if there is line break which means input length exceeds a window's width.
|
||||
func (r *Render) clear(cursor int) {
|
||||
r.move(cursor, 0)
|
||||
r.out.EraseDown()
|
||||
}
|
||||
|
||||
// backward moves cursor to backward from a current cursor position
|
||||
// regardless there is a line break.
|
||||
func (r *Render) backward(from, n int) int {
|
||||
return r.move(from, from-n)
|
||||
}
|
||||
|
||||
// move moves cursor to specified position from the beginning of input
|
||||
// even if there is a line break.
|
||||
func (r *Render) move(from, to int) int {
|
||||
fromX, fromY := r.toPos(from)
|
||||
toX, toY := r.toPos(to)
|
||||
|
||||
r.out.CursorUp(fromY - toY)
|
||||
r.out.CursorBackward(fromX - toX)
|
||||
return to
|
||||
}
|
||||
|
||||
// toPos returns the relative position from the beginning of the string.
|
||||
func (r *Render) toPos(cursor int) (x, y int) {
|
||||
col := int(r.col)
|
||||
return cursor % col, cursor / col
|
||||
}
|
||||
|
||||
func (r *Render) lineWrap(cursor int) {
|
||||
if runtime.GOOS != "windows" && cursor > 0 && cursor%int(r.col) == 0 {
|
||||
r.out.WriteRaw([]byte{'\n'})
|
||||
}
|
||||
}
|
||||
|
||||
func clamp(high, low, x float64) float64 {
|
||||
switch {
|
||||
case high < x:
|
||||
return high
|
||||
case x < low:
|
||||
return low
|
||||
default:
|
||||
return x
|
||||
}
|
||||
}
|
||||
43
vendor/github.com/c-bata/go-prompt/shortcut.go
generated
vendored
Normal file
43
vendor/github.com/c-bata/go-prompt/shortcut.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
package prompt
|
||||
|
||||
func dummyExecutor(in string) { return }
|
||||
|
||||
// Input get the input data from the user and return it.
|
||||
func Input(prefix string, completer Completer, opts ...Option) string {
|
||||
pt := New(dummyExecutor, completer)
|
||||
pt.renderer.prefixTextColor = DefaultColor
|
||||
pt.renderer.prefix = prefix
|
||||
|
||||
for _, opt := range opts {
|
||||
if err := opt(pt); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return pt.Input()
|
||||
}
|
||||
|
||||
// Choose to the shortcut of input function to select from string array.
|
||||
// Deprecated: Maybe anyone want to use this.
|
||||
func Choose(prefix string, choices []string, opts ...Option) string {
|
||||
completer := newChoiceCompleter(choices, FilterHasPrefix)
|
||||
pt := New(dummyExecutor, completer)
|
||||
pt.renderer.prefixTextColor = DefaultColor
|
||||
pt.renderer.prefix = prefix
|
||||
|
||||
for _, opt := range opts {
|
||||
if err := opt(pt); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return pt.Input()
|
||||
}
|
||||
|
||||
func newChoiceCompleter(choices []string, filter Filter) Completer {
|
||||
s := make([]Suggest, len(choices))
|
||||
for i := range choices {
|
||||
s[i] = Suggest{Text: choices[i]}
|
||||
}
|
||||
return func(x Document) []Suggest {
|
||||
return filter(s, x.GetWordBeforeCursor(), true)
|
||||
}
|
||||
}
|
||||
48
vendor/github.com/c-bata/go-prompt/signal_posix.go
generated
vendored
Normal file
48
vendor/github.com/c-bata/go-prompt/signal_posix.go
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
// +build !windows
|
||||
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func (p *Prompt) handleSignals(exitCh chan int, winSizeCh chan *WinSize, stop chan struct{}) {
|
||||
in := p.in
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(
|
||||
sigCh,
|
||||
syscall.SIGINT,
|
||||
syscall.SIGTERM,
|
||||
syscall.SIGQUIT,
|
||||
syscall.SIGWINCH,
|
||||
)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-stop:
|
||||
log.Println("[INFO] stop handleSignals")
|
||||
return
|
||||
case s := <-sigCh:
|
||||
switch s {
|
||||
case syscall.SIGINT: // kill -SIGINT XXXX or Ctrl+c
|
||||
log.Println("[SIGNAL] Catch SIGINT")
|
||||
exitCh <- 0
|
||||
|
||||
case syscall.SIGTERM: // kill -SIGTERM XXXX
|
||||
log.Println("[SIGNAL] Catch SIGTERM")
|
||||
exitCh <- 1
|
||||
|
||||
case syscall.SIGQUIT: // kill -SIGQUIT XXXX
|
||||
log.Println("[SIGNAL] Catch SIGQUIT")
|
||||
exitCh <- 0
|
||||
|
||||
case syscall.SIGWINCH:
|
||||
log.Println("[SIGNAL] Catch SIGWINCH")
|
||||
winSizeCh <- in.GetWinSize()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
43
vendor/github.com/c-bata/go-prompt/signal_windows.go
generated
vendored
Normal file
43
vendor/github.com/c-bata/go-prompt/signal_windows.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
// +build windows
|
||||
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func (p *Prompt) handleSignals(exitCh chan int, winSizeCh chan *WinSize, stop chan struct{}) {
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(
|
||||
sigCh,
|
||||
syscall.SIGINT,
|
||||
syscall.SIGTERM,
|
||||
syscall.SIGQUIT,
|
||||
)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-stop:
|
||||
log.Println("[INFO] stop handleSignals")
|
||||
return
|
||||
case s := <-sigCh:
|
||||
switch s {
|
||||
|
||||
case syscall.SIGINT: // kill -SIGINT XXXX or Ctrl+c
|
||||
log.Println("[SIGNAL] Catch SIGINT")
|
||||
exitCh <- 0
|
||||
|
||||
case syscall.SIGTERM: // kill -SIGTERM XXXX
|
||||
log.Println("[SIGNAL] Catch SIGTERM")
|
||||
exitCh <- 1
|
||||
|
||||
case syscall.SIGQUIT: // kill -SIGQUIT XXXX
|
||||
log.Println("[SIGNAL] Catch SIGQUIT")
|
||||
exitCh <- 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
5
vendor/github.com/fatih/color/.travis.yml
generated
vendored
Normal file
5
vendor/github.com/fatih/color/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.8.x
|
||||
- tip
|
||||
|
||||
27
vendor/github.com/fatih/color/Gopkg.lock
generated
vendored
Normal file
27
vendor/github.com/fatih/color/Gopkg.lock
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-colorable"
|
||||
packages = ["."]
|
||||
revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
|
||||
version = "v0.0.9"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-isatty"
|
||||
packages = ["."]
|
||||
revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
|
||||
version = "v0.0.3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
revision = "37707fdb30a5b38865cfb95e5aab41707daec7fd"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "e8a50671c3cb93ea935bf210b1cd20702876b9d9226129be581ef646d1565cdc"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
30
vendor/github.com/fatih/color/Gopkg.toml
generated
vendored
Normal file
30
vendor/github.com/fatih/color/Gopkg.toml
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/mattn/go-colorable"
|
||||
version = "0.0.9"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/mattn/go-isatty"
|
||||
version = "0.0.3"
|
||||
20
vendor/github.com/fatih/color/LICENSE.md
generated
vendored
Normal file
20
vendor/github.com/fatih/color/LICENSE.md
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Fatih Arslan
|
||||
|
||||
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.
|
||||
179
vendor/github.com/fatih/color/README.md
generated
vendored
Normal file
179
vendor/github.com/fatih/color/README.md
generated
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
# Color [](https://godoc.org/github.com/fatih/color) [](https://travis-ci.org/fatih/color)
|
||||
|
||||
|
||||
|
||||
Color lets you use colorized outputs in terms of [ANSI Escape
|
||||
Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It
|
||||
has support for Windows too! The API can be used in several ways, pick one that
|
||||
suits you.
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
go get github.com/fatih/color
|
||||
```
|
||||
|
||||
Note that the `vendor` folder is here for stability. Remove the folder if you
|
||||
already have the dependencies in your GOPATH.
|
||||
|
||||
## Examples
|
||||
|
||||
### Standard colors
|
||||
|
||||
```go
|
||||
// Print with default helper functions
|
||||
color.Cyan("Prints text in cyan.")
|
||||
|
||||
// A newline will be appended automatically
|
||||
color.Blue("Prints %s in blue.", "text")
|
||||
|
||||
// These are using the default foreground colors
|
||||
color.Red("We have red")
|
||||
color.Magenta("And many others ..")
|
||||
|
||||
```
|
||||
|
||||
### Mix and reuse colors
|
||||
|
||||
```go
|
||||
// Create a new color object
|
||||
c := color.New(color.FgCyan).Add(color.Underline)
|
||||
c.Println("Prints cyan text with an underline.")
|
||||
|
||||
// Or just add them to New()
|
||||
d := color.New(color.FgCyan, color.Bold)
|
||||
d.Printf("This prints bold cyan %s\n", "too!.")
|
||||
|
||||
// Mix up foreground and background colors, create new mixes!
|
||||
red := color.New(color.FgRed)
|
||||
|
||||
boldRed := red.Add(color.Bold)
|
||||
boldRed.Println("This will print text in bold red.")
|
||||
|
||||
whiteBackground := red.Add(color.BgWhite)
|
||||
whiteBackground.Println("Red text with white background.")
|
||||
```
|
||||
|
||||
### Use your own output (io.Writer)
|
||||
|
||||
```go
|
||||
// Use your own io.Writer output
|
||||
color.New(color.FgBlue).Fprintln(myWriter, "blue color!")
|
||||
|
||||
blue := color.New(color.FgBlue)
|
||||
blue.Fprint(writer, "This will print text in blue.")
|
||||
```
|
||||
|
||||
### Custom print functions (PrintFunc)
|
||||
|
||||
```go
|
||||
// Create a custom print function for convenience
|
||||
red := color.New(color.FgRed).PrintfFunc()
|
||||
red("Warning")
|
||||
red("Error: %s", err)
|
||||
|
||||
// Mix up multiple attributes
|
||||
notice := color.New(color.Bold, color.FgGreen).PrintlnFunc()
|
||||
notice("Don't forget this...")
|
||||
```
|
||||
|
||||
### Custom fprint functions (FprintFunc)
|
||||
|
||||
```go
|
||||
blue := color.New(FgBlue).FprintfFunc()
|
||||
blue(myWriter, "important notice: %s", stars)
|
||||
|
||||
// Mix up with multiple attributes
|
||||
success := color.New(color.Bold, color.FgGreen).FprintlnFunc()
|
||||
success(myWriter, "Don't forget this...")
|
||||
```
|
||||
|
||||
### Insert into noncolor strings (SprintFunc)
|
||||
|
||||
```go
|
||||
// Create SprintXxx functions to mix strings with other non-colorized strings:
|
||||
yellow := color.New(color.FgYellow).SprintFunc()
|
||||
red := color.New(color.FgRed).SprintFunc()
|
||||
fmt.Printf("This is a %s and this is %s.\n", yellow("warning"), red("error"))
|
||||
|
||||
info := color.New(color.FgWhite, color.BgGreen).SprintFunc()
|
||||
fmt.Printf("This %s rocks!\n", info("package"))
|
||||
|
||||
// Use helper functions
|
||||
fmt.Println("This", color.RedString("warning"), "should be not neglected.")
|
||||
fmt.Printf("%v %v\n", color.GreenString("Info:"), "an important message.")
|
||||
|
||||
// Windows supported too! Just don't forget to change the output to color.Output
|
||||
fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS"))
|
||||
```
|
||||
|
||||
### Plug into existing code
|
||||
|
||||
```go
|
||||
// Use handy standard colors
|
||||
color.Set(color.FgYellow)
|
||||
|
||||
fmt.Println("Existing text will now be in yellow")
|
||||
fmt.Printf("This one %s\n", "too")
|
||||
|
||||
color.Unset() // Don't forget to unset
|
||||
|
||||
// You can mix up parameters
|
||||
color.Set(color.FgMagenta, color.Bold)
|
||||
defer color.Unset() // Use it in your function
|
||||
|
||||
fmt.Println("All text will now be bold magenta.")
|
||||
```
|
||||
|
||||
### Disable/Enable color
|
||||
|
||||
There might be a case where you want to explicitly disable/enable color output. the
|
||||
`go-isatty` package will automatically disable color output for non-tty output streams
|
||||
(for example if the output were piped directly to `less`)
|
||||
|
||||
`Color` has support to disable/enable colors both globally and for single color
|
||||
definitions. For example suppose you have a CLI app and a `--no-color` bool flag. You
|
||||
can easily disable the color output with:
|
||||
|
||||
```go
|
||||
|
||||
var flagNoColor = flag.Bool("no-color", false, "Disable color output")
|
||||
|
||||
if *flagNoColor {
|
||||
color.NoColor = true // disables colorized output
|
||||
}
|
||||
```
|
||||
|
||||
It also has support for single color definitions (local). You can
|
||||
disable/enable color output on the fly:
|
||||
|
||||
```go
|
||||
c := color.New(color.FgCyan)
|
||||
c.Println("Prints cyan text")
|
||||
|
||||
c.DisableColor()
|
||||
c.Println("This is printed without any color")
|
||||
|
||||
c.EnableColor()
|
||||
c.Println("This prints again cyan...")
|
||||
```
|
||||
|
||||
## Todo
|
||||
|
||||
* Save/Return previous values
|
||||
* Evaluate fmt.Formatter interface
|
||||
|
||||
|
||||
## Credits
|
||||
|
||||
* [Fatih Arslan](https://github.com/fatih)
|
||||
* Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable)
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) for more details
|
||||
|
||||
603
vendor/github.com/fatih/color/color.go
generated
vendored
Normal file
603
vendor/github.com/fatih/color/color.go
generated
vendored
Normal file
@@ -0,0 +1,603 @@
|
||||
package color
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mattn/go-colorable"
|
||||
"github.com/mattn/go-isatty"
|
||||
)
|
||||
|
||||
var (
|
||||
// NoColor defines if the output is colorized or not. It's dynamically set to
|
||||
// false or true based on the stdout's file descriptor referring to a terminal
|
||||
// or not. This is a global option and affects all colors. For more control
|
||||
// over each color block use the methods DisableColor() individually.
|
||||
NoColor = os.Getenv("TERM") == "dumb" ||
|
||||
(!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd()))
|
||||
|
||||
// Output defines the standard output of the print functions. By default
|
||||
// os.Stdout is used.
|
||||
Output = colorable.NewColorableStdout()
|
||||
|
||||
// Error defines a color supporting writer for os.Stderr.
|
||||
Error = colorable.NewColorableStderr()
|
||||
|
||||
// colorsCache is used to reduce the count of created Color objects and
|
||||
// allows to reuse already created objects with required Attribute.
|
||||
colorsCache = make(map[Attribute]*Color)
|
||||
colorsCacheMu sync.Mutex // protects colorsCache
|
||||
)
|
||||
|
||||
// Color defines a custom color object which is defined by SGR parameters.
|
||||
type Color struct {
|
||||
params []Attribute
|
||||
noColor *bool
|
||||
}
|
||||
|
||||
// Attribute defines a single SGR Code
|
||||
type Attribute int
|
||||
|
||||
const escape = "\x1b"
|
||||
|
||||
// Base attributes
|
||||
const (
|
||||
Reset Attribute = iota
|
||||
Bold
|
||||
Faint
|
||||
Italic
|
||||
Underline
|
||||
BlinkSlow
|
||||
BlinkRapid
|
||||
ReverseVideo
|
||||
Concealed
|
||||
CrossedOut
|
||||
)
|
||||
|
||||
// Foreground text colors
|
||||
const (
|
||||
FgBlack Attribute = iota + 30
|
||||
FgRed
|
||||
FgGreen
|
||||
FgYellow
|
||||
FgBlue
|
||||
FgMagenta
|
||||
FgCyan
|
||||
FgWhite
|
||||
)
|
||||
|
||||
// Foreground Hi-Intensity text colors
|
||||
const (
|
||||
FgHiBlack Attribute = iota + 90
|
||||
FgHiRed
|
||||
FgHiGreen
|
||||
FgHiYellow
|
||||
FgHiBlue
|
||||
FgHiMagenta
|
||||
FgHiCyan
|
||||
FgHiWhite
|
||||
)
|
||||
|
||||
// Background text colors
|
||||
const (
|
||||
BgBlack Attribute = iota + 40
|
||||
BgRed
|
||||
BgGreen
|
||||
BgYellow
|
||||
BgBlue
|
||||
BgMagenta
|
||||
BgCyan
|
||||
BgWhite
|
||||
)
|
||||
|
||||
// Background Hi-Intensity text colors
|
||||
const (
|
||||
BgHiBlack Attribute = iota + 100
|
||||
BgHiRed
|
||||
BgHiGreen
|
||||
BgHiYellow
|
||||
BgHiBlue
|
||||
BgHiMagenta
|
||||
BgHiCyan
|
||||
BgHiWhite
|
||||
)
|
||||
|
||||
// New returns a newly created color object.
|
||||
func New(value ...Attribute) *Color {
|
||||
c := &Color{params: make([]Attribute, 0)}
|
||||
c.Add(value...)
|
||||
return c
|
||||
}
|
||||
|
||||
// Set sets the given parameters immediately. It will change the color of
|
||||
// output with the given SGR parameters until color.Unset() is called.
|
||||
func Set(p ...Attribute) *Color {
|
||||
c := New(p...)
|
||||
c.Set()
|
||||
return c
|
||||
}
|
||||
|
||||
// Unset resets all escape attributes and clears the output. Usually should
|
||||
// be called after Set().
|
||||
func Unset() {
|
||||
if NoColor {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprintf(Output, "%s[%dm", escape, Reset)
|
||||
}
|
||||
|
||||
// Set sets the SGR sequence.
|
||||
func (c *Color) Set() *Color {
|
||||
if c.isNoColorSet() {
|
||||
return c
|
||||
}
|
||||
|
||||
fmt.Fprintf(Output, c.format())
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Color) unset() {
|
||||
if c.isNoColorSet() {
|
||||
return
|
||||
}
|
||||
|
||||
Unset()
|
||||
}
|
||||
|
||||
func (c *Color) setWriter(w io.Writer) *Color {
|
||||
if c.isNoColorSet() {
|
||||
return c
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, c.format())
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Color) unsetWriter(w io.Writer) {
|
||||
if c.isNoColorSet() {
|
||||
return
|
||||
}
|
||||
|
||||
if NoColor {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "%s[%dm", escape, Reset)
|
||||
}
|
||||
|
||||
// Add is used to chain SGR parameters. Use as many as parameters to combine
|
||||
// and create custom color objects. Example: Add(color.FgRed, color.Underline).
|
||||
func (c *Color) Add(value ...Attribute) *Color {
|
||||
c.params = append(c.params, value...)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Color) prepend(value Attribute) {
|
||||
c.params = append(c.params, 0)
|
||||
copy(c.params[1:], c.params[0:])
|
||||
c.params[0] = value
|
||||
}
|
||||
|
||||
// Fprint formats using the default formats for its operands and writes to w.
|
||||
// Spaces are added between operands when neither is a string.
|
||||
// It returns the number of bytes written and any write error encountered.
|
||||
// On Windows, users should wrap w with colorable.NewColorable() if w is of
|
||||
// type *os.File.
|
||||
func (c *Color) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
c.setWriter(w)
|
||||
defer c.unsetWriter(w)
|
||||
|
||||
return fmt.Fprint(w, a...)
|
||||
}
|
||||
|
||||
// Print formats using the default formats for its operands and writes to
|
||||
// standard output. Spaces are added between operands when neither is a
|
||||
// string. It returns the number of bytes written and any write error
|
||||
// encountered. This is the standard fmt.Print() method wrapped with the given
|
||||
// color.
|
||||
func (c *Color) Print(a ...interface{}) (n int, err error) {
|
||||
c.Set()
|
||||
defer c.unset()
|
||||
|
||||
return fmt.Fprint(Output, a...)
|
||||
}
|
||||
|
||||
// Fprintf formats according to a format specifier and writes to w.
|
||||
// It returns the number of bytes written and any write error encountered.
|
||||
// On Windows, users should wrap w with colorable.NewColorable() if w is of
|
||||
// type *os.File.
|
||||
func (c *Color) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
||||
c.setWriter(w)
|
||||
defer c.unsetWriter(w)
|
||||
|
||||
return fmt.Fprintf(w, format, a...)
|
||||
}
|
||||
|
||||
// Printf formats according to a format specifier and writes to standard output.
|
||||
// It returns the number of bytes written and any write error encountered.
|
||||
// This is the standard fmt.Printf() method wrapped with the given color.
|
||||
func (c *Color) Printf(format string, a ...interface{}) (n int, err error) {
|
||||
c.Set()
|
||||
defer c.unset()
|
||||
|
||||
return fmt.Fprintf(Output, format, a...)
|
||||
}
|
||||
|
||||
// Fprintln formats using the default formats for its operands and writes to w.
|
||||
// Spaces are always added between operands and a newline is appended.
|
||||
// On Windows, users should wrap w with colorable.NewColorable() if w is of
|
||||
// type *os.File.
|
||||
func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
c.setWriter(w)
|
||||
defer c.unsetWriter(w)
|
||||
|
||||
return fmt.Fprintln(w, a...)
|
||||
}
|
||||
|
||||
// Println formats using the default formats for its operands and writes to
|
||||
// standard output. Spaces are always added between operands and a newline is
|
||||
// appended. It returns the number of bytes written and any write error
|
||||
// encountered. This is the standard fmt.Print() method wrapped with the given
|
||||
// color.
|
||||
func (c *Color) Println(a ...interface{}) (n int, err error) {
|
||||
c.Set()
|
||||
defer c.unset()
|
||||
|
||||
return fmt.Fprintln(Output, a...)
|
||||
}
|
||||
|
||||
// Sprint is just like Print, but returns a string instead of printing it.
|
||||
func (c *Color) Sprint(a ...interface{}) string {
|
||||
return c.wrap(fmt.Sprint(a...))
|
||||
}
|
||||
|
||||
// Sprintln is just like Println, but returns a string instead of printing it.
|
||||
func (c *Color) Sprintln(a ...interface{}) string {
|
||||
return c.wrap(fmt.Sprintln(a...))
|
||||
}
|
||||
|
||||
// Sprintf is just like Printf, but returns a string instead of printing it.
|
||||
func (c *Color) Sprintf(format string, a ...interface{}) string {
|
||||
return c.wrap(fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// FprintFunc returns a new function that prints the passed arguments as
|
||||
// colorized with color.Fprint().
|
||||
func (c *Color) FprintFunc() func(w io.Writer, a ...interface{}) {
|
||||
return func(w io.Writer, a ...interface{}) {
|
||||
c.Fprint(w, a...)
|
||||
}
|
||||
}
|
||||
|
||||
// PrintFunc returns a new function that prints the passed arguments as
|
||||
// colorized with color.Print().
|
||||
func (c *Color) PrintFunc() func(a ...interface{}) {
|
||||
return func(a ...interface{}) {
|
||||
c.Print(a...)
|
||||
}
|
||||
}
|
||||
|
||||
// FprintfFunc returns a new function that prints the passed arguments as
|
||||
// colorized with color.Fprintf().
|
||||
func (c *Color) FprintfFunc() func(w io.Writer, format string, a ...interface{}) {
|
||||
return func(w io.Writer, format string, a ...interface{}) {
|
||||
c.Fprintf(w, format, a...)
|
||||
}
|
||||
}
|
||||
|
||||
// PrintfFunc returns a new function that prints the passed arguments as
|
||||
// colorized with color.Printf().
|
||||
func (c *Color) PrintfFunc() func(format string, a ...interface{}) {
|
||||
return func(format string, a ...interface{}) {
|
||||
c.Printf(format, a...)
|
||||
}
|
||||
}
|
||||
|
||||
// FprintlnFunc returns a new function that prints the passed arguments as
|
||||
// colorized with color.Fprintln().
|
||||
func (c *Color) FprintlnFunc() func(w io.Writer, a ...interface{}) {
|
||||
return func(w io.Writer, a ...interface{}) {
|
||||
c.Fprintln(w, a...)
|
||||
}
|
||||
}
|
||||
|
||||
// PrintlnFunc returns a new function that prints the passed arguments as
|
||||
// colorized with color.Println().
|
||||
func (c *Color) PrintlnFunc() func(a ...interface{}) {
|
||||
return func(a ...interface{}) {
|
||||
c.Println(a...)
|
||||
}
|
||||
}
|
||||
|
||||
// SprintFunc returns a new function that returns colorized strings for the
|
||||
// given arguments with fmt.Sprint(). Useful to put into or mix into other
|
||||
// string. Windows users should use this in conjunction with color.Output, example:
|
||||
//
|
||||
// put := New(FgYellow).SprintFunc()
|
||||
// fmt.Fprintf(color.Output, "This is a %s", put("warning"))
|
||||
func (c *Color) SprintFunc() func(a ...interface{}) string {
|
||||
return func(a ...interface{}) string {
|
||||
return c.wrap(fmt.Sprint(a...))
|
||||
}
|
||||
}
|
||||
|
||||
// SprintfFunc returns a new function that returns colorized strings for the
|
||||
// given arguments with fmt.Sprintf(). Useful to put into or mix into other
|
||||
// string. Windows users should use this in conjunction with color.Output.
|
||||
func (c *Color) SprintfFunc() func(format string, a ...interface{}) string {
|
||||
return func(format string, a ...interface{}) string {
|
||||
return c.wrap(fmt.Sprintf(format, a...))
|
||||
}
|
||||
}
|
||||
|
||||
// SprintlnFunc returns a new function that returns colorized strings for the
|
||||
// given arguments with fmt.Sprintln(). Useful to put into or mix into other
|
||||
// string. Windows users should use this in conjunction with color.Output.
|
||||
func (c *Color) SprintlnFunc() func(a ...interface{}) string {
|
||||
return func(a ...interface{}) string {
|
||||
return c.wrap(fmt.Sprintln(a...))
|
||||
}
|
||||
}
|
||||
|
||||
// sequence returns a formatted SGR sequence to be plugged into a "\x1b[...m"
|
||||
// an example output might be: "1;36" -> bold cyan
|
||||
func (c *Color) sequence() string {
|
||||
format := make([]string, len(c.params))
|
||||
for i, v := range c.params {
|
||||
format[i] = strconv.Itoa(int(v))
|
||||
}
|
||||
|
||||
return strings.Join(format, ";")
|
||||
}
|
||||
|
||||
// wrap wraps the s string with the colors attributes. The string is ready to
|
||||
// be printed.
|
||||
func (c *Color) wrap(s string) string {
|
||||
if c.isNoColorSet() {
|
||||
return s
|
||||
}
|
||||
|
||||
return c.format() + s + c.unformat()
|
||||
}
|
||||
|
||||
func (c *Color) format() string {
|
||||
return fmt.Sprintf("%s[%sm", escape, c.sequence())
|
||||
}
|
||||
|
||||
func (c *Color) unformat() string {
|
||||
return fmt.Sprintf("%s[%dm", escape, Reset)
|
||||
}
|
||||
|
||||
// DisableColor disables the color output. Useful to not change any existing
|
||||
// code and still being able to output. Can be used for flags like
|
||||
// "--no-color". To enable back use EnableColor() method.
|
||||
func (c *Color) DisableColor() {
|
||||
c.noColor = boolPtr(true)
|
||||
}
|
||||
|
||||
// EnableColor enables the color output. Use it in conjunction with
|
||||
// DisableColor(). Otherwise this method has no side effects.
|
||||
func (c *Color) EnableColor() {
|
||||
c.noColor = boolPtr(false)
|
||||
}
|
||||
|
||||
func (c *Color) isNoColorSet() bool {
|
||||
// check first if we have user setted action
|
||||
if c.noColor != nil {
|
||||
return *c.noColor
|
||||
}
|
||||
|
||||
// if not return the global option, which is disabled by default
|
||||
return NoColor
|
||||
}
|
||||
|
||||
// Equals returns a boolean value indicating whether two colors are equal.
|
||||
func (c *Color) Equals(c2 *Color) bool {
|
||||
if len(c.params) != len(c2.params) {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, attr := range c.params {
|
||||
if !c2.attrExists(attr) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *Color) attrExists(a Attribute) bool {
|
||||
for _, attr := range c.params {
|
||||
if attr == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func boolPtr(v bool) *bool {
|
||||
return &v
|
||||
}
|
||||
|
||||
func getCachedColor(p Attribute) *Color {
|
||||
colorsCacheMu.Lock()
|
||||
defer colorsCacheMu.Unlock()
|
||||
|
||||
c, ok := colorsCache[p]
|
||||
if !ok {
|
||||
c = New(p)
|
||||
colorsCache[p] = c
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func colorPrint(format string, p Attribute, a ...interface{}) {
|
||||
c := getCachedColor(p)
|
||||
|
||||
if !strings.HasSuffix(format, "\n") {
|
||||
format += "\n"
|
||||
}
|
||||
|
||||
if len(a) == 0 {
|
||||
c.Print(format)
|
||||
} else {
|
||||
c.Printf(format, a...)
|
||||
}
|
||||
}
|
||||
|
||||
func colorString(format string, p Attribute, a ...interface{}) string {
|
||||
c := getCachedColor(p)
|
||||
|
||||
if len(a) == 0 {
|
||||
return c.SprintFunc()(format)
|
||||
}
|
||||
|
||||
return c.SprintfFunc()(format, a...)
|
||||
}
|
||||
|
||||
// Black is a convenient helper function to print with black foreground. A
|
||||
// newline is appended to format by default.
|
||||
func Black(format string, a ...interface{}) { colorPrint(format, FgBlack, a...) }
|
||||
|
||||
// Red is a convenient helper function to print with red foreground. A
|
||||
// newline is appended to format by default.
|
||||
func Red(format string, a ...interface{}) { colorPrint(format, FgRed, a...) }
|
||||
|
||||
// Green is a convenient helper function to print with green foreground. A
|
||||
// newline is appended to format by default.
|
||||
func Green(format string, a ...interface{}) { colorPrint(format, FgGreen, a...) }
|
||||
|
||||
// Yellow is a convenient helper function to print with yellow foreground.
|
||||
// A newline is appended to format by default.
|
||||
func Yellow(format string, a ...interface{}) { colorPrint(format, FgYellow, a...) }
|
||||
|
||||
// Blue is a convenient helper function to print with blue foreground. A
|
||||
// newline is appended to format by default.
|
||||
func Blue(format string, a ...interface{}) { colorPrint(format, FgBlue, a...) }
|
||||
|
||||
// Magenta is a convenient helper function to print with magenta foreground.
|
||||
// A newline is appended to format by default.
|
||||
func Magenta(format string, a ...interface{}) { colorPrint(format, FgMagenta, a...) }
|
||||
|
||||
// Cyan is a convenient helper function to print with cyan foreground. A
|
||||
// newline is appended to format by default.
|
||||
func Cyan(format string, a ...interface{}) { colorPrint(format, FgCyan, a...) }
|
||||
|
||||
// White is a convenient helper function to print with white foreground. A
|
||||
// newline is appended to format by default.
|
||||
func White(format string, a ...interface{}) { colorPrint(format, FgWhite, a...) }
|
||||
|
||||
// BlackString is a convenient helper function to return a string with black
|
||||
// foreground.
|
||||
func BlackString(format string, a ...interface{}) string { return colorString(format, FgBlack, a...) }
|
||||
|
||||
// RedString is a convenient helper function to return a string with red
|
||||
// foreground.
|
||||
func RedString(format string, a ...interface{}) string { return colorString(format, FgRed, a...) }
|
||||
|
||||
// GreenString is a convenient helper function to return a string with green
|
||||
// foreground.
|
||||
func GreenString(format string, a ...interface{}) string { return colorString(format, FgGreen, a...) }
|
||||
|
||||
// YellowString is a convenient helper function to return a string with yellow
|
||||
// foreground.
|
||||
func YellowString(format string, a ...interface{}) string { return colorString(format, FgYellow, a...) }
|
||||
|
||||
// BlueString is a convenient helper function to return a string with blue
|
||||
// foreground.
|
||||
func BlueString(format string, a ...interface{}) string { return colorString(format, FgBlue, a...) }
|
||||
|
||||
// MagentaString is a convenient helper function to return a string with magenta
|
||||
// foreground.
|
||||
func MagentaString(format string, a ...interface{}) string {
|
||||
return colorString(format, FgMagenta, a...)
|
||||
}
|
||||
|
||||
// CyanString is a convenient helper function to return a string with cyan
|
||||
// foreground.
|
||||
func CyanString(format string, a ...interface{}) string { return colorString(format, FgCyan, a...) }
|
||||
|
||||
// WhiteString is a convenient helper function to return a string with white
|
||||
// foreground.
|
||||
func WhiteString(format string, a ...interface{}) string { return colorString(format, FgWhite, a...) }
|
||||
|
||||
// HiBlack is a convenient helper function to print with hi-intensity black foreground. A
|
||||
// newline is appended to format by default.
|
||||
func HiBlack(format string, a ...interface{}) { colorPrint(format, FgHiBlack, a...) }
|
||||
|
||||
// HiRed is a convenient helper function to print with hi-intensity red foreground. A
|
||||
// newline is appended to format by default.
|
||||
func HiRed(format string, a ...interface{}) { colorPrint(format, FgHiRed, a...) }
|
||||
|
||||
// HiGreen is a convenient helper function to print with hi-intensity green foreground. A
|
||||
// newline is appended to format by default.
|
||||
func HiGreen(format string, a ...interface{}) { colorPrint(format, FgHiGreen, a...) }
|
||||
|
||||
// HiYellow is a convenient helper function to print with hi-intensity yellow foreground.
|
||||
// A newline is appended to format by default.
|
||||
func HiYellow(format string, a ...interface{}) { colorPrint(format, FgHiYellow, a...) }
|
||||
|
||||
// HiBlue is a convenient helper function to print with hi-intensity blue foreground. A
|
||||
// newline is appended to format by default.
|
||||
func HiBlue(format string, a ...interface{}) { colorPrint(format, FgHiBlue, a...) }
|
||||
|
||||
// HiMagenta is a convenient helper function to print with hi-intensity magenta foreground.
|
||||
// A newline is appended to format by default.
|
||||
func HiMagenta(format string, a ...interface{}) { colorPrint(format, FgHiMagenta, a...) }
|
||||
|
||||
// HiCyan is a convenient helper function to print with hi-intensity cyan foreground. A
|
||||
// newline is appended to format by default.
|
||||
func HiCyan(format string, a ...interface{}) { colorPrint(format, FgHiCyan, a...) }
|
||||
|
||||
// HiWhite is a convenient helper function to print with hi-intensity white foreground. A
|
||||
// newline is appended to format by default.
|
||||
func HiWhite(format string, a ...interface{}) { colorPrint(format, FgHiWhite, a...) }
|
||||
|
||||
// HiBlackString is a convenient helper function to return a string with hi-intensity black
|
||||
// foreground.
|
||||
func HiBlackString(format string, a ...interface{}) string {
|
||||
return colorString(format, FgHiBlack, a...)
|
||||
}
|
||||
|
||||
// HiRedString is a convenient helper function to return a string with hi-intensity red
|
||||
// foreground.
|
||||
func HiRedString(format string, a ...interface{}) string { return colorString(format, FgHiRed, a...) }
|
||||
|
||||
// HiGreenString is a convenient helper function to return a string with hi-intensity green
|
||||
// foreground.
|
||||
func HiGreenString(format string, a ...interface{}) string {
|
||||
return colorString(format, FgHiGreen, a...)
|
||||
}
|
||||
|
||||
// HiYellowString is a convenient helper function to return a string with hi-intensity yellow
|
||||
// foreground.
|
||||
func HiYellowString(format string, a ...interface{}) string {
|
||||
return colorString(format, FgHiYellow, a...)
|
||||
}
|
||||
|
||||
// HiBlueString is a convenient helper function to return a string with hi-intensity blue
|
||||
// foreground.
|
||||
func HiBlueString(format string, a ...interface{}) string { return colorString(format, FgHiBlue, a...) }
|
||||
|
||||
// HiMagentaString is a convenient helper function to return a string with hi-intensity magenta
|
||||
// foreground.
|
||||
func HiMagentaString(format string, a ...interface{}) string {
|
||||
return colorString(format, FgHiMagenta, a...)
|
||||
}
|
||||
|
||||
// HiCyanString is a convenient helper function to return a string with hi-intensity cyan
|
||||
// foreground.
|
||||
func HiCyanString(format string, a ...interface{}) string { return colorString(format, FgHiCyan, a...) }
|
||||
|
||||
// HiWhiteString is a convenient helper function to return a string with hi-intensity white
|
||||
// foreground.
|
||||
func HiWhiteString(format string, a ...interface{}) string {
|
||||
return colorString(format, FgHiWhite, a...)
|
||||
}
|
||||
133
vendor/github.com/fatih/color/doc.go
generated
vendored
Normal file
133
vendor/github.com/fatih/color/doc.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
Package color is an ANSI color package to output colorized or SGR defined
|
||||
output to the standard output. The API can be used in several way, pick one
|
||||
that suits you.
|
||||
|
||||
Use simple and default helper functions with predefined foreground colors:
|
||||
|
||||
color.Cyan("Prints text in cyan.")
|
||||
|
||||
// a newline will be appended automatically
|
||||
color.Blue("Prints %s in blue.", "text")
|
||||
|
||||
// More default foreground colors..
|
||||
color.Red("We have red")
|
||||
color.Yellow("Yellow color too!")
|
||||
color.Magenta("And many others ..")
|
||||
|
||||
// Hi-intensity colors
|
||||
color.HiGreen("Bright green color.")
|
||||
color.HiBlack("Bright black means gray..")
|
||||
color.HiWhite("Shiny white color!")
|
||||
|
||||
However there are times where custom color mixes are required. Below are some
|
||||
examples to create custom color objects and use the print functions of each
|
||||
separate color object.
|
||||
|
||||
// Create a new color object
|
||||
c := color.New(color.FgCyan).Add(color.Underline)
|
||||
c.Println("Prints cyan text with an underline.")
|
||||
|
||||
// Or just add them to New()
|
||||
d := color.New(color.FgCyan, color.Bold)
|
||||
d.Printf("This prints bold cyan %s\n", "too!.")
|
||||
|
||||
|
||||
// Mix up foreground and background colors, create new mixes!
|
||||
red := color.New(color.FgRed)
|
||||
|
||||
boldRed := red.Add(color.Bold)
|
||||
boldRed.Println("This will print text in bold red.")
|
||||
|
||||
whiteBackground := red.Add(color.BgWhite)
|
||||
whiteBackground.Println("Red text with White background.")
|
||||
|
||||
// Use your own io.Writer output
|
||||
color.New(color.FgBlue).Fprintln(myWriter, "blue color!")
|
||||
|
||||
blue := color.New(color.FgBlue)
|
||||
blue.Fprint(myWriter, "This will print text in blue.")
|
||||
|
||||
You can create PrintXxx functions to simplify even more:
|
||||
|
||||
// Create a custom print function for convenient
|
||||
red := color.New(color.FgRed).PrintfFunc()
|
||||
red("warning")
|
||||
red("error: %s", err)
|
||||
|
||||
// Mix up multiple attributes
|
||||
notice := color.New(color.Bold, color.FgGreen).PrintlnFunc()
|
||||
notice("don't forget this...")
|
||||
|
||||
You can also FprintXxx functions to pass your own io.Writer:
|
||||
|
||||
blue := color.New(FgBlue).FprintfFunc()
|
||||
blue(myWriter, "important notice: %s", stars)
|
||||
|
||||
// Mix up with multiple attributes
|
||||
success := color.New(color.Bold, color.FgGreen).FprintlnFunc()
|
||||
success(myWriter, don't forget this...")
|
||||
|
||||
|
||||
Or create SprintXxx functions to mix strings with other non-colorized strings:
|
||||
|
||||
yellow := New(FgYellow).SprintFunc()
|
||||
red := New(FgRed).SprintFunc()
|
||||
|
||||
fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error"))
|
||||
|
||||
info := New(FgWhite, BgGreen).SprintFunc()
|
||||
fmt.Printf("this %s rocks!\n", info("package"))
|
||||
|
||||
Windows support is enabled by default. All Print functions work as intended.
|
||||
However only for color.SprintXXX functions, user should use fmt.FprintXXX and
|
||||
set the output to color.Output:
|
||||
|
||||
fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS"))
|
||||
|
||||
info := New(FgWhite, BgGreen).SprintFunc()
|
||||
fmt.Fprintf(color.Output, "this %s rocks!\n", info("package"))
|
||||
|
||||
Using with existing code is possible. Just use the Set() method to set the
|
||||
standard output to the given parameters. That way a rewrite of an existing
|
||||
code is not required.
|
||||
|
||||
// Use handy standard colors.
|
||||
color.Set(color.FgYellow)
|
||||
|
||||
fmt.Println("Existing text will be now in Yellow")
|
||||
fmt.Printf("This one %s\n", "too")
|
||||
|
||||
color.Unset() // don't forget to unset
|
||||
|
||||
// You can mix up parameters
|
||||
color.Set(color.FgMagenta, color.Bold)
|
||||
defer color.Unset() // use it in your function
|
||||
|
||||
fmt.Println("All text will be now bold magenta.")
|
||||
|
||||
There might be a case where you want to disable color output (for example to
|
||||
pipe the standard output of your app to somewhere else). `Color` has support to
|
||||
disable colors both globally and for single color definition. For example
|
||||
suppose you have a CLI app and a `--no-color` bool flag. You can easily disable
|
||||
the color output with:
|
||||
|
||||
var flagNoColor = flag.Bool("no-color", false, "Disable color output")
|
||||
|
||||
if *flagNoColor {
|
||||
color.NoColor = true // disables colorized output
|
||||
}
|
||||
|
||||
It also has support for single color definitions (local). You can
|
||||
disable/enable color output on the fly:
|
||||
|
||||
c := color.New(color.FgCyan)
|
||||
c.Println("Prints cyan text")
|
||||
|
||||
c.DisableColor()
|
||||
c.Println("This is printed without any color")
|
||||
|
||||
c.EnableColor()
|
||||
c.Println("This prints again cyan...")
|
||||
*/
|
||||
package color
|
||||
3
vendor/github.com/golang-plus/errors/README.md
generated
vendored
Normal file
3
vendor/github.com/golang-plus/errors/README.md
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# errors
|
||||
|
||||
package **errors** providers utilities for manipulate errors and provide stack trace information.
|
||||
6
vendor/github.com/golang-plus/errors/doc.go
generated
vendored
Normal file
6
vendor/github.com/golang-plus/errors/doc.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*
|
||||
|
||||
Package errors providers utilities for manipulate errors and provide stack trace information.
|
||||
|
||||
*/
|
||||
package errors
|
||||
132
vendor/github.com/golang-plus/errors/errors.go
generated
vendored
Normal file
132
vendor/github.com/golang-plus/errors/errors.go
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// location represents a Location information of source code.
|
||||
type location struct {
|
||||
File string
|
||||
Line int
|
||||
}
|
||||
|
||||
// String returns the string of Location with filename:line format.
|
||||
func (l *location) String() string {
|
||||
if len(l.File) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s:%d", l.File, l.Line)
|
||||
}
|
||||
|
||||
// error2 represents an error.
|
||||
type error2 struct {
|
||||
Inner error
|
||||
Location *location
|
||||
Message string
|
||||
}
|
||||
|
||||
// Error implements builtin.error interface.
|
||||
// It returns error message in a tree like format.
|
||||
func (e *error2) Error() string {
|
||||
return TreeMessage(e)
|
||||
}
|
||||
|
||||
func locate(depth int) *location {
|
||||
_, file, line, _ := runtime.Caller(depth + 1)
|
||||
return &location{
|
||||
File: file,
|
||||
Line: line,
|
||||
}
|
||||
}
|
||||
|
||||
// Equal detects whether the error is equal to a given error.
|
||||
// Errors are considered equal by this function if they are the same object, or if they both contain the same error inside.
|
||||
func Equal(err1 error, err2 error) bool {
|
||||
if err1 == err2 {
|
||||
return true
|
||||
}
|
||||
|
||||
if v, ok := err1.(*error2); ok {
|
||||
return Equal(v.Inner, err2)
|
||||
}
|
||||
|
||||
if v, ok := err2.(*error2); ok {
|
||||
return Equal(v.Inner, err1)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// TreeMessage returns the errors message in a tree like format:
|
||||
// ├─ error message -> filename:line
|
||||
// | ├─ error message -> filename:line
|
||||
// | └─ error 3
|
||||
func TreeMessage(err error) string {
|
||||
if err == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
depth := 1
|
||||
for {
|
||||
if depth > 1 {
|
||||
buf.WriteString("\n|")
|
||||
buf.WriteString(strings.Repeat(" ", (depth-1)*3-1))
|
||||
}
|
||||
|
||||
if e, ok := err.(*error2); ok {
|
||||
buf.WriteString("├─ " + e.Message + " -> " + e.Location.String())
|
||||
err = e.Inner
|
||||
} else {
|
||||
buf.WriteString("└─ " + err.Error())
|
||||
err = nil
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
|
||||
depth++
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// New returns a new Error.
|
||||
// It's used to instead of built-in errors.New function.
|
||||
func New(message string) error {
|
||||
return &error2{
|
||||
Location: locate(1),
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// Newf same as New, but with fmt.Printf-style parameters.
|
||||
func Newf(format string, args ...interface{}) error {
|
||||
return &error2{
|
||||
Location: locate(1),
|
||||
Message: fmt.Sprintf(format, args...),
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap returns a new wrapped Error.
|
||||
func Wrap(err error, message string) error {
|
||||
return &error2{
|
||||
Inner: err,
|
||||
Location: locate(2),
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapf same as Wrap, but with fmt.Printf-style parameters.
|
||||
func Wrapf(err error, format string, args ...interface{}) error {
|
||||
return &error2{
|
||||
Inner: err,
|
||||
Location: locate(2),
|
||||
Message: fmt.Sprintf(format, args...),
|
||||
}
|
||||
}
|
||||
45
vendor/github.com/golang-plus/uuid/README.md
generated
vendored
Normal file
45
vendor/github.com/golang-plus/uuid/README.md
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
# uuid
|
||||
|
||||
Package **uuid** implements UUID [RFC 4122](http://www.ietf.org/rfc/rfc4122.txt).
|
||||
|
||||
## Usage
|
||||
|
||||
### Generating
|
||||
|
||||
#### Time-Based (Version 1)
|
||||
|
||||
uuid.NewTimeBased() (uuid.UUID, error)
|
||||
uuid.NewV1() (uuid.UUID, error)
|
||||
|
||||
#### DCE Security (Version 2)
|
||||
|
||||
uuid.NewDCESecurity(uuid.Domain) (uuid.UUID, error)
|
||||
uuid.NewV2(uuid.Domain) (uuid.UUID, error)
|
||||
|
||||
#### Name-Based uses MD5 hashing (Version 3)
|
||||
|
||||
uuid.NewNameBasedMD5(namespace, name string) (uuid.UUID, error)
|
||||
uuid.NewV3(namespace, name string) (uuid.UUID, error)
|
||||
|
||||
#### Random (Version 4)
|
||||
|
||||
uuid.NewRandom() (uuid.UUID, error)
|
||||
uuid.NewV4() (uuid.UUID, error)
|
||||
|
||||
#### Name-Based uses SHA-1 hashing (Version 5)
|
||||
|
||||
uuid.NewNameBasedSHA1(namespace, name string) (uuid.UUID, error)
|
||||
uuid.NewV5(namespace, name string) (uuid.UUID, error)
|
||||
|
||||
### Styles
|
||||
|
||||
* Standard: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12, length: 36)
|
||||
* Without Dash: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (length: 32)
|
||||
|
||||
### Formatting & Parsing
|
||||
|
||||
uuid.UUID.String() string // format to standard style
|
||||
uuid.UUID.Format(uuid.Style) string // format to uuid.StyleStandard or uuid.StyleWithoutDash
|
||||
|
||||
uuid.Parse(string) (uuid.UUID, error) // parse from UUID string
|
||||
|
||||
6
vendor/github.com/golang-plus/uuid/doc.go
generated
vendored
Normal file
6
vendor/github.com/golang-plus/uuid/doc.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*
|
||||
|
||||
Package uuid implements UUID described in RFC 4122.
|
||||
|
||||
*/
|
||||
package uuid
|
||||
15
vendor/github.com/golang-plus/uuid/domain.go
generated
vendored
Normal file
15
vendor/github.com/golang-plus/uuid/domain.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"github.com/golang-plus/uuid/internal/dcesecurity"
|
||||
)
|
||||
|
||||
// Domain represents the identifier for a local domain.
|
||||
type Domain byte
|
||||
|
||||
const (
|
||||
// DomainUser represents POSIX UID domain.
|
||||
DomainUser = Domain(dcesecurity.User)
|
||||
// DomainGroup represents POSIX GID domain.
|
||||
DomainGroup = Domain(dcesecurity.Group)
|
||||
)
|
||||
37
vendor/github.com/golang-plus/uuid/internal/dcesecurity/dcesecurity.go
generated
vendored
Normal file
37
vendor/github.com/golang-plus/uuid/internal/dcesecurity/dcesecurity.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
package dcesecurity
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"os"
|
||||
|
||||
"github.com/golang-plus/uuid/internal"
|
||||
"github.com/golang-plus/uuid/internal/timebased"
|
||||
|
||||
"github.com/golang-plus/errors"
|
||||
)
|
||||
|
||||
// NewUUID Generate returns a new DCE security uuid.
|
||||
func NewUUID(domain Domain) ([]byte, error) {
|
||||
uuid, err := timebased.NewUUID()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch domain {
|
||||
case User:
|
||||
uid := os.Getuid()
|
||||
binary.BigEndian.PutUint32(uuid[0:], uint32(uid)) // network byte order
|
||||
case Group:
|
||||
gid := os.Getgid()
|
||||
binary.BigEndian.PutUint32(uuid[0:], uint32(gid)) // network byte order
|
||||
default:
|
||||
return nil, errors.New("domain is invalid")
|
||||
}
|
||||
|
||||
// set version(v2)
|
||||
internal.SetVersion(uuid, internal.VersionDCESecurity)
|
||||
// set layout(RFC4122)
|
||||
internal.SetLayout(uuid, internal.LayoutRFC4122)
|
||||
|
||||
return uuid, nil
|
||||
}
|
||||
11
vendor/github.com/golang-plus/uuid/internal/dcesecurity/domain.go
generated
vendored
Normal file
11
vendor/github.com/golang-plus/uuid/internal/dcesecurity/domain.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
package dcesecurity
|
||||
|
||||
// Domain represents the identifier for a local domain.
|
||||
type Domain byte
|
||||
|
||||
const (
|
||||
// User represents POSIX UID domain.
|
||||
User Domain = iota + 1
|
||||
// Group represents POSIX GID domain.
|
||||
Group
|
||||
)
|
||||
50
vendor/github.com/golang-plus/uuid/internal/layout.go
generated
vendored
Normal file
50
vendor/github.com/golang-plus/uuid/internal/layout.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
package internal
|
||||
|
||||
// Layout represents the layout of UUID. See page 5 in RFC 4122.
|
||||
type Layout byte
|
||||
|
||||
const (
|
||||
// LayoutInvalid represents invalid layout.
|
||||
LayoutInvalid Layout = iota
|
||||
// LayoutNCS represents the NCS layout: Reserved, NCS backward compatibility (Values: 0x00-0x07).
|
||||
LayoutNCS
|
||||
// LayoutRFC4122 represents the RFC4122 layout: The variant specified in RFC 4122 (Values: 0x08-0x0b).
|
||||
LayoutRFC4122
|
||||
// LayoutMicrosoft represents the Microsoft layout: Reserved, Microsoft Corporation backward compatibility (Values: 0x0c-0x0d).
|
||||
LayoutMicrosoft
|
||||
// LayoutFuture represents the Future layout: Reserved for future definition. (Values: 0x0e-0x0f).
|
||||
LayoutFuture
|
||||
)
|
||||
|
||||
// SetLayout sets the layout for uuid.
|
||||
// This is intended to be called from the New function in packages that implement uuid generating functions.
|
||||
func SetLayout(uuid []byte, layout Layout) {
|
||||
switch layout {
|
||||
case LayoutNCS:
|
||||
uuid[8] = (uuid[8] | 0x00) & 0x0f // Msb0=0
|
||||
case LayoutRFC4122:
|
||||
uuid[8] = (uuid[8] | 0x80) & 0x8f // Msb0=1, Msb1=0
|
||||
case LayoutMicrosoft:
|
||||
uuid[8] = (uuid[8] | 0xc0) & 0xcf // Msb0=1, Msb1=1, Msb2=0
|
||||
case LayoutFuture:
|
||||
uuid[8] = (uuid[8] | 0xe0) & 0xef // Msb0=1, Msb1=1, Msb2=1
|
||||
default:
|
||||
panic("layout is invalid")
|
||||
}
|
||||
}
|
||||
|
||||
// GetLayout returns layout of uuid.
|
||||
func GetLayout(uuid []byte) Layout {
|
||||
switch {
|
||||
case (uuid[8] & 0x80) == 0x00:
|
||||
return LayoutNCS
|
||||
case (uuid[8] & 0xc0) == 0x80:
|
||||
return LayoutRFC4122
|
||||
case (uuid[8] & 0xe0) == 0xc0:
|
||||
return LayoutMicrosoft
|
||||
case (uuid[8] & 0xe0) == 0xe0:
|
||||
return LayoutFuture
|
||||
}
|
||||
|
||||
return LayoutInvalid
|
||||
}
|
||||
34
vendor/github.com/golang-plus/uuid/internal/namebased/md5/md5.go
generated
vendored
Normal file
34
vendor/github.com/golang-plus/uuid/internal/namebased/md5/md5.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
package md5
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
|
||||
"github.com/golang-plus/uuid/internal"
|
||||
|
||||
"github.com/golang-plus/errors"
|
||||
)
|
||||
|
||||
// NewUUID returns a new name-based uses SHA-1 hashing uuid.
|
||||
func NewUUID(namespace, name string) ([]byte, error) {
|
||||
hash := md5.New()
|
||||
_, err := hash.Write([]byte(namespace))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not compute hash value for namespace %q", namespace)
|
||||
}
|
||||
_, err = hash.Write([]byte(name))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not compute hash value for name %q", name)
|
||||
}
|
||||
|
||||
sum := hash.Sum(nil)
|
||||
|
||||
uuid := make([]byte, 16)
|
||||
copy(uuid, sum)
|
||||
|
||||
// set version(v3)
|
||||
internal.SetVersion(uuid, internal.VersionNameBasedMD5)
|
||||
// set layout(RFC4122)
|
||||
internal.SetLayout(uuid, internal.LayoutRFC4122)
|
||||
|
||||
return uuid, nil
|
||||
}
|
||||
9
vendor/github.com/golang-plus/uuid/internal/namebased/namebased.go
generated
vendored
Normal file
9
vendor/github.com/golang-plus/uuid/internal/namebased/namebased.go
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
package namebased
|
||||
|
||||
// Standard Namespaces.
|
||||
const (
|
||||
NamespaceDNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
||||
NamespaceURL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
|
||||
NamespaceOID = "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
|
||||
NamespaceX500 = "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
|
||||
)
|
||||
34
vendor/github.com/golang-plus/uuid/internal/namebased/sha1/sha1.go
generated
vendored
Normal file
34
vendor/github.com/golang-plus/uuid/internal/namebased/sha1/sha1.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
package sha1
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
|
||||
"github.com/golang-plus/uuid/internal"
|
||||
|
||||
"github.com/golang-plus/errors"
|
||||
)
|
||||
|
||||
// NewUUID returns a new name-based uses SHA-1 hashing uuid.
|
||||
func NewUUID(namespace, name string) ([]byte, error) {
|
||||
hash := sha1.New()
|
||||
_, err := hash.Write([]byte(namespace))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not compute hash value for namespace %q", namespace)
|
||||
}
|
||||
_, err = hash.Write([]byte(name))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not compute hash value for name %q", name)
|
||||
}
|
||||
|
||||
sum := hash.Sum(nil)
|
||||
|
||||
uuid := make([]byte, 16)
|
||||
copy(uuid, sum)
|
||||
|
||||
// set version(v5)
|
||||
internal.SetVersion(uuid, internal.VersionNameBasedSHA1)
|
||||
// set layout(RFC4122)
|
||||
internal.SetLayout(uuid, internal.LayoutRFC4122)
|
||||
|
||||
return uuid, nil
|
||||
}
|
||||
28
vendor/github.com/golang-plus/uuid/internal/random/random.go
generated
vendored
Normal file
28
vendor/github.com/golang-plus/uuid/internal/random/random.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
package random
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
|
||||
"github.com/golang-plus/uuid/internal"
|
||||
|
||||
"github.com/golang-plus/errors"
|
||||
)
|
||||
|
||||
// NewUUID returns a new randomly uuid.
|
||||
func NewUUID() ([]byte, error) {
|
||||
uuid := make([]byte, 16)
|
||||
n, err := rand.Read(uuid[:])
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not generate random bytes")
|
||||
}
|
||||
if n != len(uuid) {
|
||||
return nil, errors.New("could not generate random bytes with 16 length")
|
||||
}
|
||||
|
||||
// set version(v4)
|
||||
internal.SetVersion(uuid, internal.VersionRandom)
|
||||
// set layout(RFC4122)
|
||||
internal.SetLayout(uuid, internal.LayoutRFC4122)
|
||||
|
||||
return uuid, nil
|
||||
}
|
||||
93
vendor/github.com/golang-plus/uuid/internal/timebased/timebased.go
generated
vendored
Normal file
93
vendor/github.com/golang-plus/uuid/internal/timebased/timebased.go
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
package timebased
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/golang-plus/uuid/internal"
|
||||
|
||||
"github.com/golang-plus/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
// Intervals bewteen 1/1/1970 and 15/10/1582 (Julain days of 1 Jan 1970 - Julain days of 15 Oct 1582) * 100-Nanoseconds Per Day
|
||||
intervals = (2440587 - 2299160) * 86400 * 10000000
|
||||
)
|
||||
|
||||
var (
|
||||
lastGenerated time.Time // last generated time
|
||||
clockSequence uint16 // clock sequence for same tick
|
||||
nodeID []byte // node id (MAC Address)
|
||||
locker sync.Mutex // global lock
|
||||
)
|
||||
|
||||
// NewUUID returns a new time-based uuid.
|
||||
func NewUUID() ([]byte, error) {
|
||||
// Get and release a global lock
|
||||
locker.Lock()
|
||||
defer locker.Unlock()
|
||||
|
||||
uuid := make([]byte, 16)
|
||||
|
||||
// get timestamp
|
||||
now := time.Now().UTC()
|
||||
timestamp := uint64(now.UnixNano()/100) + intervals // get timestamp
|
||||
if !now.After(lastGenerated) {
|
||||
clockSequence++ // last generated time known, then just increment clock sequence
|
||||
} else {
|
||||
b := make([]byte, 2)
|
||||
_, err := rand.Read(b)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not generate clock sequence")
|
||||
}
|
||||
clockSequence = uint16(int(b[0])<<8 | int(b[1])) // set to a random value (network byte order)
|
||||
}
|
||||
|
||||
lastGenerated = now // remember the last generated time
|
||||
|
||||
timeLow := uint32(timestamp & 0xffffffff)
|
||||
timeMiddle := uint16((timestamp >> 32) & 0xffff)
|
||||
timeHigh := uint16((timestamp >> 48) & 0xfff)
|
||||
|
||||
// network byte order(BigEndian)
|
||||
binary.BigEndian.PutUint32(uuid[0:], timeLow)
|
||||
binary.BigEndian.PutUint16(uuid[4:], timeMiddle)
|
||||
binary.BigEndian.PutUint16(uuid[6:], timeHigh)
|
||||
binary.BigEndian.PutUint16(uuid[8:], clockSequence)
|
||||
|
||||
// get node id(mac address)
|
||||
if nodeID == nil {
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get network interfaces")
|
||||
}
|
||||
|
||||
for _, i := range interfaces {
|
||||
if len(i.HardwareAddr) >= 6 {
|
||||
nodeID = make([]byte, 6)
|
||||
copy(nodeID, i.HardwareAddr)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if nodeID == nil {
|
||||
nodeID = make([]byte, 6)
|
||||
_, err := rand.Read(nodeID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not generate node id")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
copy(uuid[10:], nodeID)
|
||||
|
||||
// set version(v1)
|
||||
internal.SetVersion(uuid, internal.VersionTimeBased)
|
||||
// set layout(RFC4122)
|
||||
internal.SetLayout(uuid, internal.LayoutRFC4122)
|
||||
|
||||
return uuid, nil
|
||||
}
|
||||
43
vendor/github.com/golang-plus/uuid/internal/version.go
generated
vendored
Normal file
43
vendor/github.com/golang-plus/uuid/internal/version.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
package internal
|
||||
|
||||
// Version represents the version of UUID. See page 7 in RFC 4122.
|
||||
type Version byte
|
||||
|
||||
// Version List
|
||||
const (
|
||||
VersionUnknown Version = iota // Unknwon
|
||||
VersionTimeBased // V1: The time-based version
|
||||
VersionDCESecurity // V2: The DCE security version, with embedded POSIX UIDs
|
||||
VersionNameBasedMD5 // V3: The name-based version that uses MD5 hashing
|
||||
VersionRandom // V4: The randomly or pseudo-randomly generated version
|
||||
VersionNameBasedSHA1 // V5: The name-based version that uses SHA-1 hashing
|
||||
)
|
||||
|
||||
// SetVersion sets the version for uuid.
|
||||
// This is intended to be called from the New function in packages that implement uuid generating functions.
|
||||
func SetVersion(uuid []byte, version Version) {
|
||||
switch version {
|
||||
case VersionTimeBased:
|
||||
uuid[6] = (uuid[6] | 0x10) & 0x1f
|
||||
case VersionDCESecurity:
|
||||
uuid[6] = (uuid[6] | 0x20) & 0x2f
|
||||
case VersionNameBasedMD5:
|
||||
uuid[6] = (uuid[6] | 0x30) & 0x3f
|
||||
case VersionRandom:
|
||||
uuid[6] = (uuid[6] | 0x40) & 0x4f
|
||||
case VersionNameBasedSHA1:
|
||||
uuid[6] = (uuid[6] | 0x50) & 0x5f
|
||||
default:
|
||||
panic("version is unknown")
|
||||
}
|
||||
}
|
||||
|
||||
// GetVersion gets the version of uuid.
|
||||
func GetVersion(uuid []byte) Version {
|
||||
ver := uuid[6] >> 4
|
||||
if ver > 0 && ver < 6 {
|
||||
return Version(ver)
|
||||
}
|
||||
|
||||
return VersionUnknown
|
||||
}
|
||||
37
vendor/github.com/golang-plus/uuid/layout.go
generated
vendored
Normal file
37
vendor/github.com/golang-plus/uuid/layout.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"github.com/golang-plus/uuid/internal"
|
||||
)
|
||||
|
||||
// Layout represents the layout of UUID. See page 5 in RFC 4122.
|
||||
type Layout byte
|
||||
|
||||
const (
|
||||
// LayoutInvalid represents invalid layout.
|
||||
LayoutInvalid = Layout(internal.LayoutInvalid)
|
||||
// LayoutNCS represents the layout: Reserved, NCS backward compatibility.
|
||||
LayoutNCS = Layout(internal.LayoutNCS)
|
||||
// LayoutRFC4122 represents the layout: The variant specified in RFC 4122.
|
||||
LayoutRFC4122 = Layout(internal.LayoutRFC4122)
|
||||
// LayoutMicrosoft represents the layout: Reserved, Microsoft Corporation backward compatibility.
|
||||
LayoutMicrosoft = Layout(internal.LayoutMicrosoft)
|
||||
// LayoutFuture represents the layout: Reserved for future definition.
|
||||
LayoutFuture = Layout(internal.LayoutFuture)
|
||||
)
|
||||
|
||||
// String returns English description of layout.
|
||||
func (l Layout) String() string {
|
||||
switch l {
|
||||
case LayoutNCS:
|
||||
return "Reserved For NCS"
|
||||
case LayoutRFC4122:
|
||||
return "RFC 4122"
|
||||
case LayoutMicrosoft:
|
||||
return "Reserved For Microsoft"
|
||||
case LayoutFuture:
|
||||
return "Reserved For Future"
|
||||
default:
|
||||
return "Invalid"
|
||||
}
|
||||
}
|
||||
13
vendor/github.com/golang-plus/uuid/namespace.go
generated
vendored
Normal file
13
vendor/github.com/golang-plus/uuid/namespace.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"github.com/golang-plus/uuid/internal/namebased"
|
||||
)
|
||||
|
||||
// Standard Namespaces.
|
||||
const (
|
||||
NamespaceDNS = namebased.NamespaceDNS // "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
||||
NamespaceURL = namebased.NamespaceURL // "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
|
||||
NamespaceOID = namebased.NamespaceOID // "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
|
||||
NamespaceX500 = namebased.NamespaceX500 // "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
|
||||
)
|
||||
60
vendor/github.com/golang-plus/uuid/parse.go
generated
vendored
Normal file
60
vendor/github.com/golang-plus/uuid/parse.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
|
||||
"github.com/golang-plus/errors"
|
||||
)
|
||||
|
||||
// Parse parses the UUID string.
|
||||
func Parse(str string) (UUID, error) {
|
||||
length := len(str)
|
||||
buffer := make([]byte, 16)
|
||||
indexes := []int{}
|
||||
switch length {
|
||||
case 36:
|
||||
if str[8] != '-' || str[13] != '-' || str[18] != '-' || str[23] != '-' {
|
||||
return Nil, errors.Newf("format of UUID string %q is invalid, it should be xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12)", str)
|
||||
}
|
||||
indexes = []int{0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34}
|
||||
case 32:
|
||||
indexes = []int{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}
|
||||
default:
|
||||
return Nil, errors.Newf("length of UUID string %q is invalid, it should be 36 (standard) or 32 (without dash)", str)
|
||||
}
|
||||
|
||||
var err error
|
||||
for i, v := range indexes {
|
||||
if c, e := hex.DecodeString(str[v : v+2]); e == nil {
|
||||
buffer[i] = c[0]
|
||||
} else {
|
||||
err = e
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return Nil, errors.Wrapf(err, "UUID string %q is invalid", str)
|
||||
}
|
||||
|
||||
uuid := UUID{}
|
||||
copy(uuid[:], buffer)
|
||||
|
||||
if !uuid.Equal(Nil) {
|
||||
if uuid.Layout() == LayoutInvalid {
|
||||
return Nil, errors.Newf("layout of UUID %q is invalid", str)
|
||||
}
|
||||
|
||||
if uuid.Version() == VersionUnknown {
|
||||
return Nil, errors.Newf("version of UUID %q is unknown", str)
|
||||
}
|
||||
}
|
||||
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
// IsValid reports whether the passed string is a valid uuid string.
|
||||
func IsValid(uuid string) bool {
|
||||
_, err := Parse(uuid)
|
||||
return err == nil
|
||||
}
|
||||
23
vendor/github.com/golang-plus/uuid/style.go
generated
vendored
Normal file
23
vendor/github.com/golang-plus/uuid/style.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
package uuid
|
||||
|
||||
// Style represents the style of UUID string.
|
||||
type Style byte
|
||||
|
||||
const (
|
||||
// StyleStandard represents the standard style of UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12, length: 36).
|
||||
StyleStandard Style = iota + 1
|
||||
// StyleWithoutDash represents the style without dash of UUID: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (length: 32).
|
||||
StyleWithoutDash
|
||||
)
|
||||
|
||||
// String returns English description of style.
|
||||
func (s Style) String() string {
|
||||
switch s {
|
||||
case StyleStandard:
|
||||
return "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12)"
|
||||
case StyleWithoutDash:
|
||||
return "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
147
vendor/github.com/golang-plus/uuid/uuid.go
generated
vendored
Normal file
147
vendor/github.com/golang-plus/uuid/uuid.go
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/golang-plus/uuid/internal"
|
||||
"github.com/golang-plus/uuid/internal/dcesecurity"
|
||||
"github.com/golang-plus/uuid/internal/namebased/md5"
|
||||
"github.com/golang-plus/uuid/internal/namebased/sha1"
|
||||
"github.com/golang-plus/uuid/internal/random"
|
||||
"github.com/golang-plus/uuid/internal/timebased"
|
||||
)
|
||||
|
||||
// UUID respresents an UUID type compliant with specification in RFC 4122.
|
||||
type UUID [16]byte
|
||||
|
||||
// Layout returns layout of UUID.
|
||||
func (u UUID) Layout() Layout {
|
||||
return Layout(internal.GetLayout(u[:]))
|
||||
}
|
||||
|
||||
// Version returns version of UUID.
|
||||
func (u UUID) Version() Version {
|
||||
return Version(internal.GetVersion(u[:]))
|
||||
}
|
||||
|
||||
// Equal returns true if current uuid equal to passed uuid.
|
||||
func (u UUID) Equal(another UUID) bool {
|
||||
return bytes.EqualFold(u[:], another[:])
|
||||
}
|
||||
|
||||
// Format returns the formatted string of UUID.
|
||||
func (u UUID) Format(style Style) string {
|
||||
switch style {
|
||||
case StyleWithoutDash:
|
||||
return fmt.Sprintf("%x", u[:])
|
||||
//case StyleStandard:
|
||||
default:
|
||||
return fmt.Sprintf("%08x-%04x-%04x-%04x-%012x", u[:4], u[4:6], u[6:8], u[8:10], u[10:])
|
||||
}
|
||||
}
|
||||
|
||||
// String returns the string of UUID with standard style(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | 8-4-4-4-12).
|
||||
func (u UUID) String() string {
|
||||
return u.Format(StyleStandard)
|
||||
}
|
||||
|
||||
var (
|
||||
// Nil represents the Nil UUID (00000000-0000-0000-0000-000000000000).
|
||||
Nil = UUID{}
|
||||
)
|
||||
|
||||
// NewTimeBased returns a new time based UUID (version 1).
|
||||
func NewTimeBased() (UUID, error) {
|
||||
u, err := timebased.NewUUID()
|
||||
if err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
|
||||
uuid := UUID{}
|
||||
copy(uuid[:], u)
|
||||
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
// NewV1 is short of NewTimeBased.
|
||||
func NewV1() (UUID, error) {
|
||||
return NewTimeBased()
|
||||
}
|
||||
|
||||
// NewDCESecurity returns a new DCE security UUID (version 2).
|
||||
func NewDCESecurity(domain Domain) (UUID, error) {
|
||||
u, err := dcesecurity.NewUUID(dcesecurity.Domain(domain))
|
||||
if err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
|
||||
uuid := UUID{}
|
||||
copy(uuid[:], u)
|
||||
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
// NewV2 is short of NewDCESecurity.
|
||||
func NewV2(domain Domain) (UUID, error) {
|
||||
return NewDCESecurity(domain)
|
||||
}
|
||||
|
||||
// NewNameBasedMD5 returns a new name based UUID with MD5 hash (version 3).
|
||||
func NewNameBasedMD5(namespace, name string) (UUID, error) {
|
||||
u, err := md5.NewUUID(namespace, name)
|
||||
if err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
|
||||
uuid := UUID{}
|
||||
copy(uuid[:], u)
|
||||
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
// NewV3 is short of NewNameBasedMD5.
|
||||
func NewV3(namespace, name string) (UUID, error) {
|
||||
return NewNameBasedMD5(namespace, name)
|
||||
}
|
||||
|
||||
// NewRandom returns a new random UUID (version 4).
|
||||
func NewRandom() (UUID, error) {
|
||||
u, err := random.NewUUID()
|
||||
if err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
|
||||
uuid := UUID{}
|
||||
copy(uuid[:], u)
|
||||
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
// NewV4 is short of NewRandom.
|
||||
func NewV4() (UUID, error) {
|
||||
return NewRandom()
|
||||
}
|
||||
|
||||
// New is short of NewRandom.
|
||||
func New() (UUID, error) {
|
||||
return NewRandom()
|
||||
}
|
||||
|
||||
// NewNameBasedSHA1 returns a new name based UUID with SHA1 hash (version 5).
|
||||
func NewNameBasedSHA1(namespace, name string) (UUID, error) {
|
||||
u, err := sha1.NewUUID(namespace, name)
|
||||
if err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
|
||||
uuid := UUID{}
|
||||
copy(uuid[:], u)
|
||||
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
// NewV5 is short of NewNameBasedSHA1.
|
||||
func NewV5(namespace, name string) (UUID, error) {
|
||||
return NewNameBasedSHA1(namespace, name)
|
||||
}
|
||||
51
vendor/github.com/golang-plus/uuid/version.go
generated
vendored
Normal file
51
vendor/github.com/golang-plus/uuid/version.go
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"github.com/golang-plus/uuid/internal"
|
||||
)
|
||||
|
||||
// Version represents the version of UUID. See page 7 in RFC 4122.
|
||||
type Version byte
|
||||
|
||||
// Versions.
|
||||
const (
|
||||
// VersionUnknown represents unknown version.
|
||||
VersionUnknown = Version(internal.VersionUnknown)
|
||||
// VersionTimeBased represents the time-based version (Version 1).
|
||||
VersionTimeBased = Version(internal.VersionTimeBased)
|
||||
// VersionDCESecurity represents the DCE security version, with embedded POSIX UIDs (Version 2).
|
||||
VersionDCESecurity = Version(internal.VersionDCESecurity)
|
||||
// VersionNameBasedMD5 represents the name-based version that uses MD5 hashing (Version 3).
|
||||
VersionNameBasedMD5 = Version(internal.VersionNameBasedMD5)
|
||||
// VersionRandom represents the randomly or pseudo-randomly generated version (Version 4).
|
||||
VersionRandom = Version(internal.VersionRandom)
|
||||
// VersionNameBasedSHA1 represents the name-based version that uses SHA-1 hashing (Version 5).
|
||||
VersionNameBasedSHA1 = Version(internal.VersionNameBasedSHA1)
|
||||
)
|
||||
|
||||
// Short names of versions.
|
||||
const (
|
||||
V1 = VersionTimeBased
|
||||
V2 = VersionDCESecurity
|
||||
V3 = VersionNameBasedMD5
|
||||
V4 = VersionRandom
|
||||
V5 = VersionNameBasedSHA1
|
||||
)
|
||||
|
||||
// String returns English description of Version.
|
||||
func (v Version) String() string {
|
||||
switch v {
|
||||
case VersionTimeBased:
|
||||
return "Version 1: Time-Based"
|
||||
case VersionDCESecurity:
|
||||
return "Version 2: DCE Security With Embedded POSIX UIDs"
|
||||
case VersionNameBasedMD5:
|
||||
return "Version 3: Name-Based (MD5)"
|
||||
case VersionRandom:
|
||||
return "Version 4: Randomly OR Pseudo-Randomly Generated"
|
||||
case VersionNameBasedSHA1:
|
||||
return "Version 5: Name-Based (SHA-1)"
|
||||
default:
|
||||
return "Version: Unknwon"
|
||||
}
|
||||
}
|
||||
9
vendor/github.com/mattn/go-colorable/.travis.yml
generated
vendored
Normal file
9
vendor/github.com/mattn/go-colorable/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
language: go
|
||||
go:
|
||||
- tip
|
||||
|
||||
before_install:
|
||||
- go get github.com/mattn/goveralls
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
script:
|
||||
- $HOME/gopath/bin/goveralls -repotoken xnXqRGwgW3SXIguzxf90ZSK1GPYZPaGrw
|
||||
21
vendor/github.com/mattn/go-colorable/LICENSE
generated
vendored
Normal file
21
vendor/github.com/mattn/go-colorable/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Yasuhiro Matsumoto
|
||||
|
||||
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.
|
||||
48
vendor/github.com/mattn/go-colorable/README.md
generated
vendored
Normal file
48
vendor/github.com/mattn/go-colorable/README.md
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
# go-colorable
|
||||
|
||||
[](http://godoc.org/github.com/mattn/go-colorable)
|
||||
[](https://travis-ci.org/mattn/go-colorable)
|
||||
[](https://coveralls.io/github/mattn/go-colorable?branch=master)
|
||||
[](https://goreportcard.com/report/mattn/go-colorable)
|
||||
|
||||
Colorable writer for windows.
|
||||
|
||||
For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.)
|
||||
This package is possible to handle escape sequence for ansi color on windows.
|
||||
|
||||
## Too Bad!
|
||||
|
||||

|
||||
|
||||
|
||||
## So Good!
|
||||
|
||||

|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true})
|
||||
logrus.SetOutput(colorable.NewColorableStdout())
|
||||
|
||||
logrus.Info("succeeded")
|
||||
logrus.Warn("not correct")
|
||||
logrus.Error("something error")
|
||||
logrus.Fatal("panic")
|
||||
```
|
||||
|
||||
You can compile above code on non-windows OSs.
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ go get github.com/mattn/go-colorable
|
||||
```
|
||||
|
||||
# License
|
||||
|
||||
MIT
|
||||
|
||||
# Author
|
||||
|
||||
Yasuhiro Matsumoto (a.k.a mattn)
|
||||
29
vendor/github.com/mattn/go-colorable/colorable_appengine.go
generated
vendored
Normal file
29
vendor/github.com/mattn/go-colorable/colorable_appengine.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// +build appengine
|
||||
|
||||
package colorable
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
_ "github.com/mattn/go-isatty"
|
||||
)
|
||||
|
||||
// NewColorable return new instance of Writer which handle escape sequence.
|
||||
func NewColorable(file *os.File) io.Writer {
|
||||
if file == nil {
|
||||
panic("nil passed instead of *os.File to NewColorable()")
|
||||
}
|
||||
|
||||
return file
|
||||
}
|
||||
|
||||
// NewColorableStdout return new instance of Writer which handle escape sequence for stdout.
|
||||
func NewColorableStdout() io.Writer {
|
||||
return os.Stdout
|
||||
}
|
||||
|
||||
// NewColorableStderr return new instance of Writer which handle escape sequence for stderr.
|
||||
func NewColorableStderr() io.Writer {
|
||||
return os.Stderr
|
||||
}
|
||||
30
vendor/github.com/mattn/go-colorable/colorable_others.go
generated
vendored
Normal file
30
vendor/github.com/mattn/go-colorable/colorable_others.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// +build !windows
|
||||
// +build !appengine
|
||||
|
||||
package colorable
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
_ "github.com/mattn/go-isatty"
|
||||
)
|
||||
|
||||
// NewColorable return new instance of Writer which handle escape sequence.
|
||||
func NewColorable(file *os.File) io.Writer {
|
||||
if file == nil {
|
||||
panic("nil passed instead of *os.File to NewColorable()")
|
||||
}
|
||||
|
||||
return file
|
||||
}
|
||||
|
||||
// NewColorableStdout return new instance of Writer which handle escape sequence for stdout.
|
||||
func NewColorableStdout() io.Writer {
|
||||
return os.Stdout
|
||||
}
|
||||
|
||||
// NewColorableStderr return new instance of Writer which handle escape sequence for stderr.
|
||||
func NewColorableStderr() io.Writer {
|
||||
return os.Stderr
|
||||
}
|
||||
884
vendor/github.com/mattn/go-colorable/colorable_windows.go
generated
vendored
Normal file
884
vendor/github.com/mattn/go-colorable/colorable_windows.go
generated
vendored
Normal file
@@ -0,0 +1,884 @@
|
||||
// +build windows
|
||||
// +build !appengine
|
||||
|
||||
package colorable
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/mattn/go-isatty"
|
||||
)
|
||||
|
||||
const (
|
||||
foregroundBlue = 0x1
|
||||
foregroundGreen = 0x2
|
||||
foregroundRed = 0x4
|
||||
foregroundIntensity = 0x8
|
||||
foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity)
|
||||
backgroundBlue = 0x10
|
||||
backgroundGreen = 0x20
|
||||
backgroundRed = 0x40
|
||||
backgroundIntensity = 0x80
|
||||
backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity)
|
||||
)
|
||||
|
||||
type wchar uint16
|
||||
type short int16
|
||||
type dword uint32
|
||||
type word uint16
|
||||
|
||||
type coord struct {
|
||||
x short
|
||||
y short
|
||||
}
|
||||
|
||||
type smallRect struct {
|
||||
left short
|
||||
top short
|
||||
right short
|
||||
bottom short
|
||||
}
|
||||
|
||||
type consoleScreenBufferInfo struct {
|
||||
size coord
|
||||
cursorPosition coord
|
||||
attributes word
|
||||
window smallRect
|
||||
maximumWindowSize coord
|
||||
}
|
||||
|
||||
type consoleCursorInfo struct {
|
||||
size dword
|
||||
visible int32
|
||||
}
|
||||
|
||||
var (
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
|
||||
procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
|
||||
procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
|
||||
procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
|
||||
procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute")
|
||||
procGetConsoleCursorInfo = kernel32.NewProc("GetConsoleCursorInfo")
|
||||
procSetConsoleCursorInfo = kernel32.NewProc("SetConsoleCursorInfo")
|
||||
procSetConsoleTitle = kernel32.NewProc("SetConsoleTitleW")
|
||||
)
|
||||
|
||||
// Writer provide colorable Writer to the console
|
||||
type Writer struct {
|
||||
out io.Writer
|
||||
handle syscall.Handle
|
||||
oldattr word
|
||||
oldpos coord
|
||||
}
|
||||
|
||||
// NewColorable return new instance of Writer which handle escape sequence from File.
|
||||
func NewColorable(file *os.File) io.Writer {
|
||||
if file == nil {
|
||||
panic("nil passed instead of *os.File to NewColorable()")
|
||||
}
|
||||
|
||||
if isatty.IsTerminal(file.Fd()) {
|
||||
var csbi consoleScreenBufferInfo
|
||||
handle := syscall.Handle(file.Fd())
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
return &Writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}}
|
||||
}
|
||||
return file
|
||||
}
|
||||
|
||||
// NewColorableStdout return new instance of Writer which handle escape sequence for stdout.
|
||||
func NewColorableStdout() io.Writer {
|
||||
return NewColorable(os.Stdout)
|
||||
}
|
||||
|
||||
// NewColorableStderr return new instance of Writer which handle escape sequence for stderr.
|
||||
func NewColorableStderr() io.Writer {
|
||||
return NewColorable(os.Stderr)
|
||||
}
|
||||
|
||||
var color256 = map[int]int{
|
||||
0: 0x000000,
|
||||
1: 0x800000,
|
||||
2: 0x008000,
|
||||
3: 0x808000,
|
||||
4: 0x000080,
|
||||
5: 0x800080,
|
||||
6: 0x008080,
|
||||
7: 0xc0c0c0,
|
||||
8: 0x808080,
|
||||
9: 0xff0000,
|
||||
10: 0x00ff00,
|
||||
11: 0xffff00,
|
||||
12: 0x0000ff,
|
||||
13: 0xff00ff,
|
||||
14: 0x00ffff,
|
||||
15: 0xffffff,
|
||||
16: 0x000000,
|
||||
17: 0x00005f,
|
||||
18: 0x000087,
|
||||
19: 0x0000af,
|
||||
20: 0x0000d7,
|
||||
21: 0x0000ff,
|
||||
22: 0x005f00,
|
||||
23: 0x005f5f,
|
||||
24: 0x005f87,
|
||||
25: 0x005faf,
|
||||
26: 0x005fd7,
|
||||
27: 0x005fff,
|
||||
28: 0x008700,
|
||||
29: 0x00875f,
|
||||
30: 0x008787,
|
||||
31: 0x0087af,
|
||||
32: 0x0087d7,
|
||||
33: 0x0087ff,
|
||||
34: 0x00af00,
|
||||
35: 0x00af5f,
|
||||
36: 0x00af87,
|
||||
37: 0x00afaf,
|
||||
38: 0x00afd7,
|
||||
39: 0x00afff,
|
||||
40: 0x00d700,
|
||||
41: 0x00d75f,
|
||||
42: 0x00d787,
|
||||
43: 0x00d7af,
|
||||
44: 0x00d7d7,
|
||||
45: 0x00d7ff,
|
||||
46: 0x00ff00,
|
||||
47: 0x00ff5f,
|
||||
48: 0x00ff87,
|
||||
49: 0x00ffaf,
|
||||
50: 0x00ffd7,
|
||||
51: 0x00ffff,
|
||||
52: 0x5f0000,
|
||||
53: 0x5f005f,
|
||||
54: 0x5f0087,
|
||||
55: 0x5f00af,
|
||||
56: 0x5f00d7,
|
||||
57: 0x5f00ff,
|
||||
58: 0x5f5f00,
|
||||
59: 0x5f5f5f,
|
||||
60: 0x5f5f87,
|
||||
61: 0x5f5faf,
|
||||
62: 0x5f5fd7,
|
||||
63: 0x5f5fff,
|
||||
64: 0x5f8700,
|
||||
65: 0x5f875f,
|
||||
66: 0x5f8787,
|
||||
67: 0x5f87af,
|
||||
68: 0x5f87d7,
|
||||
69: 0x5f87ff,
|
||||
70: 0x5faf00,
|
||||
71: 0x5faf5f,
|
||||
72: 0x5faf87,
|
||||
73: 0x5fafaf,
|
||||
74: 0x5fafd7,
|
||||
75: 0x5fafff,
|
||||
76: 0x5fd700,
|
||||
77: 0x5fd75f,
|
||||
78: 0x5fd787,
|
||||
79: 0x5fd7af,
|
||||
80: 0x5fd7d7,
|
||||
81: 0x5fd7ff,
|
||||
82: 0x5fff00,
|
||||
83: 0x5fff5f,
|
||||
84: 0x5fff87,
|
||||
85: 0x5fffaf,
|
||||
86: 0x5fffd7,
|
||||
87: 0x5fffff,
|
||||
88: 0x870000,
|
||||
89: 0x87005f,
|
||||
90: 0x870087,
|
||||
91: 0x8700af,
|
||||
92: 0x8700d7,
|
||||
93: 0x8700ff,
|
||||
94: 0x875f00,
|
||||
95: 0x875f5f,
|
||||
96: 0x875f87,
|
||||
97: 0x875faf,
|
||||
98: 0x875fd7,
|
||||
99: 0x875fff,
|
||||
100: 0x878700,
|
||||
101: 0x87875f,
|
||||
102: 0x878787,
|
||||
103: 0x8787af,
|
||||
104: 0x8787d7,
|
||||
105: 0x8787ff,
|
||||
106: 0x87af00,
|
||||
107: 0x87af5f,
|
||||
108: 0x87af87,
|
||||
109: 0x87afaf,
|
||||
110: 0x87afd7,
|
||||
111: 0x87afff,
|
||||
112: 0x87d700,
|
||||
113: 0x87d75f,
|
||||
114: 0x87d787,
|
||||
115: 0x87d7af,
|
||||
116: 0x87d7d7,
|
||||
117: 0x87d7ff,
|
||||
118: 0x87ff00,
|
||||
119: 0x87ff5f,
|
||||
120: 0x87ff87,
|
||||
121: 0x87ffaf,
|
||||
122: 0x87ffd7,
|
||||
123: 0x87ffff,
|
||||
124: 0xaf0000,
|
||||
125: 0xaf005f,
|
||||
126: 0xaf0087,
|
||||
127: 0xaf00af,
|
||||
128: 0xaf00d7,
|
||||
129: 0xaf00ff,
|
||||
130: 0xaf5f00,
|
||||
131: 0xaf5f5f,
|
||||
132: 0xaf5f87,
|
||||
133: 0xaf5faf,
|
||||
134: 0xaf5fd7,
|
||||
135: 0xaf5fff,
|
||||
136: 0xaf8700,
|
||||
137: 0xaf875f,
|
||||
138: 0xaf8787,
|
||||
139: 0xaf87af,
|
||||
140: 0xaf87d7,
|
||||
141: 0xaf87ff,
|
||||
142: 0xafaf00,
|
||||
143: 0xafaf5f,
|
||||
144: 0xafaf87,
|
||||
145: 0xafafaf,
|
||||
146: 0xafafd7,
|
||||
147: 0xafafff,
|
||||
148: 0xafd700,
|
||||
149: 0xafd75f,
|
||||
150: 0xafd787,
|
||||
151: 0xafd7af,
|
||||
152: 0xafd7d7,
|
||||
153: 0xafd7ff,
|
||||
154: 0xafff00,
|
||||
155: 0xafff5f,
|
||||
156: 0xafff87,
|
||||
157: 0xafffaf,
|
||||
158: 0xafffd7,
|
||||
159: 0xafffff,
|
||||
160: 0xd70000,
|
||||
161: 0xd7005f,
|
||||
162: 0xd70087,
|
||||
163: 0xd700af,
|
||||
164: 0xd700d7,
|
||||
165: 0xd700ff,
|
||||
166: 0xd75f00,
|
||||
167: 0xd75f5f,
|
||||
168: 0xd75f87,
|
||||
169: 0xd75faf,
|
||||
170: 0xd75fd7,
|
||||
171: 0xd75fff,
|
||||
172: 0xd78700,
|
||||
173: 0xd7875f,
|
||||
174: 0xd78787,
|
||||
175: 0xd787af,
|
||||
176: 0xd787d7,
|
||||
177: 0xd787ff,
|
||||
178: 0xd7af00,
|
||||
179: 0xd7af5f,
|
||||
180: 0xd7af87,
|
||||
181: 0xd7afaf,
|
||||
182: 0xd7afd7,
|
||||
183: 0xd7afff,
|
||||
184: 0xd7d700,
|
||||
185: 0xd7d75f,
|
||||
186: 0xd7d787,
|
||||
187: 0xd7d7af,
|
||||
188: 0xd7d7d7,
|
||||
189: 0xd7d7ff,
|
||||
190: 0xd7ff00,
|
||||
191: 0xd7ff5f,
|
||||
192: 0xd7ff87,
|
||||
193: 0xd7ffaf,
|
||||
194: 0xd7ffd7,
|
||||
195: 0xd7ffff,
|
||||
196: 0xff0000,
|
||||
197: 0xff005f,
|
||||
198: 0xff0087,
|
||||
199: 0xff00af,
|
||||
200: 0xff00d7,
|
||||
201: 0xff00ff,
|
||||
202: 0xff5f00,
|
||||
203: 0xff5f5f,
|
||||
204: 0xff5f87,
|
||||
205: 0xff5faf,
|
||||
206: 0xff5fd7,
|
||||
207: 0xff5fff,
|
||||
208: 0xff8700,
|
||||
209: 0xff875f,
|
||||
210: 0xff8787,
|
||||
211: 0xff87af,
|
||||
212: 0xff87d7,
|
||||
213: 0xff87ff,
|
||||
214: 0xffaf00,
|
||||
215: 0xffaf5f,
|
||||
216: 0xffaf87,
|
||||
217: 0xffafaf,
|
||||
218: 0xffafd7,
|
||||
219: 0xffafff,
|
||||
220: 0xffd700,
|
||||
221: 0xffd75f,
|
||||
222: 0xffd787,
|
||||
223: 0xffd7af,
|
||||
224: 0xffd7d7,
|
||||
225: 0xffd7ff,
|
||||
226: 0xffff00,
|
||||
227: 0xffff5f,
|
||||
228: 0xffff87,
|
||||
229: 0xffffaf,
|
||||
230: 0xffffd7,
|
||||
231: 0xffffff,
|
||||
232: 0x080808,
|
||||
233: 0x121212,
|
||||
234: 0x1c1c1c,
|
||||
235: 0x262626,
|
||||
236: 0x303030,
|
||||
237: 0x3a3a3a,
|
||||
238: 0x444444,
|
||||
239: 0x4e4e4e,
|
||||
240: 0x585858,
|
||||
241: 0x626262,
|
||||
242: 0x6c6c6c,
|
||||
243: 0x767676,
|
||||
244: 0x808080,
|
||||
245: 0x8a8a8a,
|
||||
246: 0x949494,
|
||||
247: 0x9e9e9e,
|
||||
248: 0xa8a8a8,
|
||||
249: 0xb2b2b2,
|
||||
250: 0xbcbcbc,
|
||||
251: 0xc6c6c6,
|
||||
252: 0xd0d0d0,
|
||||
253: 0xdadada,
|
||||
254: 0xe4e4e4,
|
||||
255: 0xeeeeee,
|
||||
}
|
||||
|
||||
// `\033]0;TITLESTR\007`
|
||||
func doTitleSequence(er *bytes.Reader) error {
|
||||
var c byte
|
||||
var err error
|
||||
|
||||
c, err = er.ReadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if c != '0' && c != '2' {
|
||||
return nil
|
||||
}
|
||||
c, err = er.ReadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if c != ';' {
|
||||
return nil
|
||||
}
|
||||
title := make([]byte, 0, 80)
|
||||
for {
|
||||
c, err = er.ReadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if c == 0x07 || c == '\n' {
|
||||
break
|
||||
}
|
||||
title = append(title, c)
|
||||
}
|
||||
if len(title) > 0 {
|
||||
title8, err := syscall.UTF16PtrFromString(string(title))
|
||||
if err == nil {
|
||||
procSetConsoleTitle.Call(uintptr(unsafe.Pointer(title8)))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write write data on console
|
||||
func (w *Writer) Write(data []byte) (n int, err error) {
|
||||
var csbi consoleScreenBufferInfo
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
|
||||
er := bytes.NewReader(data)
|
||||
var bw [1]byte
|
||||
loop:
|
||||
for {
|
||||
c1, err := er.ReadByte()
|
||||
if err != nil {
|
||||
break loop
|
||||
}
|
||||
if c1 != 0x1b {
|
||||
bw[0] = c1
|
||||
w.out.Write(bw[:])
|
||||
continue
|
||||
}
|
||||
c2, err := er.ReadByte()
|
||||
if err != nil {
|
||||
break loop
|
||||
}
|
||||
|
||||
if c2 == ']' {
|
||||
if err := doTitleSequence(er); err != nil {
|
||||
break loop
|
||||
}
|
||||
continue
|
||||
}
|
||||
if c2 != 0x5b {
|
||||
continue
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
var m byte
|
||||
for {
|
||||
c, err := er.ReadByte()
|
||||
if err != nil {
|
||||
break loop
|
||||
}
|
||||
if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
|
||||
m = c
|
||||
break
|
||||
}
|
||||
buf.Write([]byte(string(c)))
|
||||
}
|
||||
|
||||
switch m {
|
||||
case 'A':
|
||||
n, err = strconv.Atoi(buf.String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
csbi.cursorPosition.y -= short(n)
|
||||
procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
||||
case 'B':
|
||||
n, err = strconv.Atoi(buf.String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
csbi.cursorPosition.y += short(n)
|
||||
procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
||||
case 'C':
|
||||
n, err = strconv.Atoi(buf.String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
csbi.cursorPosition.x += short(n)
|
||||
procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
||||
case 'D':
|
||||
n, err = strconv.Atoi(buf.String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
csbi.cursorPosition.x -= short(n)
|
||||
procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
||||
case 'E':
|
||||
n, err = strconv.Atoi(buf.String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
csbi.cursorPosition.x = 0
|
||||
csbi.cursorPosition.y += short(n)
|
||||
procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
||||
case 'F':
|
||||
n, err = strconv.Atoi(buf.String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
csbi.cursorPosition.x = 0
|
||||
csbi.cursorPosition.y -= short(n)
|
||||
procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
||||
case 'G':
|
||||
n, err = strconv.Atoi(buf.String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
csbi.cursorPosition.x = short(n - 1)
|
||||
procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
||||
case 'H', 'f':
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
if buf.Len() > 0 {
|
||||
token := strings.Split(buf.String(), ";")
|
||||
switch len(token) {
|
||||
case 1:
|
||||
n1, err := strconv.Atoi(token[0])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
csbi.cursorPosition.y = short(n1 - 1)
|
||||
case 2:
|
||||
n1, err := strconv.Atoi(token[0])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
n2, err := strconv.Atoi(token[1])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
csbi.cursorPosition.x = short(n2 - 1)
|
||||
csbi.cursorPosition.y = short(n1 - 1)
|
||||
}
|
||||
} else {
|
||||
csbi.cursorPosition.y = 0
|
||||
}
|
||||
procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
||||
case 'J':
|
||||
n := 0
|
||||
if buf.Len() > 0 {
|
||||
n, err = strconv.Atoi(buf.String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
var count, written dword
|
||||
var cursor coord
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
switch n {
|
||||
case 0:
|
||||
cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}
|
||||
count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x)
|
||||
case 1:
|
||||
cursor = coord{x: csbi.window.left, y: csbi.window.top}
|
||||
count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.window.top-csbi.cursorPosition.y)*csbi.size.x)
|
||||
case 2:
|
||||
cursor = coord{x: csbi.window.left, y: csbi.window.top}
|
||||
count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x)
|
||||
}
|
||||
procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
|
||||
procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
|
||||
case 'K':
|
||||
n := 0
|
||||
if buf.Len() > 0 {
|
||||
n, err = strconv.Atoi(buf.String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
var cursor coord
|
||||
var count, written dword
|
||||
switch n {
|
||||
case 0:
|
||||
cursor = coord{x: csbi.cursorPosition.x + 1, y: csbi.cursorPosition.y}
|
||||
count = dword(csbi.size.x - csbi.cursorPosition.x - 1)
|
||||
case 1:
|
||||
cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y}
|
||||
count = dword(csbi.size.x - csbi.cursorPosition.x)
|
||||
case 2:
|
||||
cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y}
|
||||
count = dword(csbi.size.x)
|
||||
}
|
||||
procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
|
||||
procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
|
||||
case 'm':
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
attr := csbi.attributes
|
||||
cs := buf.String()
|
||||
if cs == "" {
|
||||
procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr))
|
||||
continue
|
||||
}
|
||||
token := strings.Split(cs, ";")
|
||||
for i := 0; i < len(token); i++ {
|
||||
ns := token[i]
|
||||
if n, err = strconv.Atoi(ns); err == nil {
|
||||
switch {
|
||||
case n == 0 || n == 100:
|
||||
attr = w.oldattr
|
||||
case 1 <= n && n <= 5:
|
||||
attr |= foregroundIntensity
|
||||
case n == 7:
|
||||
attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)
|
||||
case n == 22 || n == 25:
|
||||
attr |= foregroundIntensity
|
||||
case n == 27:
|
||||
attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)
|
||||
case 30 <= n && n <= 37:
|
||||
attr &= backgroundMask
|
||||
if (n-30)&1 != 0 {
|
||||
attr |= foregroundRed
|
||||
}
|
||||
if (n-30)&2 != 0 {
|
||||
attr |= foregroundGreen
|
||||
}
|
||||
if (n-30)&4 != 0 {
|
||||
attr |= foregroundBlue
|
||||
}
|
||||
case n == 38: // set foreground color.
|
||||
if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") {
|
||||
if n256, err := strconv.Atoi(token[i+2]); err == nil {
|
||||
if n256foreAttr == nil {
|
||||
n256setup()
|
||||
}
|
||||
attr &= backgroundMask
|
||||
attr |= n256foreAttr[n256]
|
||||
i += 2
|
||||
}
|
||||
} else {
|
||||
attr = attr & (w.oldattr & backgroundMask)
|
||||
}
|
||||
case n == 39: // reset foreground color.
|
||||
attr &= backgroundMask
|
||||
attr |= w.oldattr & foregroundMask
|
||||
case 40 <= n && n <= 47:
|
||||
attr &= foregroundMask
|
||||
if (n-40)&1 != 0 {
|
||||
attr |= backgroundRed
|
||||
}
|
||||
if (n-40)&2 != 0 {
|
||||
attr |= backgroundGreen
|
||||
}
|
||||
if (n-40)&4 != 0 {
|
||||
attr |= backgroundBlue
|
||||
}
|
||||
case n == 48: // set background color.
|
||||
if i < len(token)-2 && token[i+1] == "5" {
|
||||
if n256, err := strconv.Atoi(token[i+2]); err == nil {
|
||||
if n256backAttr == nil {
|
||||
n256setup()
|
||||
}
|
||||
attr &= foregroundMask
|
||||
attr |= n256backAttr[n256]
|
||||
i += 2
|
||||
}
|
||||
} else {
|
||||
attr = attr & (w.oldattr & foregroundMask)
|
||||
}
|
||||
case n == 49: // reset foreground color.
|
||||
attr &= foregroundMask
|
||||
attr |= w.oldattr & backgroundMask
|
||||
case 90 <= n && n <= 97:
|
||||
attr = (attr & backgroundMask)
|
||||
attr |= foregroundIntensity
|
||||
if (n-90)&1 != 0 {
|
||||
attr |= foregroundRed
|
||||
}
|
||||
if (n-90)&2 != 0 {
|
||||
attr |= foregroundGreen
|
||||
}
|
||||
if (n-90)&4 != 0 {
|
||||
attr |= foregroundBlue
|
||||
}
|
||||
case 100 <= n && n <= 107:
|
||||
attr = (attr & foregroundMask)
|
||||
attr |= backgroundIntensity
|
||||
if (n-100)&1 != 0 {
|
||||
attr |= backgroundRed
|
||||
}
|
||||
if (n-100)&2 != 0 {
|
||||
attr |= backgroundGreen
|
||||
}
|
||||
if (n-100)&4 != 0 {
|
||||
attr |= backgroundBlue
|
||||
}
|
||||
}
|
||||
procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr))
|
||||
}
|
||||
}
|
||||
case 'h':
|
||||
var ci consoleCursorInfo
|
||||
cs := buf.String()
|
||||
if cs == "5>" {
|
||||
procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
|
||||
ci.visible = 0
|
||||
procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
|
||||
} else if cs == "?25" {
|
||||
procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
|
||||
ci.visible = 1
|
||||
procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
|
||||
}
|
||||
case 'l':
|
||||
var ci consoleCursorInfo
|
||||
cs := buf.String()
|
||||
if cs == "5>" {
|
||||
procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
|
||||
ci.visible = 1
|
||||
procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
|
||||
} else if cs == "?25" {
|
||||
procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
|
||||
ci.visible = 0
|
||||
procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
|
||||
}
|
||||
case 's':
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
w.oldpos = csbi.cursorPosition
|
||||
case 'u':
|
||||
procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&w.oldpos)))
|
||||
}
|
||||
}
|
||||
|
||||
return len(data), nil
|
||||
}
|
||||
|
||||
type consoleColor struct {
|
||||
rgb int
|
||||
red bool
|
||||
green bool
|
||||
blue bool
|
||||
intensity bool
|
||||
}
|
||||
|
||||
func (c consoleColor) foregroundAttr() (attr word) {
|
||||
if c.red {
|
||||
attr |= foregroundRed
|
||||
}
|
||||
if c.green {
|
||||
attr |= foregroundGreen
|
||||
}
|
||||
if c.blue {
|
||||
attr |= foregroundBlue
|
||||
}
|
||||
if c.intensity {
|
||||
attr |= foregroundIntensity
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c consoleColor) backgroundAttr() (attr word) {
|
||||
if c.red {
|
||||
attr |= backgroundRed
|
||||
}
|
||||
if c.green {
|
||||
attr |= backgroundGreen
|
||||
}
|
||||
if c.blue {
|
||||
attr |= backgroundBlue
|
||||
}
|
||||
if c.intensity {
|
||||
attr |= backgroundIntensity
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var color16 = []consoleColor{
|
||||
{0x000000, false, false, false, false},
|
||||
{0x000080, false, false, true, false},
|
||||
{0x008000, false, true, false, false},
|
||||
{0x008080, false, true, true, false},
|
||||
{0x800000, true, false, false, false},
|
||||
{0x800080, true, false, true, false},
|
||||
{0x808000, true, true, false, false},
|
||||
{0xc0c0c0, true, true, true, false},
|
||||
{0x808080, false, false, false, true},
|
||||
{0x0000ff, false, false, true, true},
|
||||
{0x00ff00, false, true, false, true},
|
||||
{0x00ffff, false, true, true, true},
|
||||
{0xff0000, true, false, false, true},
|
||||
{0xff00ff, true, false, true, true},
|
||||
{0xffff00, true, true, false, true},
|
||||
{0xffffff, true, true, true, true},
|
||||
}
|
||||
|
||||
type hsv struct {
|
||||
h, s, v float32
|
||||
}
|
||||
|
||||
func (a hsv) dist(b hsv) float32 {
|
||||
dh := a.h - b.h
|
||||
switch {
|
||||
case dh > 0.5:
|
||||
dh = 1 - dh
|
||||
case dh < -0.5:
|
||||
dh = -1 - dh
|
||||
}
|
||||
ds := a.s - b.s
|
||||
dv := a.v - b.v
|
||||
return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv)))
|
||||
}
|
||||
|
||||
func toHSV(rgb int) hsv {
|
||||
r, g, b := float32((rgb&0xFF0000)>>16)/256.0,
|
||||
float32((rgb&0x00FF00)>>8)/256.0,
|
||||
float32(rgb&0x0000FF)/256.0
|
||||
min, max := minmax3f(r, g, b)
|
||||
h := max - min
|
||||
if h > 0 {
|
||||
if max == r {
|
||||
h = (g - b) / h
|
||||
if h < 0 {
|
||||
h += 6
|
||||
}
|
||||
} else if max == g {
|
||||
h = 2 + (b-r)/h
|
||||
} else {
|
||||
h = 4 + (r-g)/h
|
||||
}
|
||||
}
|
||||
h /= 6.0
|
||||
s := max - min
|
||||
if max != 0 {
|
||||
s /= max
|
||||
}
|
||||
v := max
|
||||
return hsv{h: h, s: s, v: v}
|
||||
}
|
||||
|
||||
type hsvTable []hsv
|
||||
|
||||
func toHSVTable(rgbTable []consoleColor) hsvTable {
|
||||
t := make(hsvTable, len(rgbTable))
|
||||
for i, c := range rgbTable {
|
||||
t[i] = toHSV(c.rgb)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func (t hsvTable) find(rgb int) consoleColor {
|
||||
hsv := toHSV(rgb)
|
||||
n := 7
|
||||
l := float32(5.0)
|
||||
for i, p := range t {
|
||||
d := hsv.dist(p)
|
||||
if d < l {
|
||||
l, n = d, i
|
||||
}
|
||||
}
|
||||
return color16[n]
|
||||
}
|
||||
|
||||
func minmax3f(a, b, c float32) (min, max float32) {
|
||||
if a < b {
|
||||
if b < c {
|
||||
return a, c
|
||||
} else if a < c {
|
||||
return a, b
|
||||
} else {
|
||||
return c, b
|
||||
}
|
||||
} else {
|
||||
if a < c {
|
||||
return b, c
|
||||
} else if b < c {
|
||||
return b, a
|
||||
} else {
|
||||
return c, a
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var n256foreAttr []word
|
||||
var n256backAttr []word
|
||||
|
||||
func n256setup() {
|
||||
n256foreAttr = make([]word, 256)
|
||||
n256backAttr = make([]word, 256)
|
||||
t := toHSVTable(color16)
|
||||
for i, rgb := range color256 {
|
||||
c := t.find(rgb)
|
||||
n256foreAttr[i] = c.foregroundAttr()
|
||||
n256backAttr[i] = c.backgroundAttr()
|
||||
}
|
||||
}
|
||||
55
vendor/github.com/mattn/go-colorable/noncolorable.go
generated
vendored
Normal file
55
vendor/github.com/mattn/go-colorable/noncolorable.go
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
package colorable
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
)
|
||||
|
||||
// NonColorable hold writer but remove escape sequence.
|
||||
type NonColorable struct {
|
||||
out io.Writer
|
||||
}
|
||||
|
||||
// NewNonColorable return new instance of Writer which remove escape sequence from Writer.
|
||||
func NewNonColorable(w io.Writer) io.Writer {
|
||||
return &NonColorable{out: w}
|
||||
}
|
||||
|
||||
// Write write data on console
|
||||
func (w *NonColorable) Write(data []byte) (n int, err error) {
|
||||
er := bytes.NewReader(data)
|
||||
var bw [1]byte
|
||||
loop:
|
||||
for {
|
||||
c1, err := er.ReadByte()
|
||||
if err != nil {
|
||||
break loop
|
||||
}
|
||||
if c1 != 0x1b {
|
||||
bw[0] = c1
|
||||
w.out.Write(bw[:])
|
||||
continue
|
||||
}
|
||||
c2, err := er.ReadByte()
|
||||
if err != nil {
|
||||
break loop
|
||||
}
|
||||
if c2 != 0x5b {
|
||||
continue
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
for {
|
||||
c, err := er.ReadByte()
|
||||
if err != nil {
|
||||
break loop
|
||||
}
|
||||
if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
|
||||
break
|
||||
}
|
||||
buf.Write([]byte(string(c)))
|
||||
}
|
||||
}
|
||||
|
||||
return len(data), nil
|
||||
}
|
||||
9
vendor/github.com/mattn/go-isatty/.travis.yml
generated
vendored
Normal file
9
vendor/github.com/mattn/go-isatty/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
language: go
|
||||
go:
|
||||
- tip
|
||||
|
||||
before_install:
|
||||
- go get github.com/mattn/goveralls
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
script:
|
||||
- $HOME/gopath/bin/goveralls -repotoken 3gHdORO5k5ziZcWMBxnd9LrMZaJs8m9x5
|
||||
9
vendor/github.com/mattn/go-isatty/LICENSE
generated
vendored
Normal file
9
vendor/github.com/mattn/go-isatty/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
Copyright (c) Yasuhiro MATSUMOTO <mattn.jp@gmail.com>
|
||||
|
||||
MIT License (Expat)
|
||||
|
||||
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.
|
||||
50
vendor/github.com/mattn/go-isatty/README.md
generated
vendored
Normal file
50
vendor/github.com/mattn/go-isatty/README.md
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
# go-isatty
|
||||
|
||||
[](http://godoc.org/github.com/mattn/go-isatty)
|
||||
[](https://travis-ci.org/mattn/go-isatty)
|
||||
[](https://coveralls.io/github/mattn/go-isatty?branch=master)
|
||||
[](https://goreportcard.com/report/mattn/go-isatty)
|
||||
|
||||
isatty for golang
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mattn/go-isatty"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
||||
fmt.Println("Is Terminal")
|
||||
} else if isatty.IsCygwinTerminal(os.Stdout.Fd()) {
|
||||
fmt.Println("Is Cygwin/MSYS2 Terminal")
|
||||
} else {
|
||||
fmt.Println("Is Not Terminal")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ go get github.com/mattn/go-isatty
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
## Author
|
||||
|
||||
Yasuhiro Matsumoto (a.k.a mattn)
|
||||
|
||||
## Thanks
|
||||
|
||||
* k-takata: base idea for IsCygwinTerminal
|
||||
|
||||
https://github.com/k-takata/go-iscygpty
|
||||
2
vendor/github.com/mattn/go-isatty/doc.go
generated
vendored
Normal file
2
vendor/github.com/mattn/go-isatty/doc.go
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
// Package isatty implements interface to isatty
|
||||
package isatty
|
||||
15
vendor/github.com/mattn/go-isatty/isatty_appengine.go
generated
vendored
Normal file
15
vendor/github.com/mattn/go-isatty/isatty_appengine.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// +build appengine
|
||||
|
||||
package isatty
|
||||
|
||||
// IsTerminal returns true if the file descriptor is terminal which
|
||||
// is always false on on appengine classic which is a sandboxed PaaS.
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
|
||||
// terminal. This is also always false on this environment.
|
||||
func IsCygwinTerminal(fd uintptr) bool {
|
||||
return false
|
||||
}
|
||||
18
vendor/github.com/mattn/go-isatty/isatty_bsd.go
generated
vendored
Normal file
18
vendor/github.com/mattn/go-isatty/isatty_bsd.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// +build darwin freebsd openbsd netbsd dragonfly
|
||||
// +build !appengine
|
||||
|
||||
package isatty
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const ioctlReadTermios = syscall.TIOCGETA
|
||||
|
||||
// IsTerminal return true if the file descriptor is terminal.
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
var termios syscall.Termios
|
||||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
|
||||
return err == 0
|
||||
}
|
||||
18
vendor/github.com/mattn/go-isatty/isatty_linux.go
generated
vendored
Normal file
18
vendor/github.com/mattn/go-isatty/isatty_linux.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// +build linux
|
||||
// +build !appengine,!ppc64,!ppc64le
|
||||
|
||||
package isatty
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const ioctlReadTermios = syscall.TCGETS
|
||||
|
||||
// IsTerminal return true if the file descriptor is terminal.
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
var termios syscall.Termios
|
||||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
|
||||
return err == 0
|
||||
}
|
||||
19
vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go
generated
vendored
Normal file
19
vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// +build linux
|
||||
// +build ppc64 ppc64le
|
||||
|
||||
package isatty
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
syscall "golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const ioctlReadTermios = syscall.TCGETS
|
||||
|
||||
// IsTerminal return true if the file descriptor is terminal.
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
var termios syscall.Termios
|
||||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
|
||||
return err == 0
|
||||
}
|
||||
10
vendor/github.com/mattn/go-isatty/isatty_others.go
generated
vendored
Normal file
10
vendor/github.com/mattn/go-isatty/isatty_others.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// +build !windows
|
||||
// +build !appengine
|
||||
|
||||
package isatty
|
||||
|
||||
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
|
||||
// terminal. This is also always false on this environment.
|
||||
func IsCygwinTerminal(fd uintptr) bool {
|
||||
return false
|
||||
}
|
||||
16
vendor/github.com/mattn/go-isatty/isatty_solaris.go
generated
vendored
Normal file
16
vendor/github.com/mattn/go-isatty/isatty_solaris.go
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// +build solaris
|
||||
// +build !appengine
|
||||
|
||||
package isatty
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||
// see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
var termio unix.Termio
|
||||
err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio)
|
||||
return err == nil
|
||||
}
|
||||
94
vendor/github.com/mattn/go-isatty/isatty_windows.go
generated
vendored
Normal file
94
vendor/github.com/mattn/go-isatty/isatty_windows.go
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
// +build windows
|
||||
// +build !appengine
|
||||
|
||||
package isatty
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
fileNameInfo uintptr = 2
|
||||
fileTypePipe = 3
|
||||
)
|
||||
|
||||
var (
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
||||
procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx")
|
||||
procGetFileType = kernel32.NewProc("GetFileType")
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Check if GetFileInformationByHandleEx is available.
|
||||
if procGetFileInformationByHandleEx.Find() != nil {
|
||||
procGetFileInformationByHandleEx = nil
|
||||
}
|
||||
}
|
||||
|
||||
// IsTerminal return true if the file descriptor is terminal.
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
var st uint32
|
||||
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)
|
||||
return r != 0 && e == 0
|
||||
}
|
||||
|
||||
// Check pipe name is used for cygwin/msys2 pty.
|
||||
// Cygwin/MSYS2 PTY has a name like:
|
||||
// \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master
|
||||
func isCygwinPipeName(name string) bool {
|
||||
token := strings.Split(name, "-")
|
||||
if len(token) < 5 {
|
||||
return false
|
||||
}
|
||||
|
||||
if token[0] != `\msys` && token[0] != `\cygwin` {
|
||||
return false
|
||||
}
|
||||
|
||||
if token[1] == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(token[2], "pty") {
|
||||
return false
|
||||
}
|
||||
|
||||
if token[3] != `from` && token[3] != `to` {
|
||||
return false
|
||||
}
|
||||
|
||||
if token[4] != "master" {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
|
||||
// terminal.
|
||||
func IsCygwinTerminal(fd uintptr) bool {
|
||||
if procGetFileInformationByHandleEx == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// Cygwin/msys's pty is a pipe.
|
||||
ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0)
|
||||
if ft != fileTypePipe || e != 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
var buf [2 + syscall.MAX_PATH]uint16
|
||||
r, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(),
|
||||
4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)),
|
||||
uintptr(len(buf)*2), 0, 0)
|
||||
if r == 0 || e != 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
l := *(*uint32)(unsafe.Pointer(&buf))
|
||||
return isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2])))
|
||||
}
|
||||
8
vendor/github.com/mattn/go-runewidth/.travis.yml
generated
vendored
Normal file
8
vendor/github.com/mattn/go-runewidth/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
language: go
|
||||
go:
|
||||
- tip
|
||||
before_install:
|
||||
- go get github.com/mattn/goveralls
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
script:
|
||||
- $HOME/gopath/bin/goveralls -repotoken lAKAWPzcGsD3A8yBX3BGGtRUdJ6CaGERL
|
||||
21
vendor/github.com/mattn/go-runewidth/LICENSE
generated
vendored
Normal file
21
vendor/github.com/mattn/go-runewidth/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Yasuhiro Matsumoto
|
||||
|
||||
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.
|
||||
27
vendor/github.com/mattn/go-runewidth/README.mkd
generated
vendored
Normal file
27
vendor/github.com/mattn/go-runewidth/README.mkd
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
go-runewidth
|
||||
============
|
||||
|
||||
[](https://travis-ci.org/mattn/go-runewidth)
|
||||
[](https://coveralls.io/r/mattn/go-runewidth?branch=HEAD)
|
||||
[](http://godoc.org/github.com/mattn/go-runewidth)
|
||||
[](https://goreportcard.com/report/github.com/mattn/go-runewidth)
|
||||
|
||||
Provides functions to get fixed width of the character or string.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
```go
|
||||
runewidth.StringWidth("つのだ☆HIRO") == 12
|
||||
```
|
||||
|
||||
|
||||
Author
|
||||
------
|
||||
|
||||
Yasuhiro Matsumoto
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
under the MIT License: http://mattn.mit-license.org/2013
|
||||
1235
vendor/github.com/mattn/go-runewidth/runewidth.go
generated
vendored
Normal file
1235
vendor/github.com/mattn/go-runewidth/runewidth.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8
vendor/github.com/mattn/go-runewidth/runewidth_js.go
generated
vendored
Normal file
8
vendor/github.com/mattn/go-runewidth/runewidth_js.go
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
// +build js
|
||||
|
||||
package runewidth
|
||||
|
||||
func IsEastAsian() bool {
|
||||
// TODO: Implement this for the web. Detect east asian in a compatible way, and return true.
|
||||
return false
|
||||
}
|
||||
77
vendor/github.com/mattn/go-runewidth/runewidth_posix.go
generated
vendored
Normal file
77
vendor/github.com/mattn/go-runewidth/runewidth_posix.go
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
// +build !windows,!js
|
||||
|
||||
package runewidth
|
||||
|
||||
import (
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`)
|
||||
|
||||
var mblenTable = map[string]int{
|
||||
"utf-8": 6,
|
||||
"utf8": 6,
|
||||
"jis": 8,
|
||||
"eucjp": 3,
|
||||
"euckr": 2,
|
||||
"euccn": 2,
|
||||
"sjis": 2,
|
||||
"cp932": 2,
|
||||
"cp51932": 2,
|
||||
"cp936": 2,
|
||||
"cp949": 2,
|
||||
"cp950": 2,
|
||||
"big5": 2,
|
||||
"gbk": 2,
|
||||
"gb2312": 2,
|
||||
}
|
||||
|
||||
func isEastAsian(locale string) bool {
|
||||
charset := strings.ToLower(locale)
|
||||
r := reLoc.FindStringSubmatch(locale)
|
||||
if len(r) == 2 {
|
||||
charset = strings.ToLower(r[1])
|
||||
}
|
||||
|
||||
if strings.HasSuffix(charset, "@cjk_narrow") {
|
||||
return false
|
||||
}
|
||||
|
||||
for pos, b := range []byte(charset) {
|
||||
if b == '@' {
|
||||
charset = charset[:pos]
|
||||
break
|
||||
}
|
||||
}
|
||||
max := 1
|
||||
if m, ok := mblenTable[charset]; ok {
|
||||
max = m
|
||||
}
|
||||
if max > 1 && (charset[0] != 'u' ||
|
||||
strings.HasPrefix(locale, "ja") ||
|
||||
strings.HasPrefix(locale, "ko") ||
|
||||
strings.HasPrefix(locale, "zh")) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsEastAsian return true if the current locale is CJK
|
||||
func IsEastAsian() bool {
|
||||
locale := os.Getenv("LC_CTYPE")
|
||||
if locale == "" {
|
||||
locale = os.Getenv("LANG")
|
||||
}
|
||||
|
||||
// ignore C locale
|
||||
if locale == "POSIX" || locale == "C" {
|
||||
return false
|
||||
}
|
||||
if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') {
|
||||
return false
|
||||
}
|
||||
|
||||
return isEastAsian(locale)
|
||||
}
|
||||
25
vendor/github.com/mattn/go-runewidth/runewidth_windows.go
generated
vendored
Normal file
25
vendor/github.com/mattn/go-runewidth/runewidth_windows.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
package runewidth
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var (
|
||||
kernel32 = syscall.NewLazyDLL("kernel32")
|
||||
procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP")
|
||||
)
|
||||
|
||||
// IsEastAsian return true if the current locale is CJK
|
||||
func IsEastAsian() bool {
|
||||
r1, _, _ := procGetConsoleOutputCP.Call()
|
||||
if r1 == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
switch int(r1) {
|
||||
case 932, 51932, 936, 949, 950:
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
4
vendor/github.com/mattn/go-tty/.travis.yml
generated
vendored
Normal file
4
vendor/github.com/mattn/go-tty/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
language: go
|
||||
sudo: false
|
||||
go:
|
||||
- tip
|
||||
49
vendor/github.com/mattn/go-tty/README.md
generated
vendored
Normal file
49
vendor/github.com/mattn/go-tty/README.md
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
# go-tty
|
||||
|
||||
Simple tty utility
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
tty, err := tty.Open()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer tty.Close()
|
||||
|
||||
for {
|
||||
r, err := tty.ReadRune()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// handle key event
|
||||
}
|
||||
```
|
||||
|
||||
if you are on windows and want to display ANSI colors, use <a href="https://github.com/mattn/go-colorable">go-colorable</a>.
|
||||
|
||||
```go
|
||||
tty, err := tty.Open()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer tty.Close()
|
||||
|
||||
out := colorable.NewColorable(tty.Output())
|
||||
|
||||
fmt.Fprintln(out, "\x1b[2J")
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ go get github.com/mattn/go-tty
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
## Author
|
||||
|
||||
Yasuhiro Matsumoto (a.k.a mattn)
|
||||
120
vendor/github.com/mattn/go-tty/tty.go
generated
vendored
Normal file
120
vendor/github.com/mattn/go-tty/tty.go
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
package tty
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
func Open() (*TTY, error) {
|
||||
return open()
|
||||
}
|
||||
|
||||
func (tty *TTY) Raw() (func() error, error) {
|
||||
return tty.raw()
|
||||
}
|
||||
|
||||
func (tty *TTY) MustRaw() func() error {
|
||||
f, err := tty.raw()
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func (tty *TTY) Buffered() bool {
|
||||
return tty.buffered()
|
||||
}
|
||||
|
||||
func (tty *TTY) ReadRune() (rune, error) {
|
||||
return tty.readRune()
|
||||
}
|
||||
|
||||
func (tty *TTY) Close() error {
|
||||
return tty.close()
|
||||
}
|
||||
|
||||
func (tty *TTY) Size() (int, int, error) {
|
||||
return tty.size()
|
||||
}
|
||||
|
||||
func (tty *TTY) Input() *os.File {
|
||||
return tty.input()
|
||||
}
|
||||
|
||||
func (tty *TTY) Output() *os.File {
|
||||
return tty.output()
|
||||
}
|
||||
|
||||
// Display types.
|
||||
const (
|
||||
displayNone = iota
|
||||
displayRune
|
||||
displayMask
|
||||
)
|
||||
|
||||
func (tty *TTY) readString(displayType int) (string, error) {
|
||||
rs := []rune{}
|
||||
loop:
|
||||
for {
|
||||
r, err := tty.readRune()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
switch r {
|
||||
case 13:
|
||||
break loop
|
||||
case 8, 127:
|
||||
if len(rs) > 0 {
|
||||
rs = rs[:len(rs)-1]
|
||||
if displayType != displayNone {
|
||||
tty.Output().WriteString("\b \b")
|
||||
}
|
||||
}
|
||||
default:
|
||||
if unicode.IsPrint(r) {
|
||||
rs = append(rs, r)
|
||||
switch displayType {
|
||||
case displayRune:
|
||||
tty.Output().WriteString(string(r))
|
||||
case displayMask:
|
||||
tty.Output().WriteString("*")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return string(rs), nil
|
||||
}
|
||||
|
||||
func (tty *TTY) ReadString() (string, error) {
|
||||
defer tty.Output().WriteString("\n")
|
||||
return tty.readString(displayRune)
|
||||
}
|
||||
|
||||
func (tty *TTY) ReadPassword() (string, error) {
|
||||
defer tty.Output().WriteString("\n")
|
||||
return tty.readString(displayMask)
|
||||
}
|
||||
|
||||
func (tty *TTY) ReadPasswordNoEcho() (string, error) {
|
||||
defer tty.Output().WriteString("\n")
|
||||
return tty.readString(displayNone)
|
||||
}
|
||||
|
||||
func (tty *TTY) ReadPasswordClear() (string, error) {
|
||||
s, err := tty.readString(displayMask)
|
||||
tty.Output().WriteString(
|
||||
strings.Repeat("\b", len(s)) +
|
||||
strings.Repeat(" ", len(s)) +
|
||||
strings.Repeat("\b", len(s)))
|
||||
return s, err
|
||||
}
|
||||
|
||||
type WINSIZE struct {
|
||||
W int
|
||||
H int
|
||||
}
|
||||
|
||||
func (tty *TTY) SIGWINCH() chan WINSIZE {
|
||||
return tty.sigwinch()
|
||||
}
|
||||
12
vendor/github.com/mattn/go-tty/tty_bsd.go
generated
vendored
Normal file
12
vendor/github.com/mattn/go-tty/tty_bsd.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// +build darwin dragonfly freebsd netbsd openbsd
|
||||
|
||||
package tty
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const (
|
||||
ioctlReadTermios = syscall.TIOCGETA
|
||||
ioctlWriteTermios = syscall.TIOCSETA
|
||||
)
|
||||
8
vendor/github.com/mattn/go-tty/tty_linux.go
generated
vendored
Normal file
8
vendor/github.com/mattn/go-tty/tty_linux.go
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
// +build linux
|
||||
|
||||
package tty
|
||||
|
||||
const (
|
||||
ioctlReadTermios = 0x5401 // syscall.TCGETS
|
||||
ioctlWriteTermios = 0x5402 // syscall.TCSETS
|
||||
)
|
||||
63
vendor/github.com/mattn/go-tty/tty_plan9.go
generated
vendored
Normal file
63
vendor/github.com/mattn/go-tty/tty_plan9.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
package tty
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type TTY struct {
|
||||
in *os.File
|
||||
bin *bufio.Reader
|
||||
out *os.File
|
||||
}
|
||||
|
||||
func open() (*TTY, error) {
|
||||
tty := new(TTY)
|
||||
|
||||
in, err := os.Open("/dev/cons")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tty.in = in
|
||||
tty.bin = bufio.NewReader(in)
|
||||
|
||||
out, err := os.OpenFile("/dev/cons", syscall.O_WRONLY, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tty.out = out
|
||||
|
||||
return tty, nil
|
||||
}
|
||||
|
||||
func (tty *TTY) buffered() bool {
|
||||
return tty.bin.Buffered() > 0
|
||||
}
|
||||
|
||||
func (tty *TTY) readRune() (rune, error) {
|
||||
r, _, err := tty.bin.ReadRune()
|
||||
return r, err
|
||||
}
|
||||
|
||||
func (tty *TTY) close() (err error) {
|
||||
if err2 := tty.in.Close(); err2 != nil {
|
||||
err = err2
|
||||
}
|
||||
if err2 := tty.out.Close(); err2 != nil {
|
||||
err = err2
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (tty *TTY) size() (int, int, error) {
|
||||
return 80, 24, nil
|
||||
}
|
||||
|
||||
func (tty *TTY) input() *os.File {
|
||||
return tty.in
|
||||
}
|
||||
|
||||
func (tty *TTY) output() *os.File {
|
||||
return tty.out
|
||||
}
|
||||
130
vendor/github.com/mattn/go-tty/tty_unix.go
generated
vendored
Normal file
130
vendor/github.com/mattn/go-tty/tty_unix.go
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
// +build !windows
|
||||
// +build !plan9
|
||||
|
||||
package tty
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
type TTY struct {
|
||||
in *os.File
|
||||
bin *bufio.Reader
|
||||
out *os.File
|
||||
termios syscall.Termios
|
||||
ws chan WINSIZE
|
||||
ss chan os.Signal
|
||||
}
|
||||
|
||||
func open() (*TTY, error) {
|
||||
tty := new(TTY)
|
||||
|
||||
in, err := os.Open("/dev/tty")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tty.in = in
|
||||
tty.bin = bufio.NewReader(in)
|
||||
|
||||
out, err := os.OpenFile("/dev/tty", syscall.O_WRONLY, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tty.out = out
|
||||
|
||||
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(tty.in.Fd()), ioctlReadTermios, uintptr(unsafe.Pointer(&tty.termios)), 0, 0, 0); err != 0 {
|
||||
return nil, err
|
||||
}
|
||||
newios := tty.termios
|
||||
newios.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXON | syscall.IXOFF
|
||||
newios.Lflag &^= syscall.ECHO | syscall.ICANON /*| syscall.ISIG*/
|
||||
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(tty.in.Fd()), ioctlWriteTermios, uintptr(unsafe.Pointer(&newios)), 0, 0, 0); err != 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tty.ws = make(chan WINSIZE)
|
||||
tty.ss = make(chan os.Signal, 1)
|
||||
signal.Notify(tty.ss, syscall.SIGWINCH)
|
||||
go func() {
|
||||
for sig := range tty.ss {
|
||||
switch sig {
|
||||
case syscall.SIGWINCH:
|
||||
if w, h, err := tty.size(); err == nil {
|
||||
tty.ws <- WINSIZE{
|
||||
W: w,
|
||||
H: h,
|
||||
}
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
}()
|
||||
return tty, nil
|
||||
}
|
||||
|
||||
func (tty *TTY) buffered() bool {
|
||||
return tty.bin.Buffered() > 0
|
||||
}
|
||||
|
||||
func (tty *TTY) readRune() (rune, error) {
|
||||
r, _, err := tty.bin.ReadRune()
|
||||
return r, err
|
||||
}
|
||||
|
||||
func (tty *TTY) close() error {
|
||||
close(tty.ss)
|
||||
close(tty.ws)
|
||||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(tty.in.Fd()), ioctlWriteTermios, uintptr(unsafe.Pointer(&tty.termios)), 0, 0, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
func (tty *TTY) size() (int, int, error) {
|
||||
var dim [4]uint16
|
||||
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(tty.out.Fd()), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dim)), 0, 0, 0); err != 0 {
|
||||
return -1, -1, err
|
||||
}
|
||||
return int(dim[1]), int(dim[0]), nil
|
||||
}
|
||||
|
||||
func (tty *TTY) input() *os.File {
|
||||
return tty.in
|
||||
}
|
||||
|
||||
func (tty *TTY) output() *os.File {
|
||||
return tty.out
|
||||
}
|
||||
|
||||
func (tty *TTY) raw() (func() error, error) {
|
||||
termios, err := unix.IoctlGetTermios(int(tty.in.Fd()), ioctlReadTermios)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
|
||||
termios.Oflag &^= unix.OPOST
|
||||
termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
|
||||
termios.Cflag &^= unix.CSIZE | unix.PARENB
|
||||
termios.Cflag |= unix.CS8
|
||||
termios.Cc[unix.VMIN] = 1
|
||||
termios.Cc[unix.VTIME] = 0
|
||||
if err := unix.IoctlSetTermios(int(tty.in.Fd()), ioctlWriteTermios, termios); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return func() error {
|
||||
if err := unix.IoctlSetTermios(int(tty.in.Fd()), ioctlWriteTermios, termios); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (tty *TTY) sigwinch() chan WINSIZE {
|
||||
return tty.ws
|
||||
}
|
||||
323
vendor/github.com/mattn/go-tty/tty_windows.go
generated
vendored
Normal file
323
vendor/github.com/mattn/go-tty/tty_windows.go
generated
vendored
Normal file
@@ -0,0 +1,323 @@
|
||||
// +build windows
|
||||
|
||||
package tty
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/mattn/go-isatty"
|
||||
)
|
||||
|
||||
const (
|
||||
rightAltPressed = 1
|
||||
leftAltPressed = 2
|
||||
rightCtrlPressed = 4
|
||||
leftCtrlPressed = 8
|
||||
shiftPressed = 0x0010
|
||||
ctrlPressed = rightCtrlPressed | leftCtrlPressed
|
||||
altPressed = rightAltPressed | leftAltPressed
|
||||
)
|
||||
|
||||
const (
|
||||
enableProcessedInput = 0x1
|
||||
enableLineInput = 0x2
|
||||
enableEchoInput = 0x4
|
||||
enableWindowInput = 0x8
|
||||
enableMouseInput = 0x10
|
||||
enableInsertMode = 0x20
|
||||
enableQuickEditMode = 0x40
|
||||
enableExtendedFlag = 0x80
|
||||
|
||||
enableProcessedOutput = 1
|
||||
enableWrapAtEolOutput = 2
|
||||
|
||||
keyEvent = 0x1
|
||||
mouseEvent = 0x2
|
||||
windowBufferSizeEvent = 0x4
|
||||
)
|
||||
|
||||
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
|
||||
var (
|
||||
procAllocConsole = kernel32.NewProc("AllocConsole")
|
||||
procSetStdHandle = kernel32.NewProc("SetStdHandle")
|
||||
procGetStdHandle = kernel32.NewProc("GetStdHandle")
|
||||
procSetConsoleScreenBufferSize = kernel32.NewProc("SetConsoleScreenBufferSize")
|
||||
procCreateConsoleScreenBuffer = kernel32.NewProc("CreateConsoleScreenBuffer")
|
||||
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
|
||||
procWriteConsoleOutputCharacter = kernel32.NewProc("WriteConsoleOutputCharacterW")
|
||||
procWriteConsoleOutputAttribute = kernel32.NewProc("WriteConsoleOutputAttribute")
|
||||
procGetConsoleCursorInfo = kernel32.NewProc("GetConsoleCursorInfo")
|
||||
procSetConsoleCursorInfo = kernel32.NewProc("SetConsoleCursorInfo")
|
||||
procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
|
||||
procReadConsoleInput = kernel32.NewProc("ReadConsoleInputW")
|
||||
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
||||
procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
|
||||
procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
|
||||
procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute")
|
||||
procScrollConsoleScreenBuffer = kernel32.NewProc("ScrollConsoleScreenBufferW")
|
||||
)
|
||||
|
||||
type wchar uint16
|
||||
type short int16
|
||||
type dword uint32
|
||||
type word uint16
|
||||
|
||||
type coord struct {
|
||||
x short
|
||||
y short
|
||||
}
|
||||
|
||||
type smallRect struct {
|
||||
left short
|
||||
top short
|
||||
right short
|
||||
bottom short
|
||||
}
|
||||
|
||||
type consoleScreenBufferInfo struct {
|
||||
size coord
|
||||
cursorPosition coord
|
||||
attributes word
|
||||
window smallRect
|
||||
maximumWindowSize coord
|
||||
}
|
||||
|
||||
type consoleCursorInfo struct {
|
||||
size dword
|
||||
visible int32
|
||||
}
|
||||
|
||||
type inputRecord struct {
|
||||
eventType word
|
||||
_ [2]byte
|
||||
event [16]byte
|
||||
}
|
||||
|
||||
type keyEventRecord struct {
|
||||
keyDown int32
|
||||
repeatCount word
|
||||
virtualKeyCode word
|
||||
virtualScanCode word
|
||||
unicodeChar wchar
|
||||
controlKeyState dword
|
||||
}
|
||||
|
||||
type windowBufferSizeRecord struct {
|
||||
size coord
|
||||
}
|
||||
|
||||
type mouseEventRecord struct {
|
||||
mousePos coord
|
||||
buttonState dword
|
||||
controlKeyState dword
|
||||
eventFlags dword
|
||||
}
|
||||
|
||||
type charInfo struct {
|
||||
unicodeChar wchar
|
||||
attributes word
|
||||
}
|
||||
|
||||
type TTY struct {
|
||||
in *os.File
|
||||
out *os.File
|
||||
st uint32
|
||||
rs []rune
|
||||
ws chan WINSIZE
|
||||
}
|
||||
|
||||
func readConsoleInput(fd uintptr, record *inputRecord) (err error) {
|
||||
var w uint32
|
||||
r1, _, err := procReadConsoleInput.Call(fd, uintptr(unsafe.Pointer(record)), 1, uintptr(unsafe.Pointer(&w)))
|
||||
if r1 == 0 {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func open() (*TTY, error) {
|
||||
tty := new(TTY)
|
||||
if false && isatty.IsTerminal(os.Stdin.Fd()) {
|
||||
tty.in = os.Stdin
|
||||
} else {
|
||||
conin, err := os.Open("CONIN$")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tty.in = conin
|
||||
}
|
||||
|
||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
||||
tty.out = os.Stdout
|
||||
} else {
|
||||
procAllocConsole.Call()
|
||||
out, err := syscall.Open("CONOUT$", syscall.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tty.out = os.NewFile(uintptr(out), "/dev/tty")
|
||||
}
|
||||
|
||||
h := tty.in.Fd()
|
||||
var st uint32
|
||||
r1, _, err := procGetConsoleMode.Call(h, uintptr(unsafe.Pointer(&st)))
|
||||
if r1 == 0 {
|
||||
return nil, err
|
||||
}
|
||||
tty.st = st
|
||||
|
||||
st &^= enableEchoInput
|
||||
st &^= enableInsertMode
|
||||
st &^= enableLineInput
|
||||
st &^= enableMouseInput
|
||||
st &^= enableWindowInput
|
||||
st &^= enableExtendedFlag
|
||||
st &^= enableQuickEditMode
|
||||
st |= enableProcessedInput
|
||||
|
||||
// ignore error
|
||||
procSetConsoleMode.Call(h, uintptr(st))
|
||||
|
||||
tty.ws = make(chan WINSIZE)
|
||||
|
||||
return tty, nil
|
||||
}
|
||||
|
||||
func (tty *TTY) buffered() bool {
|
||||
return len(tty.rs) > 0
|
||||
}
|
||||
|
||||
func (tty *TTY) readRune() (rune, error) {
|
||||
if len(tty.rs) > 0 {
|
||||
r := tty.rs[0]
|
||||
tty.rs = tty.rs[1:]
|
||||
return r, nil
|
||||
}
|
||||
var ir inputRecord
|
||||
err := readConsoleInput(tty.in.Fd(), &ir)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
switch ir.eventType {
|
||||
case windowBufferSizeEvent:
|
||||
wr := (*windowBufferSizeRecord)(unsafe.Pointer(&ir.event))
|
||||
tty.ws <- WINSIZE{
|
||||
W: int(wr.size.x),
|
||||
H: int(wr.size.y),
|
||||
}
|
||||
case keyEvent:
|
||||
kr := (*keyEventRecord)(unsafe.Pointer(&ir.event))
|
||||
if kr.keyDown != 0 {
|
||||
if kr.controlKeyState&altPressed != 0 && kr.unicodeChar > 0 {
|
||||
tty.rs = []rune{rune(kr.unicodeChar)}
|
||||
return rune(0x1b), nil
|
||||
}
|
||||
if kr.unicodeChar > 0 {
|
||||
if kr.controlKeyState&shiftPressed != 0 {
|
||||
switch kr.unicodeChar {
|
||||
case 0x09:
|
||||
tty.rs = []rune{0x5b, 0x5a}
|
||||
return rune(0x1b), nil
|
||||
}
|
||||
}
|
||||
return rune(kr.unicodeChar), nil
|
||||
}
|
||||
vk := kr.virtualKeyCode
|
||||
switch vk {
|
||||
case 0x21: // page-up
|
||||
tty.rs = []rune{0x5b, 0x35, 0x7e}
|
||||
return rune(0x1b), nil
|
||||
case 0x22: // page-down
|
||||
tty.rs = []rune{0x5b, 0x36, 0x7e}
|
||||
return rune(0x1b), nil
|
||||
case 0x23: // end
|
||||
tty.rs = []rune{0x5b, 0x46}
|
||||
return rune(0x1b), nil
|
||||
case 0x24: // home
|
||||
tty.rs = []rune{0x5b, 0x48}
|
||||
return rune(0x1b), nil
|
||||
case 0x25: // left
|
||||
tty.rs = []rune{0x5b, 0x44}
|
||||
return rune(0x1b), nil
|
||||
case 0x26: // up
|
||||
tty.rs = []rune{0x5b, 0x41}
|
||||
return rune(0x1b), nil
|
||||
case 0x27: // right
|
||||
tty.rs = []rune{0x5b, 0x43}
|
||||
return rune(0x1b), nil
|
||||
case 0x28: // down
|
||||
tty.rs = []rune{0x5b, 0x42}
|
||||
return rune(0x1b), nil
|
||||
case 0x2e: // delete
|
||||
tty.rs = []rune{0x5b, 0x33, 0x7e}
|
||||
return rune(0x1b), nil
|
||||
case 0x70, 0x71, 0x72, 0x73: // F1,F2,F3,F4
|
||||
tty.rs = []rune{0x5b, 0x4f, rune(vk) - 0x20}
|
||||
return rune(0x1b), nil
|
||||
case 0x074, 0x75, 0x76, 0x77: // F5,F6,F7,F8
|
||||
tty.rs = []rune{0x5b, 0x31, rune(vk) - 0x3f, 0x7e}
|
||||
return rune(0x1b), nil
|
||||
case 0x78, 0x79: // F9,F10
|
||||
tty.rs = []rune{0x5b, 0x32, rune(vk) - 0x48, 0x7e}
|
||||
return rune(0x1b), nil
|
||||
case 0x7a, 0x7b: // F11,F12
|
||||
tty.rs = []rune{0x5b, 0x32, rune(vk) - 0x47, 0x7e}
|
||||
return rune(0x1b), nil
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (tty *TTY) close() error {
|
||||
close(tty.ws)
|
||||
procSetConsoleMode.Call(tty.in.Fd(), uintptr(tty.st))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tty *TTY) size() (int, int, error) {
|
||||
var csbi consoleScreenBufferInfo
|
||||
r1, _, err := procGetConsoleScreenBufferInfo.Call(tty.out.Fd(), uintptr(unsafe.Pointer(&csbi)))
|
||||
if r1 == 0 {
|
||||
return 0, 0, err
|
||||
}
|
||||
return int(csbi.window.right - csbi.window.left + 1), int(csbi.window.bottom - csbi.window.top + 1), nil
|
||||
}
|
||||
|
||||
func (tty *TTY) input() *os.File {
|
||||
return tty.in
|
||||
}
|
||||
|
||||
func (tty *TTY) output() *os.File {
|
||||
return tty.out
|
||||
}
|
||||
|
||||
func (tty *TTY) raw() (func() error, error) {
|
||||
var st uint32
|
||||
r1, _, err := procGetConsoleMode.Call(tty.in.Fd(), uintptr(unsafe.Pointer(&st)))
|
||||
if r1 == 0 {
|
||||
return nil, err
|
||||
}
|
||||
mode := st &^ (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput)
|
||||
r1, _, err = procSetConsoleMode.Call(tty.in.Fd(), uintptr(mode))
|
||||
if r1 == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return func() error {
|
||||
r1, _, err := procSetConsoleMode.Call(tty.in.Fd(), uintptr(st))
|
||||
if r1 == 0 {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (tty *TTY) sigwinch() chan WINSIZE {
|
||||
return tty.ws
|
||||
}
|
||||
1
vendor/github.com/mgutz/ansi/.gitignore
generated
vendored
Normal file
1
vendor/github.com/mgutz/ansi/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.test
|
||||
9
vendor/github.com/mgutz/ansi/LICENSE
generated
vendored
Normal file
9
vendor/github.com/mgutz/ansi/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2013 Mario L. Gutierrez
|
||||
|
||||
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.
|
||||
|
||||
121
vendor/github.com/mgutz/ansi/README.md
generated
vendored
Normal file
121
vendor/github.com/mgutz/ansi/README.md
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
# ansi
|
||||
|
||||
Package ansi is a small, fast library to create ANSI colored strings and codes.
|
||||
|
||||
## Install
|
||||
|
||||
Get it
|
||||
|
||||
```sh
|
||||
go get -u github.com/mgutz/ansi
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```go
|
||||
import "github.com/mgutz/ansi"
|
||||
|
||||
// colorize a string, SLOW
|
||||
msg := ansi.Color("foo", "red+b:white")
|
||||
|
||||
// create a FAST closure function to avoid computation of ANSI code
|
||||
phosphorize := ansi.ColorFunc("green+h:black")
|
||||
msg = phosphorize("Bring back the 80s!")
|
||||
msg2 := phospohorize("Look, I'm a CRT!")
|
||||
|
||||
// cache escape codes and build strings manually
|
||||
lime := ansi.ColorCode("green+h:black")
|
||||
reset := ansi.ColorCode("reset")
|
||||
|
||||
fmt.Println(lime, "Bring back the 80s!", reset)
|
||||
```
|
||||
|
||||
Other examples
|
||||
|
||||
```go
|
||||
Color(s, "red") // red
|
||||
Color(s, "red+b") // red bold
|
||||
Color(s, "red+B") // red blinking
|
||||
Color(s, "red+u") // red underline
|
||||
Color(s, "red+bh") // red bold bright
|
||||
Color(s, "red:white") // red on white
|
||||
Color(s, "red+b:white+h") // red bold on white bright
|
||||
Color(s, "red+B:white+h") // red blink on white bright
|
||||
Color(s, "off") // turn off ansi codes
|
||||
```
|
||||
|
||||
To view color combinations, from project directory in terminal.
|
||||
|
||||
```sh
|
||||
go test
|
||||
```
|
||||
|
||||
## Style format
|
||||
|
||||
```go
|
||||
"foregroundColor+attributes:backgroundColor+attributes"
|
||||
```
|
||||
|
||||
Colors
|
||||
|
||||
* black
|
||||
* red
|
||||
* green
|
||||
* yellow
|
||||
* blue
|
||||
* magenta
|
||||
* cyan
|
||||
* white
|
||||
* 0...255 (256 colors)
|
||||
|
||||
Foreground Attributes
|
||||
|
||||
* B = Blink
|
||||
* b = bold
|
||||
* h = high intensity (bright)
|
||||
* i = inverse
|
||||
* s = strikethrough
|
||||
* u = underline
|
||||
|
||||
Background Attributes
|
||||
|
||||
* h = high intensity (bright)
|
||||
|
||||
## Constants
|
||||
|
||||
* ansi.Reset
|
||||
* ansi.DefaultBG
|
||||
* ansi.DefaultFG
|
||||
* ansi.Black
|
||||
* ansi.Red
|
||||
* ansi.Green
|
||||
* ansi.Yellow
|
||||
* ansi.Blue
|
||||
* ansi.Magenta
|
||||
* ansi.Cyan
|
||||
* ansi.White
|
||||
* ansi.LightBlack
|
||||
* ansi.LightRed
|
||||
* ansi.LightGreen
|
||||
* ansi.LightYellow
|
||||
* ansi.LightBlue
|
||||
* ansi.LightMagenta
|
||||
* ansi.LightCyan
|
||||
* ansi.LightWhite
|
||||
|
||||
## References
|
||||
|
||||
Wikipedia ANSI escape codes [Colors](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors)
|
||||
|
||||
General [tips and formatting](http://misc.flogisoft.com/bash/tip_colors_and_formatting)
|
||||
|
||||
What about support on Windows? Use [colorable by mattn](https://github.com/mattn/go-colorable).
|
||||
Ansi and colorable are used by [logxi](https://github.com/mgutz/logxi) to support logging in
|
||||
color on Windows.
|
||||
|
||||
## MIT License
|
||||
|
||||
Copyright (c) 2013 Mario Gutierrez mario@mgutz.com
|
||||
|
||||
See the file LICENSE for copying permission.
|
||||
|
||||
285
vendor/github.com/mgutz/ansi/ansi.go
generated
vendored
Normal file
285
vendor/github.com/mgutz/ansi/ansi.go
generated
vendored
Normal file
@@ -0,0 +1,285 @@
|
||||
package ansi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
black = iota
|
||||
red
|
||||
green
|
||||
yellow
|
||||
blue
|
||||
magenta
|
||||
cyan
|
||||
white
|
||||
defaultt = 9
|
||||
|
||||
normalIntensityFG = 30
|
||||
highIntensityFG = 90
|
||||
normalIntensityBG = 40
|
||||
highIntensityBG = 100
|
||||
|
||||
start = "\033["
|
||||
bold = "1;"
|
||||
blink = "5;"
|
||||
underline = "4;"
|
||||
inverse = "7;"
|
||||
strikethrough = "9;"
|
||||
|
||||
// Reset is the ANSI reset escape sequence
|
||||
Reset = "\033[0m"
|
||||
// DefaultBG is the default background
|
||||
DefaultBG = "\033[49m"
|
||||
// DefaultFG is the default foreground
|
||||
DefaultFG = "\033[39m"
|
||||
)
|
||||
|
||||
// Black FG
|
||||
var Black string
|
||||
|
||||
// Red FG
|
||||
var Red string
|
||||
|
||||
// Green FG
|
||||
var Green string
|
||||
|
||||
// Yellow FG
|
||||
var Yellow string
|
||||
|
||||
// Blue FG
|
||||
var Blue string
|
||||
|
||||
// Magenta FG
|
||||
var Magenta string
|
||||
|
||||
// Cyan FG
|
||||
var Cyan string
|
||||
|
||||
// White FG
|
||||
var White string
|
||||
|
||||
// LightBlack FG
|
||||
var LightBlack string
|
||||
|
||||
// LightRed FG
|
||||
var LightRed string
|
||||
|
||||
// LightGreen FG
|
||||
var LightGreen string
|
||||
|
||||
// LightYellow FG
|
||||
var LightYellow string
|
||||
|
||||
// LightBlue FG
|
||||
var LightBlue string
|
||||
|
||||
// LightMagenta FG
|
||||
var LightMagenta string
|
||||
|
||||
// LightCyan FG
|
||||
var LightCyan string
|
||||
|
||||
// LightWhite FG
|
||||
var LightWhite string
|
||||
|
||||
var (
|
||||
plain = false
|
||||
// Colors maps common color names to their ANSI color code.
|
||||
Colors = map[string]int{
|
||||
"black": black,
|
||||
"red": red,
|
||||
"green": green,
|
||||
"yellow": yellow,
|
||||
"blue": blue,
|
||||
"magenta": magenta,
|
||||
"cyan": cyan,
|
||||
"white": white,
|
||||
"default": defaultt,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
for i := 0; i < 256; i++ {
|
||||
Colors[strconv.Itoa(i)] = i
|
||||
}
|
||||
|
||||
Black = ColorCode("black")
|
||||
Red = ColorCode("red")
|
||||
Green = ColorCode("green")
|
||||
Yellow = ColorCode("yellow")
|
||||
Blue = ColorCode("blue")
|
||||
Magenta = ColorCode("magenta")
|
||||
Cyan = ColorCode("cyan")
|
||||
White = ColorCode("white")
|
||||
LightBlack = ColorCode("black+h")
|
||||
LightRed = ColorCode("red+h")
|
||||
LightGreen = ColorCode("green+h")
|
||||
LightYellow = ColorCode("yellow+h")
|
||||
LightBlue = ColorCode("blue+h")
|
||||
LightMagenta = ColorCode("magenta+h")
|
||||
LightCyan = ColorCode("cyan+h")
|
||||
LightWhite = ColorCode("white+h")
|
||||
}
|
||||
|
||||
// ColorCode returns the ANSI color color code for style.
|
||||
func ColorCode(style string) string {
|
||||
return colorCode(style).String()
|
||||
}
|
||||
|
||||
// Gets the ANSI color code for a style.
|
||||
func colorCode(style string) *bytes.Buffer {
|
||||
buf := bytes.NewBufferString("")
|
||||
if plain || style == "" {
|
||||
return buf
|
||||
}
|
||||
if style == "reset" {
|
||||
buf.WriteString(Reset)
|
||||
return buf
|
||||
} else if style == "off" {
|
||||
return buf
|
||||
}
|
||||
|
||||
foregroundBackground := strings.Split(style, ":")
|
||||
foreground := strings.Split(foregroundBackground[0], "+")
|
||||
fgKey := foreground[0]
|
||||
fg := Colors[fgKey]
|
||||
fgStyle := ""
|
||||
if len(foreground) > 1 {
|
||||
fgStyle = foreground[1]
|
||||
}
|
||||
|
||||
bg, bgStyle := "", ""
|
||||
|
||||
if len(foregroundBackground) > 1 {
|
||||
background := strings.Split(foregroundBackground[1], "+")
|
||||
bg = background[0]
|
||||
if len(background) > 1 {
|
||||
bgStyle = background[1]
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString(start)
|
||||
base := normalIntensityFG
|
||||
if len(fgStyle) > 0 {
|
||||
if strings.Contains(fgStyle, "b") {
|
||||
buf.WriteString(bold)
|
||||
}
|
||||
if strings.Contains(fgStyle, "B") {
|
||||
buf.WriteString(blink)
|
||||
}
|
||||
if strings.Contains(fgStyle, "u") {
|
||||
buf.WriteString(underline)
|
||||
}
|
||||
if strings.Contains(fgStyle, "i") {
|
||||
buf.WriteString(inverse)
|
||||
}
|
||||
if strings.Contains(fgStyle, "s") {
|
||||
buf.WriteString(strikethrough)
|
||||
}
|
||||
if strings.Contains(fgStyle, "h") {
|
||||
base = highIntensityFG
|
||||
}
|
||||
}
|
||||
|
||||
// if 256-color
|
||||
n, err := strconv.Atoi(fgKey)
|
||||
if err == nil {
|
||||
fmt.Fprintf(buf, "38;5;%d;", n)
|
||||
} else {
|
||||
fmt.Fprintf(buf, "%d;", base+fg)
|
||||
}
|
||||
|
||||
base = normalIntensityBG
|
||||
if len(bg) > 0 {
|
||||
if strings.Contains(bgStyle, "h") {
|
||||
base = highIntensityBG
|
||||
}
|
||||
// if 256-color
|
||||
n, err := strconv.Atoi(bg)
|
||||
if err == nil {
|
||||
fmt.Fprintf(buf, "48;5;%d;", n)
|
||||
} else {
|
||||
fmt.Fprintf(buf, "%d;", base+Colors[bg])
|
||||
}
|
||||
}
|
||||
|
||||
// remove last ";"
|
||||
buf.Truncate(buf.Len() - 1)
|
||||
buf.WriteRune('m')
|
||||
return buf
|
||||
}
|
||||
|
||||
// Color colors a string based on the ANSI color code for style.
|
||||
func Color(s, style string) string {
|
||||
if plain || len(style) < 1 {
|
||||
return s
|
||||
}
|
||||
buf := colorCode(style)
|
||||
buf.WriteString(s)
|
||||
buf.WriteString(Reset)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// ColorFunc creates a closure to avoid computation ANSI color code.
|
||||
func ColorFunc(style string) func(string) string {
|
||||
if style == "" {
|
||||
return func(s string) string {
|
||||
return s
|
||||
}
|
||||
}
|
||||
color := ColorCode(style)
|
||||
return func(s string) string {
|
||||
if plain || s == "" {
|
||||
return s
|
||||
}
|
||||
buf := bytes.NewBufferString(color)
|
||||
buf.WriteString(s)
|
||||
buf.WriteString(Reset)
|
||||
result := buf.String()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// DisableColors disables ANSI color codes. The default is false (colors are on).
|
||||
func DisableColors(disable bool) {
|
||||
plain = disable
|
||||
if plain {
|
||||
Black = ""
|
||||
Red = ""
|
||||
Green = ""
|
||||
Yellow = ""
|
||||
Blue = ""
|
||||
Magenta = ""
|
||||
Cyan = ""
|
||||
White = ""
|
||||
LightBlack = ""
|
||||
LightRed = ""
|
||||
LightGreen = ""
|
||||
LightYellow = ""
|
||||
LightBlue = ""
|
||||
LightMagenta = ""
|
||||
LightCyan = ""
|
||||
LightWhite = ""
|
||||
} else {
|
||||
Black = ColorCode("black")
|
||||
Red = ColorCode("red")
|
||||
Green = ColorCode("green")
|
||||
Yellow = ColorCode("yellow")
|
||||
Blue = ColorCode("blue")
|
||||
Magenta = ColorCode("magenta")
|
||||
Cyan = ColorCode("cyan")
|
||||
White = ColorCode("white")
|
||||
LightBlack = ColorCode("black+h")
|
||||
LightRed = ColorCode("red+h")
|
||||
LightGreen = ColorCode("green+h")
|
||||
LightYellow = ColorCode("yellow+h")
|
||||
LightBlue = ColorCode("blue+h")
|
||||
LightMagenta = ColorCode("magenta+h")
|
||||
LightCyan = ColorCode("cyan+h")
|
||||
LightWhite = ColorCode("white+h")
|
||||
}
|
||||
}
|
||||
65
vendor/github.com/mgutz/ansi/doc.go
generated
vendored
Normal file
65
vendor/github.com/mgutz/ansi/doc.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Package ansi is a small, fast library to create ANSI colored strings and codes.
|
||||
|
||||
Installation
|
||||
|
||||
# this installs the color viewer and the package
|
||||
go get -u github.com/mgutz/ansi/cmd/ansi-mgutz
|
||||
|
||||
Example
|
||||
|
||||
// colorize a string, SLOW
|
||||
msg := ansi.Color("foo", "red+b:white")
|
||||
|
||||
// create a closure to avoid recalculating ANSI code compilation
|
||||
phosphorize := ansi.ColorFunc("green+h:black")
|
||||
msg = phosphorize("Bring back the 80s!")
|
||||
msg2 := phospohorize("Look, I'm a CRT!")
|
||||
|
||||
// cache escape codes and build strings manually
|
||||
lime := ansi.ColorCode("green+h:black")
|
||||
reset := ansi.ColorCode("reset")
|
||||
|
||||
fmt.Println(lime, "Bring back the 80s!", reset)
|
||||
|
||||
Other examples
|
||||
|
||||
Color(s, "red") // red
|
||||
Color(s, "red+b") // red bold
|
||||
Color(s, "red+B") // red blinking
|
||||
Color(s, "red+u") // red underline
|
||||
Color(s, "red+bh") // red bold bright
|
||||
Color(s, "red:white") // red on white
|
||||
Color(s, "red+b:white+h") // red bold on white bright
|
||||
Color(s, "red+B:white+h") // red blink on white bright
|
||||
|
||||
To view color combinations, from terminal
|
||||
|
||||
ansi-mgutz
|
||||
|
||||
Style format
|
||||
|
||||
"foregroundColor+attributes:backgroundColor+attributes"
|
||||
|
||||
Colors
|
||||
|
||||
black
|
||||
red
|
||||
green
|
||||
yellow
|
||||
blue
|
||||
magenta
|
||||
cyan
|
||||
white
|
||||
|
||||
Attributes
|
||||
|
||||
b = bold foreground
|
||||
B = Blink foreground
|
||||
u = underline foreground
|
||||
h = high intensity (bright) foreground, background
|
||||
i = inverse
|
||||
|
||||
Wikipedia ANSI escape codes [Colors](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors)
|
||||
*/
|
||||
package ansi
|
||||
57
vendor/github.com/mgutz/ansi/print.go
generated
vendored
Normal file
57
vendor/github.com/mgutz/ansi/print.go
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
package ansi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
colorable "github.com/mattn/go-colorable"
|
||||
)
|
||||
|
||||
// PrintStyles prints all style combinations to the terminal.
|
||||
func PrintStyles() {
|
||||
// for compatibility with Windows, not needed for *nix
|
||||
stdout := colorable.NewColorableStdout()
|
||||
|
||||
bgColors := []string{
|
||||
"",
|
||||
":black",
|
||||
":red",
|
||||
":green",
|
||||
":yellow",
|
||||
":blue",
|
||||
":magenta",
|
||||
":cyan",
|
||||
":white",
|
||||
}
|
||||
|
||||
keys := make([]string, 0, len(Colors))
|
||||
for k := range Colors {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
sort.Sort(sort.StringSlice(keys))
|
||||
|
||||
for _, fg := range keys {
|
||||
for _, bg := range bgColors {
|
||||
fmt.Fprintln(stdout, padColor(fg, []string{"" + bg, "+b" + bg, "+bh" + bg, "+u" + bg}))
|
||||
fmt.Fprintln(stdout, padColor(fg, []string{"+s" + bg, "+i" + bg}))
|
||||
fmt.Fprintln(stdout, padColor(fg, []string{"+uh" + bg, "+B" + bg, "+Bb" + bg /* backgrounds */, "" + bg + "+h"}))
|
||||
fmt.Fprintln(stdout, padColor(fg, []string{"+b" + bg + "+h", "+bh" + bg + "+h", "+u" + bg + "+h", "+uh" + bg + "+h"}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func pad(s string, length int) string {
|
||||
for len(s) < length {
|
||||
s += " "
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func padColor(color string, styles []string) string {
|
||||
buffer := ""
|
||||
for _, style := range styles {
|
||||
buffer += Color(pad(color+style, 20), color+style)
|
||||
}
|
||||
return buffer
|
||||
}
|
||||
24
vendor/github.com/moul/http2curl/.gitignore
generated
vendored
Normal file
24
vendor/github.com/moul/http2curl/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user