diff --git a/Gopkg.lock b/Gopkg.lock
index 4776167d56..420644b68a 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -87,12 +87,12 @@
version = "v0.5.0"
[[projects]]
- digest = "1:a2486f94bda33b301614ff5cfce102b7eed4c923fa650c2b83dba1fcf2117466"
+ digest = "1:1659cb76cbd08a29826688d006e7a3d9279d6ca8a12155acb7b20164958987d3"
name = "github.com/c-bata/go-prompt"
packages = ["."]
pruneopts = "UT"
- revision = "c52492ff1b386e5c0ba5271b5eaad165fab09eca"
- version = "v0.2.2"
+ revision = "e99fbc797b795e0a7a94affc8d44f6a0350d85f0"
+ version = "v0.2.1"
[[projects]]
digest = "1:40098afbdd06a76dee4b6bcb85a22fed81ac9d2ebaf775c91e558c80f57aaff1"
diff --git a/Gopkg.toml b/Gopkg.toml
index dcb3fa9554..2cf2019028 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -27,7 +27,7 @@
[[constraint]]
name = "github.com/c-bata/go-prompt"
- version = "0.2.2"
+ version = "=0.2.1"
[[constraint]]
branch = "master"
diff --git a/vendor/github.com/c-bata/go-prompt/CHANGELOG.md b/vendor/github.com/c-bata/go-prompt/CHANGELOG.md
index a1fcb273be..ac4b02dc1f 100644
--- a/vendor/github.com/c-bata/go-prompt/CHANGELOG.md
+++ b/vendor/github.com/c-bata/go-prompt/CHANGELOG.md
@@ -1,31 +1,10 @@
# 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.
+* It seems that windows support is almost perfect.
### Fixed
diff --git a/vendor/github.com/c-bata/go-prompt/DEVELOPER_GUIDE.md b/vendor/github.com/c-bata/go-prompt/DEVELOPER_GUIDE.md
new file mode 100644
index 0000000000..44f2c55bd2
--- /dev/null
+++ b/vendor/github.com/c-bata/go-prompt/DEVELOPER_GUIDE.md
@@ -0,0 +1,155 @@
+# Developer Guide
+
+## Getting Started
+
+The most simple example is below.
+
+```go
+package main
+
+import (
+ "fmt"
+
+ "github.com/c-bata/go-prompt"
+)
+
+// executor executes command and print the output.
+func executor(in string) {
+ fmt.Println("Your input: " + in)
+}
+
+// completer returns the completion items from user input.
+func completer(d prompt.Document) []prompt.Suggest {
+ s := []prompt.Suggest{
+ {Text: "users", Description: "user table"},
+ {Text: "sites", Description: "sites table"},
+ {Text: "articles", Description: "articles table"},
+ {Text: "comments", Description: "comments table"},
+ }
+ return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
+}
+
+func main() {
+ p := prompt.New(
+ executor,
+ completer,
+ prompt.OptionPrefix(">>> "),
+ prompt.OptionTitle("sql-prompt"),
+ )
+ p.Run()
+}
+```
+
+If you want to create CLI using go-prompt, I recommend you to look at the [source code of kube-prompt](https://github.com/c-bata/kube-prompt).
+It is the most practical example.
+
+
+## Options
+
+go-prompt has many color options.
+It is difficult to describe by text. So please see below figure:
+
+
+
+* **OptionPrefixTextColor(prompt.Color)** : default `prompt.Blue`
+* **OptionPrefixBackgroundColor(prompt.Color)** : default `prompt.DefaultColor`
+* **OptionInputTextColor(prompt.Color)** : default `prompt.DefaultColor`
+* **OptionInputBGColor(prompt.Color)** : default `prompt.DefaultColor`
+* **OptionPreviewSuggestionTextColor(prompt.Color)** : default `prompt.Green`
+* **OptionPreviewSuggestionBGColor(prompt.Color)** : default `prompt.DefaultColor`
+* **OptionSuggestionTextColor(prompt.Color)** : default `prompt.White`
+* **OptionSuggestionBGColor(prompt.Color)** : default `prompt.Cyan`
+* **OptionSelectedSuggestionTextColor(prompt.Color)** : `default prompt.Black`
+* **OptionSelectedSuggestionBGColor(prompt.Color)** : `default prompt.DefaultColor`
+* **OptionDescriptionTextColor(prompt.Color)** : default `prompt.Black`
+* **OptionDescriptionBGColor(prompt.Color)** : default `prompt.Turquoise`
+* **OptionSelectedDescriptionTextColor(prompt.Color)** : default `prompt.White`
+* **OptionSelectedDescriptionBGColor(prompt.Color)** : default `prompt.Cyan`
+* **OptionScrollbarThumbColor** : `prompt.DarkGray`
+* **OptionScrollbarBGColor** : `prompt.Cyan`
+
+**Other Options**
+
+#### `OptionTitle(string)` : default `""`
+Option to set a title that wll be displayed on the header bar of terminal.
+
+#### `OptionHistory([]string)` : default `[]string{}`
+Option to set history.
+
+#### `OptionPrefix(string)` : default `"> "`
+Option to set prefix string.
+
+#### `OptionLivePrefix(func() (prefix string, useLivePrefix bool))` : default `nil`
+Option to set a callback function for updating prefix string dynamically.
+
+#### `OptionMaxSuggestions(x uint16)` : default `6`
+The max number of displayed suggestions.
+
+#### `OptionParser(prompt.ConsoleParser)` : default `VT100Parser`
+To set a custom ConsoleParser object.
+The argument should implement ConsoleParser interface.
+
+#### `OptionWriter(prompt.ConsoleWriter)` : default `VT100Writer`
+To set a custom ConsoleWriter object.
+The argument should implement ConsoleWriter interface.
+
+#### `SwitchKeyBindMode(prompt.KeyBindMode)` : default `prompt.EmacsKeyBindMode`
+To set a key bind mode.
+
+#### `OptionAddKeyBind(...KeyBind)` : default `[]KeyBind{}`
+To set a custom key bind.
+
+## Architecture of go-prompt
+
+*Caution: This section is WIP.*
+
+This is a short description of go-prompt implementation.
+go-prompt consists of three parts.
+
+1. Input parser
+2. Emulate user input with Buffer object.
+3. Render buffer object.
+
+### Input Parser
+
+
+
+Input Parser only supports vt100-compatible console now.
+
+* Set as the raw mode.
+* Read a standard input.
+* Parse to byte array
+
+### Emulate user input
+
+go-prompt contains Buffer class.
+It represents input state by handling a key input by user.
+
+`Buffer` object has text and cursor position.
+
+**TODO prepare the sample of buffer**
+
+```go
+package main
+
+import "github.com/c-bata/go-prompt"
+
+func main() {
+ b := prompt.NewBuffer()
+ ... wip
+}
+```
+
+### Renderer
+
+`Renderer` object renders a buffer object.
+
+**TODO prepare the sample of brender**
+
+```go
+package main
+```
+
+the output is below:
+
+**TODO prepare a screen shot**
diff --git a/vendor/github.com/c-bata/go-prompt/Gopkg.lock b/vendor/github.com/c-bata/go-prompt/Gopkg.lock
index 1b6866bfcb..0228094527 100644
--- a/vendor/github.com/c-bata/go-prompt/Gopkg.lock
+++ b/vendor/github.com/c-bata/go-prompt/Gopkg.lock
@@ -13,33 +13,27 @@
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"
+ revision = "c1750293025292316a611ae8f632d9791515e51c"
[[projects]]
branch = "master"
name = "github.com/pkg/term"
packages = ["termios"]
- revision = "cda20d4ac917ad418d86e151eff439648b06185b"
+ revision = "b1f72af2d63057363398bec5873d16a98b453312"
[[projects]]
branch = "master"
name = "golang.org/x/sys"
packages = ["unix"]
- revision = "ad87a3a340fa7f3bed189293fbfa7a9b7e021ae1"
+ revision = "37707fdb30a5b38865cfb95e5aab41707daec7fd"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
- inputs-digest = "d6a0ea9e49092cfd8cb3d6077c97a938de7c39195b83828dae2a0befdd207ffd"
+ inputs-digest = "6c442f55617e93df75aa1ee2fd2b36cfab23003fded4723be56c6b6fd0545c56"
solver-name = "gps-cdcl"
solver-version = 1
diff --git a/vendor/github.com/c-bata/go-prompt/Gopkg.toml b/vendor/github.com/c-bata/go-prompt/Gopkg.toml
index 903f53b251..fe31c575ad 100644
--- a/vendor/github.com/c-bata/go-prompt/Gopkg.toml
+++ b/vendor/github.com/c-bata/go-prompt/Gopkg.toml
@@ -32,7 +32,3 @@
[[constraint]]
branch = "master"
name = "github.com/pkg/term"
-
-[[constraint]]
- branch = "master"
- name = "github.com/mattn/go-runewidth"
diff --git a/vendor/github.com/c-bata/go-prompt/Makefile b/vendor/github.com/c-bata/go-prompt/Makefile
index 3cb6edfe63..caf263cabc 100644
--- a/vendor/github.com/c-bata/go-prompt/Makefile
+++ b/vendor/github.com/c-bata/go-prompt/Makefile
@@ -21,11 +21,6 @@ lint: ## Run golint and go vet.
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 .
diff --git a/vendor/github.com/c-bata/go-prompt/README.md b/vendor/github.com/c-bata/go-prompt/README.md
index a949b8b9d8..e66ae425e0 100644
--- a/vendor/github.com/c-bata/go-prompt/README.md
+++ b/vendor/github.com/c-bata/go-prompt/README.md
@@ -1,10 +1,7 @@
# 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.
+Library for building a powerful interactive prompt, inspired by [python-prompt-toolkit](https://github.com/jonathanslenders/python-prompt-toolkit).
+Easy building a multi-platform binary of the command line tools because written in Golang.
```go
package main
@@ -30,15 +27,15 @@ func main() {
}
```
+
#### 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)
+* [kris-nova/kubicorn : Simple. Cloud Native. Kubernetes. Infrastructure.](https://github.com/kris-nova/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.)
+* (If you create a CLI using go-prompt and want your own project to be listed here, Please submit a Github Issue.)
## Features
@@ -50,52 +47,54 @@ func main() {
### 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.
+go-prompt provides many options. All options are listed in [Developer Guide](./DEVELOPER_GUIDE.md).
[](#flexible-options)
### Keyboard Shortcuts
-Emacs-like keyboard shortcuts are available by default (these also are the default shortcuts in Bash shell).
+Emacs-like keyboard shortcut is available by default (it's also default shortcuts in Bash shell).
You can customize and expand these shortcuts.
[](#keyboard-shortcuts)
-Key Binding | Description
----------------------|---------------------------------------------------------
-Ctrl + A | Go to the beginning of the line (Home)
-Ctrl + E | Go to the end of the line (End)
-Ctrl + P | Previous command (Up arrow)
-Ctrl + N | Next command (Down arrow)
-Ctrl + F | Forward one character
-Ctrl + B | Backward one character
-Ctrl + D | Delete character under the cursor
-Ctrl + H | Delete character before the cursor (Backspace)
-Ctrl + W | Cut the word before the cursor to the clipboard
-Ctrl + K | Cut the line after the cursor to the clipboard
-Ctrl + U | Cut the line before the cursor to the clipboard
-Ctrl + L | Clear the screen
+KeyBinding | Description
+--------------------|---------------------------------------------------------
+Ctrl + A | Go to the beginning of the line (Home)
+Ctrl + E | Go to the End of the line (End)
+Ctrl + P | Previous command (Up arrow)
+Ctrl + N | Next command (Down arrow)
+Ctrl + F | Forward one character
+Ctrl + B | Backward one character
+Ctrl + D | Delete character under the cursor
+Ctrl + H | Delete character before the cursor (Backspace)
+Ctrl + W | Cut the Word before the cursor to the clipboard.
+Ctrl + K | Cut the Line after the cursor to the clipboard.
+Ctrl + U | Cut/delete the Line before the cursor to the clipboard.
+Ctrl + L | Clear the screen
### History
-You can use Up arrow and Down arrow to walk through the history of commands executed.
+You can use up-arrow and down-arrow to walk through the history of commands executed.
[](#history)
+
### Multiple platform support
-We have confirmed go-prompt works fine in the following terminals:
+We confirmed following terminals
* iTerm2 (macOS)
* Terminal.app (macOS)
* Command Prompt (Windows)
-* gnome-terminal (Ubuntu)
+* GNU Terminal (Ubuntu)
+
## Links
+* [Developer Guide](./DEVELOPER_GUIDE.md).
* [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)
+* [GoDoc](http://godoc.org/github.com/c-bata/go-prompt).
## Author
@@ -105,6 +104,7 @@ Masashi Shibata
* Github: [@c-bata](https://github.com/c-bata/)
* Facebook: [Masashi Shibata](https://www.facebook.com/masashi.cbata)
-## License
+## LICENSE
+
+This software is licensed under the MIT License (See [LICENSE](./LICENSE) ).
-This software is licensed under the MIT license, see [LICENSE](./LICENSE) for more information.
diff --git a/vendor/github.com/c-bata/go-prompt/bisect.go b/vendor/github.com/c-bata/go-prompt/bisect.go
new file mode 100644
index 0000000000..2bcef3a5be
--- /dev/null
+++ b/vendor/github.com/c-bata/go-prompt/bisect.go
@@ -0,0 +1,27 @@
+package prompt
+
+import "sort"
+
+// BisectLeft to Locate the insertion point for v in a to maintain sorted order.
+func BisectLeft(a []int, v int) int {
+ return bisectLeftRange(a, v, 0, len(a))
+}
+
+func bisectLeftRange(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
+ })
+}
+
+// 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
+ })
+}
diff --git a/vendor/github.com/c-bata/go-prompt/buffer.go b/vendor/github.com/c-bata/go-prompt/buffer.go
index 6c29b461e3..929d2fcecb 100644
--- a/vendor/github.com/c-bata/go-prompt/buffer.go
+++ b/vendor/github.com/c-bata/go-prompt/buffer.go
@@ -9,7 +9,7 @@ import (
type Buffer struct {
workingLines []string // The working lines. Similar to history
workingIndex int
- cursorPosition int
+ CursorPosition int
cacheDocument *Document
preferredColumn int // Remember the original column for the next up/down movement.
}
@@ -23,25 +23,19 @@ func (b *Buffer) Text() string {
func (b *Buffer) Document() (d *Document) {
if b.cacheDocument == nil ||
b.cacheDocument.Text != b.Text() ||
- b.cacheDocument.cursorPosition != b.cursorPosition {
+ b.cacheDocument.CursorPosition != b.CursorPosition {
b.cacheDocument = &Document{
Text: b.Text(),
- cursorPosition: b.cursorPosition,
+ 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
+ oc := b.CursorPosition
if overwrite {
overwritten := string(or[oc : oc+len(v)])
@@ -55,15 +49,15 @@ func (b *Buffer) InsertText(v string, overwrite bool, moveCursor bool) {
}
if moveCursor {
- b.cursorPosition += len([]rune(v))
+ b.CursorPosition += len([]rune(v))
}
}
-// SetText method to set text and update cursorPosition.
+// 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)) {
+ 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]
@@ -78,11 +72,11 @@ func (b *Buffer) setText(v string) {
// Set cursor position. Return whether it changed.
func (b *Buffer) setCursorPosition(p int) {
- o := b.cursorPosition
+ o := b.CursorPosition
if p > 0 {
- b.cursorPosition = p
+ b.CursorPosition = p
} else {
- b.cursorPosition = 0
+ b.CursorPosition = 0
}
if p != o {
// Cursor position is changed.
@@ -92,21 +86,21 @@ func (b *Buffer) setCursorPosition(p int) {
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.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
+ 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
+ b.CursorPosition += l
return
}
@@ -117,7 +111,7 @@ func (b *Buffer) CursorUp(count int) {
if b.preferredColumn == -1 { // -1 means nil
orig = b.Document().CursorPositionCol()
}
- b.cursorPosition += b.Document().GetCursorUpPosition(count, orig)
+ b.CursorPosition += b.Document().GetCursorUpPosition(count, orig)
// Remember the original column for the next up/down movement.
b.preferredColumn = orig
@@ -130,7 +124,7 @@ func (b *Buffer) CursorDown(count int) {
if b.preferredColumn == -1 { // -1 means nil
orig = b.Document().CursorPositionCol()
}
- b.cursorPosition += b.Document().GetCursorDownPosition(count, orig)
+ b.CursorPosition += b.Document().GetCursorDownPosition(count, orig)
// Remember the original column for the next up/down movement.
b.preferredColumn = orig
@@ -143,15 +137,15 @@ func (b *Buffer) DeleteBeforeCursor(count int) (deleted string) {
}
r := []rune(b.Text())
- if b.cursorPosition > 0 {
- start := b.cursorPosition - count
+ if b.CursorPosition > 0 {
+ start := b.CursorPosition - count
if start < 0 {
start = 0
}
- deleted = string(r[start:b.cursorPosition])
+ deleted = string(r[start:b.CursorPosition])
b.setDocument(&Document{
- Text: string(r[:start]) + string(r[b.cursorPosition:]),
- cursorPosition: b.cursorPosition - len([]rune(deleted)),
+ Text: string(r[:start]) + string(r[b.CursorPosition:]),
+ CursorPosition: b.CursorPosition - len([]rune(deleted)),
})
}
return
@@ -169,9 +163,9 @@ func (b *Buffer) NewLine(copyMargin bool) {
// 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) {
+ if b.CursorPosition < len(r) {
deleted = b.Document().TextAfterCursor()[:count]
- b.setText(string(r[:b.cursorPosition]) + string(r[b.cursorPosition+len(deleted):]))
+ b.setText(string(r[:b.CursorPosition]) + string(r[b.CursorPosition+len(deleted):]))
}
return
}
@@ -179,7 +173,7 @@ func (b *Buffer) Delete(count int) (deleted string) {
// 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.CursorPosition += b.Document().GetEndOfLinePosition()
b.Delete(1)
// Remove spaces
b.setText(b.Document().TextBeforeCursor() + separator + strings.TrimLeft(b.Document().TextAfterCursor(), " "))
@@ -188,10 +182,10 @@ func (b *Buffer) JoinNextLine(separator string) {
// 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:])
+ 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:])
}
}
diff --git a/vendor/github.com/c-bata/go-prompt/completion.go b/vendor/github.com/c-bata/go-prompt/completion.go
index 5f698034bf..0c0f54bf81 100644
--- a/vendor/github.com/c-bata/go-prompt/completion.go
+++ b/vendor/github.com/c-bata/go-prompt/completion.go
@@ -3,21 +3,16 @@ 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)
+ shortenSuffix = "..."
+ leftPrefix = " "
+ leftSuffix = " "
+ rightPrefix = " "
+ rightSuffix = " "
+ leftMargin = len(leftPrefix + leftSuffix)
+ rightMargin = len(rightPrefix + rightSuffix)
completionMargin = leftMargin + rightMargin
)
@@ -35,7 +30,6 @@ type CompletionManager struct {
completer Completer
verticalScroll int
- wordSeparator string
}
// GetSelectedSuggestion returns the selected item.
@@ -108,26 +102,17 @@ func (c *CompletionManager) update() {
}
}
-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)
+ lenPrefix := len([]rune(prefix))
+ lenSuffix := len([]rune(suffix))
+ lenShorten := len(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 < len([]rune(o[i])) {
+ width = len([]rune(o[i]))
}
}
@@ -143,15 +128,13 @@ func formatTexts(o []string, max int, prefix, suffix string) (new []string, widt
}
for i := 0; i < l; i++ {
- x := runewidth.StringWidth(o[i])
+ r := []rune(o[i])
+ x := len(r)
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
+ n[i] = prefix + string(r[:width-lenShorten]) + shortenSuffix + suffix
}
}
return n, lenPrefix + width + lenSuffix
diff --git a/vendor/github.com/c-bata/go-prompt/output.go b/vendor/github.com/c-bata/go-prompt/console_interface.go
similarity index 58%
rename from vendor/github.com/c-bata/go-prompt/output.go
rename to vendor/github.com/c-bata/go-prompt/console_interface.go
index 5afb81c090..1215359a77 100644
--- a/vendor/github.com/c-bata/go-prompt/output.go
+++ b/vendor/github.com/c-bata/go-prompt/console_interface.go
@@ -1,90 +1,63 @@
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
-)
+// WinSize represents the width and height of terminal.
+type WinSize struct {
+ Row uint16
+ Col uint16
+}
// 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
)
+// 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)
+}
+
// 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 to write byte array without control sequences.
Write(data []byte)
// WriteStr to write raw string.
WriteRawStr(data string)
- // WriteStr to write safety string by removing control sequences.
+ // WriteStr to write string without control sequences.
WriteStr(data string)
// Flush to flush buffer.
Flush() error
diff --git a/vendor/github.com/c-bata/go-prompt/document.go b/vendor/github.com/c-bata/go-prompt/document.go
index 06b436a21d..94a410e229 100644
--- a/vendor/github.com/c-bata/go-prompt/document.go
+++ b/vendor/github.com/c-bata/go-prompt/document.go
@@ -1,41 +1,24 @@
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
+ Text string
+ CursorPosition int
}
// NewDocument return the new empty document.
func NewDocument() *Document {
return &Document{
Text: "",
- cursorPosition: 0,
+ 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
@@ -44,7 +27,7 @@ func (d *Document) GetCharRelativeToCursor(offset int) (r rune) {
for len(s) > 0 {
cnt++
r, size := utf8.DecodeRuneInString(s)
- if cnt == d.cursorPosition+offset {
+ if cnt == d.CursorPosition+offset {
return r
}
s = s[size:]
@@ -55,13 +38,13 @@ func (d *Document) GetCharRelativeToCursor(offset int) (r rune) {
// TextBeforeCursor returns the text before the cursor.
func (d *Document) TextBeforeCursor() string {
r := []rune(d.Text)
- return string(r[:d.cursorPosition])
+ 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:])
+ return string(r[d.CursorPosition:])
}
// GetWordBeforeCursor returns the word before the cursor.
@@ -71,13 +54,6 @@ func (d *Document) GetWordBeforeCursor() string {
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 {
@@ -85,46 +61,16 @@ func (d *Document) GetWordBeforeCursorWithSpace() string {
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.
+// pointing to the start of the previous word. Return `None` if nothing was found.
func (d *Document) FindStartOfPreviousWord() int {
+ // Reverse the text before the cursor, in order to do an efficient backwards search.
x := d.TextBeforeCursor()
- i := strings.LastIndexByte(x, ' ')
- if i != -1 {
- return i + 1
+ l := len(x)
+ for i := l; i > 0; i-- {
+ if x[i-1:i] == " " {
+ return i
+ }
}
return 0
}
@@ -132,119 +78,21 @@ func (d *Document) FindStartOfPreviousWord() int {
// FindStartOfPreviousWordWithSpace is almost the same as FindStartOfPreviousWord.
// The only difference is to ignore contiguous spaces.
func (d *Document) FindStartOfPreviousWordWithSpace() int {
+ // Reverse the text before the cursor, in order to do an efficient backwards search.
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
+ l := len(x)
+ appear := false
+ for i := l; i > 0; i-- {
+ if x[i-1:i] != " " {
+ appear = true
+ }
+ if x[i-1:i] == " " && appear {
+ return i
+ }
}
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")
@@ -292,14 +140,14 @@ func (d *Document) lineStartIndexes() []int {
// the first character on that line.
func (d *Document) findLineStartIndex(index int) (pos int, lineStartIndex int) {
indexes := d.lineStartIndexes()
- pos = bisectRight(indexes, index) - 1
+ 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)
+ row, _ = d.findLineStartIndex(d.CursorPosition)
return
}
@@ -307,8 +155,8 @@ func (d *Document) CursorPositionRow() (row int) {
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
+ _, index := d.findLineStartIndex(d.CursorPosition)
+ col = d.CursorPosition - index
return
}
@@ -348,7 +196,7 @@ func (d *Document) GetCursorUpPosition(count int, preferredColumn int) int {
if row < 0 {
row = 0
}
- return d.TranslateRowColToIndex(row, col) - d.cursorPosition
+ return d.TranslateRowColToIndex(row, col) - d.CursorPosition
}
// GetCursorDownPosition return the relative cursor position (character index) where we would be if the
@@ -361,7 +209,7 @@ func (d *Document) GetCursorDownPosition(count int, preferredColumn int) int {
col = preferredColumn
}
row := d.CursorPositionRow() + count
- return d.TranslateRowColToIndex(row, col) - d.cursorPosition
+ return d.TranslateRowColToIndex(row, col) - d.CursorPosition
}
// Lines returns the array of all the lines.
@@ -432,102 +280,3 @@ func (d *Document) leadingWhitespaceInCurrentLine() (margin string) {
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
-}
diff --git a/vendor/github.com/c-bata/go-prompt/emacs.go b/vendor/github.com/c-bata/go-prompt/emacs.go
index 9dc71edcab..f38d3f7302 100644
--- a/vendor/github.com/c-bata/go-prompt/emacs.go
+++ b/vendor/github.com/c-bata/go-prompt/emacs.go
@@ -113,7 +113,6 @@ var emacsKeyBindings = []KeyBind{
out := NewStandardOutputWriter()
out.EraseScreen()
out.CursorGoTo(0, 0)
- out.Flush()
},
},
}
diff --git a/vendor/github.com/c-bata/go-prompt/input.go b/vendor/github.com/c-bata/go-prompt/input.go
index 4c90b0f309..70837103cc 100644
--- a/vendor/github.com/c-bata/go-prompt/input.go
+++ b/vendor/github.com/c-bata/go-prompt/input.go
@@ -1,158 +1,42 @@
package prompt
-// WinSize represents the width and height of terminal.
-type WinSize struct {
- Row uint16
- Col uint16
+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()
}
-// 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)
+// Choose to the shortcut of input function to select from string array.
+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()
}
-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
+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)
+ }
}
diff --git a/vendor/github.com/c-bata/go-prompt/input_posix.go b/vendor/github.com/c-bata/go-prompt/input_posix.go
deleted file mode 100644
index 46ecb511a1..0000000000
--- a/vendor/github.com/c-bata/go-prompt/input_posix.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// +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,
- }
-}
diff --git a/vendor/github.com/c-bata/go-prompt/input_windows.go b/vendor/github.com/c-bata/go-prompt/input_windows.go
deleted file mode 100644
index f52b538977..0000000000
--- a/vendor/github.com/c-bata/go-prompt/input_windows.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// +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{}
-}
diff --git a/vendor/github.com/c-bata/go-prompt/key.go b/vendor/github.com/c-bata/go-prompt/key.go
index 068b70e9f7..9f79185f50 100644
--- a/vendor/github.com/c-bata/go-prompt/key.go
+++ b/vendor/github.com/c-bata/go-prompt/key.go
@@ -1,6 +1,3 @@
-// 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.
diff --git a/vendor/github.com/c-bata/go-prompt/key_bind.go b/vendor/github.com/c-bata/go-prompt/key_bind.go
index 42669e7f94..0cfcab44aa 100644
--- a/vendor/github.com/c-bata/go-prompt/key_bind.go
+++ b/vendor/github.com/c-bata/go-prompt/key_bind.go
@@ -1,59 +1,62 @@
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"
+ EmacsKeyBind KeyBindMode = "emacs"
)
var commonKeyBindings = []KeyBind{
// Go to the End of the line
{
Key: End,
- Fn: GoLineEnd,
+ Fn: func(buf *Buffer) {
+ x := []rune(buf.Document().TextAfterCursor())
+ buf.CursorRight(len(x))
+ },
},
// Go to the beginning of the line
{
Key: Home,
- Fn: GoLineBeginning,
+ Fn: func(buf *Buffer) {
+ x := []rune(buf.Document().TextBeforeCursor())
+ buf.CursorLeft(len(x))
+ },
},
// Delete character under the cursor
{
Key: Delete,
- Fn: DeleteChar,
+ Fn: func(buf *Buffer) {
+ buf.Delete(1)
+ },
},
// Backspace
{
Key: Backspace,
- Fn: DeleteBeforeChar,
+ Fn: func(buf *Buffer) {
+ buf.DeleteBeforeCursor(1)
+ },
},
// Right allow: Forward one character
{
Key: Right,
- Fn: GoRightChar,
+ Fn: func(buf *Buffer) {
+ buf.CursorRight(1)
+ },
},
// Left allow: Backward one character
{
Key: Left,
- Fn: GoLeftChar,
+ Fn: func(buf *Buffer) {
+ buf.CursorLeft(1)
+ },
},
}
diff --git a/vendor/github.com/c-bata/go-prompt/key_bind_func.go b/vendor/github.com/c-bata/go-prompt/key_bind_func.go
deleted file mode 100644
index 7b2ecdf631..0000000000
--- a/vendor/github.com/c-bata/go-prompt/key_bind_func.go
+++ /dev/null
@@ -1,48 +0,0 @@
-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())
-}
diff --git a/vendor/github.com/c-bata/go-prompt/option.go b/vendor/github.com/c-bata/go-prompt/option.go
index 9a7f386da3..72c6de3103 100644
--- a/vendor/github.com/c-bata/go-prompt/option.go
+++ b/vendor/github.com/c-bata/go-prompt/option.go
@@ -12,7 +12,7 @@ func OptionParser(x ConsoleParser) Option {
}
}
-// OptionWriter to set a custom ConsoleWriter object. An argument should implement ConsoleWriter interface.
+// OptionWriter to set a custom ConsoleWriter object. An argument should implement ConsoleWriter interace.
func OptionWriter(x ConsoleWriter) Option {
return func(p *Prompt) error {
p.renderer.out = x
@@ -36,14 +36,6 @@ func OptionPrefix(x string) Option {
}
}
-// 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 {
@@ -52,7 +44,6 @@ func OptionLivePrefix(f func() (prefix string, useLivePrefix bool)) Option {
}
}
-// OptionPrefixTextColor change a text color of prefix string
func OptionPrefixTextColor(x Color) Option {
return func(p *Prompt) error {
p.renderer.prefixTextColor = x
@@ -60,7 +51,6 @@ func OptionPrefixTextColor(x Color) Option {
}
}
-// OptionPrefixBackgroundColor to change a background color of prefix string
func OptionPrefixBackgroundColor(x Color) Option {
return func(p *Prompt) error {
p.renderer.prefixBGColor = x
@@ -68,7 +58,6 @@ func OptionPrefixBackgroundColor(x Color) Option {
}
}
-// 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
@@ -76,7 +65,6 @@ func OptionInputTextColor(x Color) Option {
}
}
-// 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
@@ -84,7 +72,6 @@ func OptionInputBGColor(x Color) Option {
}
}
-// OptionPreviewSuggestionTextColor to change a text color which is completed
func OptionPreviewSuggestionTextColor(x Color) Option {
return func(p *Prompt) error {
p.renderer.previewSuggestionTextColor = x
@@ -92,7 +79,6 @@ func OptionPreviewSuggestionTextColor(x Color) Option {
}
}
-// OptionPreviewSuggestionBGColor to change a background color which is completed
func OptionPreviewSuggestionBGColor(x Color) Option {
return func(p *Prompt) error {
p.renderer.previewSuggestionBGColor = x
@@ -100,7 +86,6 @@ func OptionPreviewSuggestionBGColor(x Color) Option {
}
}
-// OptionSuggestionTextColor to change a text color in drop down suggestions.
func OptionSuggestionTextColor(x Color) Option {
return func(p *Prompt) error {
p.renderer.suggestionTextColor = x
@@ -108,7 +93,6 @@ func OptionSuggestionTextColor(x Color) Option {
}
}
-// OptionSuggestionBGColor change a background color in drop down suggestions.
func OptionSuggestionBGColor(x Color) Option {
return func(p *Prompt) error {
p.renderer.suggestionBGColor = x
@@ -116,7 +100,6 @@ func OptionSuggestionBGColor(x Color) Option {
}
}
-// 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
@@ -124,7 +107,6 @@ func OptionSelectedSuggestionTextColor(x Color) Option {
}
}
-// 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
@@ -132,7 +114,6 @@ func OptionSelectedSuggestionBGColor(x Color) Option {
}
}
-// 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
@@ -140,7 +121,6 @@ func OptionDescriptionTextColor(x Color) Option {
}
}
-// 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
@@ -148,7 +128,6 @@ func OptionDescriptionBGColor(x Color) Option {
}
}
-// 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
@@ -156,7 +135,6 @@ func OptionSelectedDescriptionTextColor(x Color) Option {
}
}
-// 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
@@ -164,7 +142,6 @@ func OptionSelectedDescriptionBGColor(x Color) Option {
}
}
-// OptionScrollbarThumbColor to change a thumb color on scrollbar.
func OptionScrollbarThumbColor(x Color) Option {
return func(p *Prompt) error {
p.renderer.scrollbarThumbColor = x
@@ -172,7 +149,6 @@ func OptionScrollbarThumbColor(x Color) Option {
}
}
-// OptionScrollbarBGColor to change a background color of scrollbar.
func OptionScrollbarBGColor(x Color) Option {
return func(p *Prompt) error {
p.renderer.scrollbarBGColor = x
@@ -217,14 +193,6 @@ func OptionAddKeyBind(b ...KeyBind) Option {
}
}
-// 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{
diff --git a/vendor/github.com/c-bata/go-prompt/output_posix.go b/vendor/github.com/c-bata/go-prompt/output_posix.go
deleted file mode 100644
index 4c2ccf63b1..0000000000
--- a/vendor/github.com/c-bata/go-prompt/output_posix.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// +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,
- }
-}
diff --git a/vendor/github.com/c-bata/go-prompt/output_vt100.go b/vendor/github.com/c-bata/go-prompt/output_vt100.go
deleted file mode 100644
index 3b3031d70b..0000000000
--- a/vendor/github.com/c-bata/go-prompt/output_vt100.go
+++ /dev/null
@@ -1,333 +0,0 @@
-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. [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'},
-}
diff --git a/vendor/github.com/c-bata/go-prompt/output_windows.go b/vendor/github.com/c-bata/go-prompt/output_windows.go
deleted file mode 100644
index 7418af3491..0000000000
--- a/vendor/github.com/c-bata/go-prompt/output_windows.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// +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(),
- }
-}
diff --git a/vendor/github.com/c-bata/go-prompt/posix_input.go b/vendor/github.com/c-bata/go-prompt/posix_input.go
new file mode 100644
index 0000000000..ead496d97e
--- /dev/null
+++ b/vendor/github.com/c-bata/go-prompt/posix_input.go
@@ -0,0 +1,265 @@
+// +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 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
+}
+
+var _ ConsoleParser = &PosixParser{}
+
+// NewStandardInputParser returns ConsoleParser object to read from stdin.
+func NewStandardInputParser() *PosixParser {
+ return &PosixParser{
+ fd: syscall.Stdin,
+ }
+}
diff --git a/vendor/github.com/c-bata/go-prompt/posix_output.go b/vendor/github.com/c-bata/go-prompt/posix_output.go
new file mode 100644
index 0000000000..52c69d9465
--- /dev/null
+++ b/vendor/github.com/c-bata/go-prompt/posix_output.go
@@ -0,0 +1,335 @@
+// +build !windows
+
+package prompt
+
+import (
+ "strconv"
+ "syscall"
+)
+
+// PosixWriter is a ConsoleWriter implementation for POSIX environment.
+// To control terminal emulator, this outputs VT100 escape sequences.
+type PosixWriter struct {
+ fd int
+ buffer []byte
+}
+
+// WriteRaw to write raw byte array
+func (w *PosixWriter) WriteRaw(data []byte) {
+ w.buffer = append(w.buffer, data...)
+ // Flush because sometimes the render is broken when a large amount data in buffer.
+ w.Flush()
+ return
+}
+
+// Write to write byte array without control sequences
+func (w *PosixWriter) Write(data []byte) {
+ w.WriteRaw(byteFilter(data, writeFilter))
+ return
+}
+
+// WriteRawStr to write raw string
+func (w *PosixWriter) WriteRawStr(data string) {
+ w.WriteRaw([]byte(data))
+ return
+}
+
+// WriteStr to write string without control sequences
+func (w *PosixWriter) WriteStr(data string) {
+ w.Write([]byte(data))
+ return
+}
+
+// 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
+}
+
+/* Erase */
+
+// EraseScreen erases the screen with the background colour and moves the cursor to home.
+func (w *PosixWriter) EraseScreen() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x32, 0x4a})
+ return
+}
+
+// EraseUp erases the screen from the current line up to the top of the screen.
+func (w *PosixWriter) EraseUp() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x31, 0x4a})
+ return
+}
+
+// EraseDown erases the screen from the current line down to the bottom of the screen.
+func (w *PosixWriter) EraseDown() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x4a})
+ return
+}
+
+// EraseStartOfLine erases from the current cursor position to the start of the current line.
+func (w *PosixWriter) EraseStartOfLine() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x31, 0x4b})
+ return
+}
+
+// EraseEndOfLine erases from the current cursor position to the end of the current line.
+func (w *PosixWriter) EraseEndOfLine() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x4b})
+ return
+}
+
+// EraseLine erases the entire current line.
+func (w *PosixWriter) EraseLine() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x32, 0x4b})
+ return
+}
+
+/* Cursor */
+
+// ShowCursor stops blinking cursor and show.
+func (w *PosixWriter) ShowCursor() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x3f, 0x31, 0x32, 0x6c, 0x1b, 0x5b, 0x3f, 0x32, 0x35, 0x68})
+}
+
+// HideCursor hides cursor.
+func (w *PosixWriter) HideCursor() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x3f, 0x32, 0x35, 0x6c})
+ return
+}
+
+// CursorGoTo sets the cursor position where subsequent text will begin.
+func (w *PosixWriter) CursorGoTo(row, col int) {
+ if row == 0 && col == 0 {
+ // If no row/column parameters are provided (ie. [H), the cursor will move to the home position.
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x3b, 0x48})
+ return
+ }
+ r := strconv.Itoa(row)
+ c := strconv.Itoa(col)
+ w.WriteRaw([]byte{0x1b, 0x5b})
+ w.WriteRaw([]byte(r))
+ w.WriteRaw([]byte{0x3b})
+ w.WriteRaw([]byte(c))
+ w.WriteRaw([]byte{0x48})
+ return
+}
+
+// CursorUp moves the cursor up by 'n' rows; the default count is 1.
+func (w *PosixWriter) CursorUp(n int) {
+ if n == 0 {
+ return
+ } else if n < 0 {
+ w.CursorDown(-n)
+ return
+ }
+ s := strconv.Itoa(n)
+ w.WriteRaw([]byte{0x1b, 0x5b})
+ w.WriteRaw([]byte(s))
+ w.WriteRaw([]byte{0x41})
+ return
+}
+
+// CursorDown moves the cursor down by 'n' rows; the default count is 1.
+func (w *PosixWriter) CursorDown(n int) {
+ if n == 0 {
+ return
+ } else if n < 0 {
+ w.CursorUp(-n)
+ return
+ }
+ s := strconv.Itoa(n)
+ w.WriteRaw([]byte{0x1b, 0x5b})
+ w.WriteRaw([]byte(s))
+ w.WriteRaw([]byte{0x42})
+ return
+}
+
+// CursorForward moves the cursor forward by 'n' columns; the default count is 1.
+func (w *PosixWriter) CursorForward(n int) {
+ if n == 0 {
+ return
+ } else if n < 0 {
+ w.CursorBackward(-n)
+ return
+ }
+ s := strconv.Itoa(n)
+ w.WriteRaw([]byte{0x1b, 0x5b})
+ w.WriteRaw([]byte(s))
+ w.WriteRaw([]byte{0x43})
+ return
+}
+
+// CursorBackward moves the cursor backward by 'n' columns; the default count is 1.
+func (w *PosixWriter) CursorBackward(n int) {
+ if n == 0 {
+ return
+ } else if n < 0 {
+ w.CursorForward(-n)
+ return
+ }
+ s := strconv.Itoa(n)
+ w.WriteRaw([]byte{0x1b, 0x5b})
+ w.WriteRaw([]byte(s))
+ w.WriteRaw([]byte{0x44})
+ return
+}
+
+// AskForCPR asks for a cursor position report (CPR).
+func (w *PosixWriter) AskForCPR() {
+ // CPR: Cursor Position Request.
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x36, 0x6e})
+ w.Flush()
+ return
+}
+
+// SaveCursor saves current cursor position.
+func (w *PosixWriter) SaveCursor() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x73})
+ return
+}
+
+// UnSaveCursor restores cursor position after a Save Cursor.
+func (w *PosixWriter) UnSaveCursor() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x75})
+ return
+}
+
+/* Scrolling */
+
+// ScrollDown scrolls display down one line.
+func (w *PosixWriter) ScrollDown() {
+ w.WriteRaw([]byte{0x1b, 0x44})
+ return
+}
+
+// ScrollUp scroll display up one line.
+func (w *PosixWriter) ScrollUp() {
+ w.WriteRaw([]byte{0x1b, 0x4d})
+ return
+}
+
+/* Title */
+
+// SetTitle sets a title of terminal window.
+func (w *PosixWriter) SetTitle(title string) {
+ w.WriteRaw([]byte{0x1b, 0x5d, 0x32, 0x3b})
+ w.WriteRaw(byteFilter([]byte(title), setTextFilter))
+ w.WriteRaw([]byte{0x07})
+ return
+}
+
+// ClearTitle clears a title of terminal window.
+func (w *PosixWriter) ClearTitle() {
+ w.WriteRaw([]byte{0x1b, 0x5d, 0x32, 0x3b, 0x07})
+ return
+}
+
+/* Font */
+
+// SetColor sets text and background colors. and specify whether text is bold.
+func (w *PosixWriter) SetColor(fg, bg Color, bold bool) {
+ f, ok := foregroundANSIColors[fg]
+ if !ok {
+ f = foregroundANSIColors[DefaultColor]
+ }
+ b, ok := backgroundANSIColors[bg]
+ if !ok {
+ b = backgroundANSIColors[DefaultColor]
+ }
+ syscall.Write(syscall.Stdout, []byte{0x1b, 0x5b, 0x33, 0x39, 0x3b, 0x34, 0x39, 0x6d})
+ w.WriteRaw([]byte{0x1b, 0x5b})
+ if !bold {
+ w.WriteRaw([]byte{0x30, 0x3b})
+ }
+ w.WriteRaw(f)
+ w.WriteRaw([]byte{0x3b})
+ w.WriteRaw(b)
+ if bold {
+ w.WriteRaw([]byte{0x3b, 0x31})
+ }
+ w.WriteRaw([]byte{0x6d})
+ return
+}
+
+var foregroundANSIColors = map[Color][]byte{
+ DefaultColor: {0x33, 0x39}, // 39
+
+ // Low intensity.
+ Black: {0x33, 0x30}, // 30
+ DarkRed: {0x33, 0x31}, // 31
+ DarkGreen: {0x33, 0x32}, // 32
+ Brown: {0x33, 0x33}, // 33
+ DarkBlue: {0x33, 0x34}, // 34
+ Purple: {0x33, 0x35}, // 35
+ Cyan: {0x33, 0x36}, //36
+ LightGray: {0x33, 0x37}, //37
+
+ // High intensity.
+ DarkGray: {0x39, 0x30}, // 90
+ Red: {0x39, 0x31}, // 91
+ Green: {0x39, 0x32}, // 92
+ Yellow: {0x39, 0x33}, // 93
+ Blue: {0x39, 0x34}, // 94
+ Fuchsia: {0x39, 0x35}, // 95
+ Turquoise: {0x39, 0x36}, // 96
+ White: {0x39, 0x37}, // 97
+}
+
+var backgroundANSIColors = map[Color][]byte{
+ DefaultColor: {0x34, 0x39}, // 49
+
+ // Low intensity.
+ Black: {0x34, 0x30}, // 40
+ DarkRed: {0x34, 0x31}, // 41
+ DarkGreen: {0x34, 0x32}, // 42
+ Brown: {0x34, 0x33}, // 43
+ DarkBlue: {0x34, 0x34}, // 44
+ Purple: {0x34, 0x35}, // 45
+ Cyan: {0x34, 0x36}, // 46
+ LightGray: {0x34, 0x37}, // 47
+
+ // High intensity
+ DarkGray: {0x31, 0x30, 0x30}, // 100
+ Red: {0x31, 0x30, 0x31}, // 101
+ Green: {0x31, 0x30, 0x32}, // 102
+ Yellow: {0x31, 0x30, 0x33}, // 103
+ Blue: {0x31, 0x30, 0x34}, // 104
+ Fuchsia: {0x31, 0x30, 0x35}, // 105
+ Turquoise: {0x31, 0x30, 0x36}, // 106
+ White: {0x31, 0x30, 0x37}, // 107
+}
+
+func writeFilter(buf byte) bool {
+ return buf != 0x1b && buf != 0x3f
+}
+
+func setTextFilter(buf byte) bool {
+ return buf != 0x1b && buf != 0x07
+}
+
+func byteFilter(buf []byte, fn ...func(b byte) bool) []byte {
+ if len(fn) == 0 {
+ return buf
+ }
+ ret := make([]byte, 0, len(buf))
+ f := fn[0]
+ for i, n := range buf {
+ if f(n) {
+ ret = append(ret, buf[i])
+ }
+ }
+ return byteFilter(ret, fn[1:]...)
+}
+
+var _ ConsoleWriter = &PosixWriter{}
+
+// NewStandardOutputWriter returns ConsoleWriter object to write to stdout.
+func NewStandardOutputWriter() *PosixWriter {
+ return &PosixWriter{
+ fd: syscall.Stdout,
+ }
+}
diff --git a/vendor/github.com/c-bata/go-prompt/prompt.go b/vendor/github.com/c-bata/go-prompt/prompt.go
index 6f72944c34..74ce03b616 100644
--- a/vendor/github.com/c-bata/go-prompt/prompt.go
+++ b/vendor/github.com/c-bata/go-prompt/prompt.go
@@ -1,7 +1,6 @@
package prompt
import (
- "bytes"
"io/ioutil"
"log"
"os"
@@ -20,15 +19,14 @@ 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
+ in ConsoleParser
+ buf *Buffer
+ renderer *Render
+ executor Executor
+ history *History
+ completion *CompletionManager
+ keyBindings []KeyBind
+ keyBindMode KeyBindMode
}
// Exec is the struct contains user input context.
@@ -67,8 +65,6 @@ func (p *Prompt) Run() {
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
@@ -109,7 +105,31 @@ func (p *Prompt) feed(b []byte) (shouldExit bool, exec *Exec) {
// completion
completing := p.completion.Completing()
- p.handleCompletionKeyBinding(key, completing)
+ 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()
+ case ControlSpace:
+ return
+ default:
+ if s, ok := p.completion.GetSelectedSuggestion(); ok {
+ w := p.buf.Document().GetWordBeforeCursor()
+ if w != "" {
+ p.buf.DeleteBeforeCursor(len([]rune(w)))
+ }
+ p.buf.InsertText(s.Text, false, true)
+ }
+ p.completion.Reset()
+ }
switch key {
case Enter, ControlJ, ControlM:
@@ -144,43 +164,10 @@ func (p *Prompt) feed(b []byte) (shouldExit bool, exec *Exec) {
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) {
+ // Key bindings
for i := range commonKeyBindings {
kb := commonKeyBindings[i]
if kb.Key == key {
@@ -204,17 +191,7 @@ func (p *Prompt) handleKeyBinding(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
+ return
}
// Input just returns user input text.
@@ -242,7 +219,6 @@ func (p *Prompt) Input() string {
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
@@ -261,16 +237,16 @@ func (p *Prompt) Input() string {
func (p *Prompt) readBuffer(bufCh chan []byte, stopCh chan struct{}) {
log.Printf("[INFO] readBuffer start")
for {
+ time.Sleep(10 * time.Millisecond)
select {
case <-stopCh:
log.Print("[INFO] stop readBuffer")
return
default:
- if b, err := p.in.Read(); err == nil && !(len(b) == 1 && b[0] == 0) {
+ if b, err := p.in.Read(); err == nil {
bufCh <- b
}
}
- time.Sleep(10 * time.Millisecond)
}
}
diff --git a/vendor/github.com/c-bata/go-prompt/render.go b/vendor/github.com/c-bata/go-prompt/render.go
index 2d774aafca..e37867876e 100644
--- a/vendor/github.com/c-bata/go-prompt/render.go
+++ b/vendor/github.com/c-bata/go-prompt/render.go
@@ -1,11 +1,5 @@
package prompt
-import (
- "runtime"
-
- "github.com/mattn/go-runewidth"
-)
-
// Render to render prompt information from state of Buffer.
type Render struct {
out ConsoleWriter
@@ -88,6 +82,7 @@ func (r *Render) renderWindowTooSmall() {
r.out.EraseScreen()
r.out.SetColor(DarkRed, White, false)
r.out.WriteStr("Your console window is too small...")
+ r.out.Flush()
return
}
@@ -99,7 +94,7 @@ func (r *Render) renderCompletion(buf *Buffer, completions *CompletionManager) {
prefix := r.getCurrentPrefix()
formatted, width := formatSuggestions(
suggestions,
- int(r.col)-runewidth.StringWidth(prefix)-1, // -1 means a width of scrollbar
+ int(r.col)-len(prefix)-1, // -1 means a width of scrollbar
)
// +1 means a width of scrollbar.
width++
@@ -111,10 +106,10 @@ func (r *Render) renderCompletion(buf *Buffer, completions *CompletionManager) {
formatted = formatted[completions.verticalScroll : completions.verticalScroll+windowHeight]
r.prepareArea(windowHeight)
- cursor := runewidth.StringWidth(prefix) + runewidth.StringWidth(buf.Document().TextBeforeCursor())
+ cursor := len(prefix) + len(buf.Document().TextBeforeCursor())
x, _ := r.toPos(cursor)
if x+width >= int(r.col) {
- cursor = r.backward(cursor, x+width-int(r.col))
+ r.out.CursorBackward(x + width - int(r.col))
}
contentHeight := len(completions.tmp)
@@ -153,10 +148,7 @@ func (r *Render) renderCompletion(buf *Buffer, completions *CompletionManager) {
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)
+ r.out.CursorBackward(width)
}
if x+width >= int(r.col) {
@@ -170,64 +162,53 @@ func (r *Render) renderCompletion(buf *Buffer, completions *CompletionManager) {
// 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)
+ cursor := len(prefix) + len(line)
- // prepare area
- _, y := r.toPos(cursor)
+ // In situations where a psuedo 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 {
+ // Erasing
+ r.clear(r.previousCursor)
- h := y + 1 + int(completion.max)
- if h > int(r.row) || completionMargin > int(r.col) {
- r.renderWindowTooSmall()
- return
+ // 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())
+ cursor = r.backward(cursor, len(line)-buffer.CursorPosition)
r.renderCompletion(buffer, completion)
if suggest, ok := completion.GetSelectedSuggestion(); ok {
- cursor = r.backward(cursor, runewidth.StringWidth(buffer.Document().GetWordBeforeCursorUntilSeparator(completion.wordSeparator)))
+ cursor = r.backward(cursor, len(buffer.Document().GetWordBeforeCursor()))
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))
+ cursor += len(suggest.Text)
}
+ r.out.Flush()
+
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())
+ cursor := len(buffer.Document().TextBeforeCursor()) + len(r.getCurrentPrefix())
r.clear(cursor)
r.renderPrefix()
r.out.SetColor(r.inputTextColor, r.inputBGColor, false)
@@ -238,40 +219,37 @@ func (r *Render) BreakLine(buffer *Buffer) {
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.backward(cursor, cursor)
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)
+ _, fromY := r.toPos(from)
toX, toY := r.toPos(to)
r.out.CursorUp(fromY - toY)
- r.out.CursorBackward(fromX - toX)
+ r.out.WriteRaw([]byte{'\r'})
+ r.out.CursorForward(toX)
return to
}
// toPos returns the relative position from the beginning of the string.
+// the coordinate system with the beginning of the string as (0,0) and the width as r.col.
+// the cursor points to the next character, but it points to that character only at the right end (x == r.col - 1).
+// x will not return 0 except for the first row.
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'})
+ if cursor > 0 && cursor%col == 0 {
+ return col - 1, cursor/col - 1
}
+
+ return cursor % col, cursor / col
}
func clamp(high, low, x float64) float64 {
diff --git a/vendor/github.com/c-bata/go-prompt/shortcut.go b/vendor/github.com/c-bata/go-prompt/shortcut.go
deleted file mode 100644
index 20fe71d085..0000000000
--- a/vendor/github.com/c-bata/go-prompt/shortcut.go
+++ /dev/null
@@ -1,43 +0,0 @@
-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)
- }
-}
diff --git a/vendor/github.com/c-bata/go-prompt/windows_input.go b/vendor/github.com/c-bata/go-prompt/windows_input.go
new file mode 100644
index 0000000000..13b332a775
--- /dev/null
+++ b/vendor/github.com/c-bata/go-prompt/windows_input.go
@@ -0,0 +1,214 @@
+// +build windows
+
+package prompt
+
+import (
+ "bytes"
+ "unicode/utf8"
+
+ "github.com/mattn/go-tty"
+)
+
+const maxReadBytes = 1024
+
+// 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) {
+ buf := make([]byte, maxReadBytes)
+ r, err := p.tty.ReadRune()
+ if err != nil {
+ return []byte{}, err
+ }
+ 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),
+ }
+}
+
+var asciiSequences []*ASCIICode = []*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, 0x4f, 0x48}},
+ {Key: End, ASCIICode: []byte{0x1b, 0x5b, 0x70}},
+ {Key: End, ASCIICode: []byte{0x1b, 0x4f, 0x70}},
+
+ {Key: Enter, ASCIICode: []byte{0xa}},
+ {Key: Delete, ASCIICode: []byte{0x1b, 0x5b, 0x33, 0x7e}},
+ {Key: ShiftDelete, ASCIICode: []byte{0x1b, 0x5b, 0x33, 0x3b, 0x02, 0x7e}},
+ {Key: ControlDelete, ASCIICode: []byte{0x1b, 0x5b, 0x33, 0x3b, 0x05, 0x7e}},
+ {Key: Home, ASCIICode: []byte{0x1b, 0x5b, 0x01, 0x7e}},
+ {Key: End, ASCIICode: []byte{0x1b, 0x5b, 0x04, 0x7e}},
+ {Key: PageUp, ASCIICode: []byte{0x1b, 0x5b, 0x05, 0x7e}},
+ {Key: PageDown, ASCIICode: []byte{0x1b, 0x5b, 0x06, 0x7e}},
+ {Key: Home, ASCIICode: []byte{0x1b, 0x5b, 0x07, 0x7e}},
+ {Key: End, ASCIICode: []byte{0x1b, 0x5b, 0x09, 0x7e}},
+ {Key: Tab, ASCIICode: []byte{0x9}},
+ {Key: BackTab, ASCIICode: []byte{0x1b, 0x5b, 0x5a}},
+ {Key: Insert, ASCIICode: []byte{0x1b, 0x5b, 0x02, 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, 0x01, 0x3b, 0x02, 0x50}},
+ {Key: F14, ASCIICode: []byte{0x1b, 0x5b, 0x01, 0x3b, 0x02, 0x51}},
+ // &ASCIICode{Key: F15, ASCIICode: []byte{0x1b, 0x5b, 0x01, 0x3b, 0x02, 0x52}}, // Conflicts with CPR response
+ {Key: F16, ASCIICode: []byte{0x1b, 0x5b, 0x01, 0x3b, 0x02, 0x52}},
+ {Key: F17, ASCIICode: []byte{0x1b, 0x5b, 0x15, 0x3b, 0x02, 0x7e}},
+ {Key: F18, ASCIICode: []byte{0x1b, 0x5b, 0x17, 0x3b, 0x02, 0x7e}},
+ {Key: F19, ASCIICode: []byte{0x1b, 0x5b, 0x18, 0x3b, 0x02, 0x7e}},
+ {Key: F20, ASCIICode: []byte{0x1b, 0x5b, 0x19, 0x3b, 0x02, 0x7e}},
+ {Key: F21, ASCIICode: []byte{0x1b, 0x5b, 0x20, 0x3b, 0x02, 0x7e}},
+ {Key: F22, ASCIICode: []byte{0x1b, 0x5b, 0x21, 0x3b, 0x02, 0x7e}},
+ {Key: F23, ASCIICode: []byte{0x1b, 0x5b, 0x23, 0x3b, 0x02, 0x7e}},
+ {Key: F24, ASCIICode: []byte{0x1b, 0x5b, 0x24, 0x3b, 0x02, 0x7e}},
+
+ {Key: ControlUp, ASCIICode: []byte{0x1b, 0x5b, 0x01, 0x3b, 0x5a}},
+ {Key: ControlDown, ASCIICode: []byte{0x1b, 0x5b, 0x01, 0x3b, 0x5b}},
+ {Key: ControlRight, ASCIICode: []byte{0x1b, 0x5b, 0x01, 0x3b, 0x5c}},
+ {Key: ControlLeft, ASCIICode: []byte{0x1b, 0x5b, 0x01, 0x3b, 0x5d}},
+
+ {Key: ShiftUp, ASCIICode: []byte{0x1b, 0x5b, 0x01, 0x2a}},
+ {Key: ShiftDown, ASCIICode: []byte{0x1b, 0x5b, 0x01, 0x2b}},
+ {Key: ShiftRight, ASCIICode: []byte{0x1b, 0x5b, 0x01, 0x2c}},
+ {Key: ShiftLeft, ASCIICode: []byte{0x1b, 0x5b, 0x01, 0x2d}},
+
+ // 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, 0x05, 0x41}},
+ {Key: ControlDown, ASCIICode: []byte{0x1b, 0x5b, 0x05, 0x42}},
+ {Key: ControlRight, ASCIICode: []byte{0x1b, 0x5b, 0x05, 0x43}},
+ {Key: ControlLeft, ASCIICode: []byte{0x1b, 0x5b, 0x05, 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
+}
+
+// NewStandardInputParser returns ConsoleParser object to read from stdin.
+func NewStandardInputParser() *WindowsParser {
+ return &WindowsParser{}
+}
diff --git a/vendor/github.com/c-bata/go-prompt/windows_output.go b/vendor/github.com/c-bata/go-prompt/windows_output.go
new file mode 100644
index 0000000000..2281ab1563
--- /dev/null
+++ b/vendor/github.com/c-bata/go-prompt/windows_output.go
@@ -0,0 +1,333 @@
+// +build windows
+
+package prompt
+
+import (
+ "io"
+ "strconv"
+
+ "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 {
+ out io.Writer
+ buffer []byte
+}
+
+// WriteRaw to write raw byte array
+func (w *WindowsWriter) WriteRaw(data []byte) {
+ w.buffer = append(w.buffer, data...)
+ // Flush because sometimes the render is broken when a large amount data in buffer.
+ w.Flush()
+ return
+}
+
+// Write to write byte array without control sequences
+func (w *WindowsWriter) Write(data []byte) {
+ w.WriteRaw(byteFilter(data, writeFilter))
+ return
+}
+
+// WriteRawStr to write raw string
+func (w *WindowsWriter) WriteRawStr(data string) {
+ w.WriteRaw([]byte(data))
+ return
+}
+
+// WriteStr to write string without control sequences
+func (w *WindowsWriter) WriteStr(data string) {
+ w.Write([]byte(data))
+ return
+}
+
+// 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
+}
+
+/* Erase */
+
+// EraseScreen erases the screen with the background colour and moves the cursor to home.
+func (w *WindowsWriter) EraseScreen() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x32, 0x4a})
+ return
+}
+
+// EraseUp erases the screen from the current line up to the top of the screen.
+func (w *WindowsWriter) EraseUp() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x31, 0x4a})
+ return
+}
+
+// EraseDown erases the screen from the current line down to the bottom of the screen.
+func (w *WindowsWriter) EraseDown() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x4a})
+ return
+}
+
+// EraseStartOfLine erases from the current cursor position to the start of the current line.
+func (w *WindowsWriter) EraseStartOfLine() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x31, 0x4b})
+ return
+}
+
+// EraseEndOfLine erases from the current cursor position to the end of the current line.
+func (w *WindowsWriter) EraseEndOfLine() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x4b})
+ return
+}
+
+// EraseLine erases the entire current line.
+func (w *WindowsWriter) EraseLine() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x32, 0x4b})
+ return
+}
+
+/* Cursor */
+
+// ShowCursor stops blinking cursor and show.
+func (w *WindowsWriter) ShowCursor() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x3f, 0x31, 0x32, 0x6c, 0x1b, 0x5b, 0x3f, 0x32, 0x35, 0x68})
+}
+
+// HideCursor hides cursor.
+func (w *WindowsWriter) HideCursor() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x3f, 0x32, 0x35, 0x6c})
+ return
+}
+
+// CursorGoTo sets the cursor position where subsequent text will begin.
+func (w *WindowsWriter) CursorGoTo(row, col int) {
+ if row == 0 && col == 0 {
+ // If no row/column parameters are provided (ie. [H), the cursor will move to the home position.
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x3b, 0x48})
+ return
+ }
+ r := strconv.Itoa(row)
+ c := strconv.Itoa(col)
+ w.WriteRaw([]byte{0x1b, 0x5b})
+ w.WriteRaw([]byte(r))
+ w.WriteRaw([]byte{0x3b})
+ w.WriteRaw([]byte(c))
+ w.WriteRaw([]byte{0x48})
+ return
+}
+
+// CursorUp moves the cursor up by 'n' rows; the default count is 1.
+func (w *WindowsWriter) CursorUp(n int) {
+ if n < 0 {
+ w.CursorDown(n)
+ return
+ }
+ s := strconv.Itoa(n)
+ w.WriteRaw([]byte{0x1b, 0x5b})
+ w.WriteRaw([]byte(s))
+ w.WriteRaw([]byte{0x41})
+ return
+}
+
+// CursorDown moves the cursor down by 'n' rows; the default count is 1.
+func (w *WindowsWriter) CursorDown(n int) {
+ if n < 0 {
+ w.CursorUp(n)
+ return
+ }
+ s := strconv.Itoa(n)
+ w.WriteRaw([]byte{0x1b, 0x5b})
+ w.WriteRaw([]byte(s))
+ w.WriteRaw([]byte{0x42})
+ return
+}
+
+// CursorForward moves the cursor forward by 'n' columns; the default count is 1.
+func (w *WindowsWriter) CursorForward(n int) {
+ if n == 0 {
+ return
+ } else if n < 0 {
+ w.CursorBackward(-n)
+ return
+ }
+ s := strconv.Itoa(n)
+ w.WriteRaw([]byte{0x1b, 0x5b})
+ w.WriteRaw([]byte(s))
+ w.WriteRaw([]byte{0x43})
+ return
+}
+
+// CursorBackward moves the cursor backward by 'n' columns; the default count is 1.
+func (w *WindowsWriter) CursorBackward(n int) {
+ if n == 0 {
+ return
+ } else if n < 0 {
+ w.CursorForward(-n)
+ return
+ }
+ s := strconv.Itoa(n)
+ w.WriteRaw([]byte{0x1b, 0x5b})
+ w.WriteRaw([]byte(s))
+ w.WriteRaw([]byte{0x44})
+ return
+}
+
+// AskForCPR asks for a cursor position report (CPR).
+func (w *WindowsWriter) AskForCPR() {
+ // CPR: Cursor Position Request.
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x36, 0x6e})
+ w.Flush()
+ return
+}
+
+// SaveCursor saves current cursor position.
+func (w *WindowsWriter) SaveCursor() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x73})
+ return
+}
+
+// UnSaveCursor restores cursor position after a Save Cursor.
+func (w *WindowsWriter) UnSaveCursor() {
+ w.WriteRaw([]byte{0x1b, 0x5b, 0x75})
+ return
+}
+
+/* Scrolling */
+
+// ScrollDown scrolls display down one line.
+func (w *WindowsWriter) ScrollDown() {
+ w.WriteRaw([]byte{0x1b, 0x44})
+ return
+}
+
+// ScrollUp scroll display up one line.
+func (w *WindowsWriter) ScrollUp() {
+ w.WriteRaw([]byte{0x1b, 0x4d})
+ return
+}
+
+/* Title */
+
+// SetTitle sets a title of terminal window.
+func (w *WindowsWriter) SetTitle(title string) {
+ w.WriteRaw([]byte{0x1b, 0x5d, 0x32, 0x3b})
+ w.WriteRaw(byteFilter([]byte(title), setTextFilter))
+ w.WriteRaw([]byte{0x07})
+ return
+}
+
+// ClearTitle clears a title of terminal window.
+func (w *WindowsWriter) ClearTitle() {
+ w.WriteRaw([]byte{0x1b, 0x5d, 0x32, 0x3b, 0x07})
+ return
+}
+
+/* Font */
+
+// SetColor sets text and background colors. and specify whether text is bold.
+func (w *WindowsWriter) SetColor(fg, bg Color, bold bool) {
+ f, ok := foregroundANSIColors[fg]
+ if !ok {
+ f, _ = foregroundANSIColors[DefaultColor]
+ }
+ b, ok := backgroundANSIColors[bg]
+ if !ok {
+ b, _ = backgroundANSIColors[DefaultColor]
+ }
+ w.out.Write([]byte{0x1b, 0x5b, 0x33, 0x39, 0x3b, 0x34, 0x39, 0x6d})
+ w.WriteRaw([]byte{0x1b, 0x5b})
+ if !bold {
+ w.WriteRaw([]byte{0x30, 0x3b})
+ }
+ w.WriteRaw(f)
+ w.WriteRaw([]byte{0x3b})
+ w.WriteRaw(b)
+ if bold {
+ w.WriteRaw([]byte{0x3b, 0x31})
+ }
+ w.WriteRaw([]byte{0x6d})
+ return
+}
+
+var foregroundANSIColors = map[Color][]byte{
+ DefaultColor: {0x33, 0x39}, // 39
+
+ // Low intensity.
+ Black: {0x33, 0x30}, // 30
+ DarkRed: {0x33, 0x31}, // 31
+ DarkGreen: {0x33, 0x32}, // 32
+ Brown: {0x33, 0x33}, // 33
+ DarkBlue: {0x33, 0x34}, // 34
+ Purple: {0x33, 0x35}, // 35
+ Cyan: {0x33, 0x36}, //36
+ LightGray: {0x33, 0x37}, //37
+
+ // High intensity.
+ DarkGray: {0x39, 0x30}, // 90
+ Red: {0x39, 0x31}, // 91
+ Green: {0x39, 0x32}, // 92
+ Yellow: {0x39, 0x33}, // 93
+ Blue: {0x39, 0x34}, // 94
+ Fuchsia: {0x39, 0x35}, // 95
+ Turquoise: {0x39, 0x36}, // 96
+ White: {0x39, 0x37}, // 97
+}
+
+var backgroundANSIColors = map[Color][]byte{
+ DefaultColor: {0x34, 0x39}, // 49
+
+ // Low intensity.
+ Black: {0x34, 0x30}, // 40
+ DarkRed: {0x34, 0x31}, // 41
+ DarkGreen: {0x34, 0x32}, // 42
+ Brown: {0x34, 0x33}, // 43
+ DarkBlue: {0x34, 0x34}, // 44
+ Purple: {0x34, 0x35}, // 45
+ Cyan: {0x34, 0x36}, // 46
+ LightGray: {0x34, 0x37}, // 47
+
+ // High intensity
+ DarkGray: {0x31, 0x30, 0x30}, // 100
+ Red: {0x31, 0x30, 0x31}, // 101
+ Green: {0x31, 0x30, 0x32}, // 102
+ Yellow: {0x31, 0x30, 0x33}, // 103
+ Blue: {0x31, 0x30, 0x34}, // 104
+ Fuchsia: {0x31, 0x30, 0x35}, // 105
+ Turquoise: {0x31, 0x30, 0x36}, // 106
+ White: {0x31, 0x30, 0x37}, // 107
+}
+
+func writeFilter(buf byte) bool {
+ return buf != 0x1b && buf != 0x3f
+}
+
+func setTextFilter(buf byte) bool {
+ return buf != 0x1b && buf != 0x07
+}
+
+func byteFilter(buf []byte, fn ...func(b byte) bool) []byte {
+ if len(fn) == 0 {
+ return buf
+ }
+ ret := make([]byte, 0, len(buf))
+ f := fn[0]
+ for i, n := range buf {
+ if f(n) {
+ ret = append(ret, buf[i])
+ }
+ }
+ return byteFilter(ret, fn[1:]...)
+}
+
+var _ ConsoleWriter = &WindowsWriter{}
+
+// NewStandardOutputWriter returns ConsoleWriter object to write to stdout.
+func NewStandardOutputWriter() *WindowsWriter {
+ return &WindowsWriter{
+ out: colorable.NewColorableStdout(),
+ }
+}