forked from LaconicNetwork/kompose
Merge pull request #48 from kadel/fix-win-build
Fix failing windows build
This commit is contained in:
commit
713aadff8f
13
Godeps/Godeps.json
generated
13
Godeps/Godeps.json
generated
@ -8,11 +8,11 @@
|
|||||||
"Deps": [
|
"Deps": [
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/Azure/go-ansiterm",
|
"ImportPath": "github.com/Azure/go-ansiterm",
|
||||||
"Rev": "70b2c90b260171e829f1ebd7c17f600c11858dbe"
|
"Rev": "388960b655244e76e24c75f48631564eaefade62"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/Azure/go-ansiterm/winterm",
|
"ImportPath": "github.com/Azure/go-ansiterm/winterm",
|
||||||
"Rev": "70b2c90b260171e829f1ebd7c17f600c11858dbe"
|
"Rev": "388960b655244e76e24c75f48631564eaefade62"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/Microsoft/go-winio",
|
"ImportPath": "github.com/Microsoft/go-winio",
|
||||||
@ -407,11 +407,6 @@
|
|||||||
"Comment": "v0.1.0-21-g0bbddae",
|
"Comment": "v0.1.0-21-g0bbddae",
|
||||||
"Rev": "0bbddae09c5a5419a8c6dcdd7ff90da3d450393b"
|
"Rev": "0bbddae09c5a5419a8c6dcdd7ff90da3d450393b"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "github.com/docker/libcompose/cli/logger",
|
|
||||||
"Comment": "v0.2.0-186-ga12288b",
|
|
||||||
"Rev": "a12288bd636066e330b5d39197737cd04882d164"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/libcompose/config",
|
"ImportPath": "github.com/docker/libcompose/config",
|
||||||
"Comment": "v0.2.0-186-ga12288b",
|
"Comment": "v0.2.0-186-ga12288b",
|
||||||
@ -588,10 +583,6 @@
|
|||||||
"ImportPath": "github.com/xeipuuv/gojsonschema",
|
"ImportPath": "github.com/xeipuuv/gojsonschema",
|
||||||
"Rev": "ac452913faa25c08bb78810d3e6f88b8a39f8f25"
|
"Rev": "ac452913faa25c08bb78810d3e6f88b8a39f8f25"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/crypto/ssh/terminal",
|
|
||||||
"Rev": "c84e1f8e3a7e322d497cd16c0e8a13c7e127baf3"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/net/context",
|
"ImportPath": "golang.org/x/net/context",
|
||||||
"Rev": "62685c2d7ca23c807425dca88b11a3e2323dab41"
|
"Rev": "62685c2d7ca23c807425dca88b11a3e2323dab41"
|
||||||
|
|||||||
@ -19,5 +19,6 @@ rm -f kompose*
|
|||||||
# Build binaries
|
# Build binaries
|
||||||
gox "${OS_PLATFORM_ARG[@]}" "${OS_ARCH_ARG[@]}" \
|
gox "${OS_PLATFORM_ARG[@]}" "${OS_ARCH_ARG[@]}" \
|
||||||
-output="bundles/kompose_{{.OS}}-{{.Arch}}/kompose" \
|
-output="bundles/kompose_{{.OS}}-{{.Arch}}/kompose" \
|
||||||
|
-tags experimental \
|
||||||
./cli/main
|
./cli/main
|
||||||
|
|
||||||
|
|||||||
22
vendor/github.com/Azure/go-ansiterm/constants.go
generated
vendored
22
vendor/github.com/Azure/go-ansiterm/constants.go
generated
vendored
@ -124,32 +124,32 @@ func getByteRange(start byte, end byte) []byte {
|
|||||||
return bytes
|
return bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
var ToGroundBytes = getToGroundBytes()
|
var toGroundBytes = getToGroundBytes()
|
||||||
var Executors = getExecuteBytes()
|
var executors = getExecuteBytes()
|
||||||
|
|
||||||
// SPACE 20+A0 hex Always and everywhere a blank space
|
// SPACE 20+A0 hex Always and everywhere a blank space
|
||||||
// Intermediate 20-2F hex !"#$%&'()*+,-./
|
// Intermediate 20-2F hex !"#$%&'()*+,-./
|
||||||
var Intermeds = getByteRange(0x20, 0x2F)
|
var intermeds = getByteRange(0x20, 0x2F)
|
||||||
|
|
||||||
// Parameters 30-3F hex 0123456789:;<=>?
|
// Parameters 30-3F hex 0123456789:;<=>?
|
||||||
// CSI Parameters 30-39, 3B hex 0123456789;
|
// CSI Parameters 30-39, 3B hex 0123456789;
|
||||||
var CsiParams = getByteRange(0x30, 0x3F)
|
var csiParams = getByteRange(0x30, 0x3F)
|
||||||
|
|
||||||
var CsiCollectables = append(getByteRange(0x30, 0x39), getByteRange(0x3B, 0x3F)...)
|
var csiCollectables = append(getByteRange(0x30, 0x39), getByteRange(0x3B, 0x3F)...)
|
||||||
|
|
||||||
// Uppercase 40-5F hex @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
|
// Uppercase 40-5F hex @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
|
||||||
var UpperCase = getByteRange(0x40, 0x5F)
|
var upperCase = getByteRange(0x40, 0x5F)
|
||||||
|
|
||||||
// Lowercase 60-7E hex `abcdefghijlkmnopqrstuvwxyz{|}~
|
// Lowercase 60-7E hex `abcdefghijlkmnopqrstuvwxyz{|}~
|
||||||
var LowerCase = getByteRange(0x60, 0x7E)
|
var lowerCase = getByteRange(0x60, 0x7E)
|
||||||
|
|
||||||
// Alphabetics 40-7E hex (all of upper and lower case)
|
// Alphabetics 40-7E hex (all of upper and lower case)
|
||||||
var Alphabetics = append(UpperCase, LowerCase...)
|
var alphabetics = append(upperCase, lowerCase...)
|
||||||
|
|
||||||
var Printables = getByteRange(0x20, 0x7F)
|
var printables = getByteRange(0x20, 0x7F)
|
||||||
|
|
||||||
var EscapeIntermediateToGroundBytes = getByteRange(0x30, 0x7E)
|
var escapeIntermediateToGroundBytes = getByteRange(0x30, 0x7E)
|
||||||
var EscapeToGroundBytes = getEscapeToGroundBytes()
|
var escapeToGroundBytes = getEscapeToGroundBytes()
|
||||||
|
|
||||||
// See http://www.vt100.net/emu/vt500_parser.png for description of the complex
|
// See http://www.vt100.net/emu/vt500_parser.png for description of the complex
|
||||||
// byte ranges below
|
// byte ranges below
|
||||||
|
|||||||
2
vendor/github.com/Azure/go-ansiterm/context.go
generated
vendored
2
vendor/github.com/Azure/go-ansiterm/context.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
package ansiterm
|
package ansiterm
|
||||||
|
|
||||||
type AnsiContext struct {
|
type ansiContext struct {
|
||||||
currentChar byte
|
currentChar byte
|
||||||
paramBuffer []byte
|
paramBuffer []byte
|
||||||
interBuffer []byte
|
interBuffer []byte
|
||||||
|
|||||||
32
vendor/github.com/Azure/go-ansiterm/csi_entry_state.go
generated
vendored
32
vendor/github.com/Azure/go-ansiterm/csi_entry_state.go
generated
vendored
@ -1,41 +1,41 @@
|
|||||||
package ansiterm
|
package ansiterm
|
||||||
|
|
||||||
type CsiEntryState struct {
|
type csiEntryState struct {
|
||||||
BaseState
|
baseState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (csiState CsiEntryState) Handle(b byte) (s State, e error) {
|
func (csiState csiEntryState) Handle(b byte) (s state, e error) {
|
||||||
logger.Infof("CsiEntry::Handle %#x", b)
|
logger.Infof("CsiEntry::Handle %#x", b)
|
||||||
|
|
||||||
nextState, err := csiState.BaseState.Handle(b)
|
nextState, err := csiState.baseState.Handle(b)
|
||||||
if nextState != nil || err != nil {
|
if nextState != nil || err != nil {
|
||||||
return nextState, err
|
return nextState, err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case sliceContains(Alphabetics, b):
|
case sliceContains(alphabetics, b):
|
||||||
return csiState.parser.Ground, nil
|
return csiState.parser.ground, nil
|
||||||
case sliceContains(CsiCollectables, b):
|
case sliceContains(csiCollectables, b):
|
||||||
return csiState.parser.CsiParam, nil
|
return csiState.parser.csiParam, nil
|
||||||
case sliceContains(Executors, b):
|
case sliceContains(executors, b):
|
||||||
return csiState, csiState.parser.execute()
|
return csiState, csiState.parser.execute()
|
||||||
}
|
}
|
||||||
|
|
||||||
return csiState, nil
|
return csiState, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (csiState CsiEntryState) Transition(s State) error {
|
func (csiState csiEntryState) Transition(s state) error {
|
||||||
logger.Infof("CsiEntry::Transition %s --> %s", csiState.Name(), s.Name())
|
logger.Infof("CsiEntry::Transition %s --> %s", csiState.Name(), s.Name())
|
||||||
csiState.BaseState.Transition(s)
|
csiState.baseState.Transition(s)
|
||||||
|
|
||||||
switch s {
|
switch s {
|
||||||
case csiState.parser.Ground:
|
case csiState.parser.ground:
|
||||||
return csiState.parser.csiDispatch()
|
return csiState.parser.csiDispatch()
|
||||||
case csiState.parser.CsiParam:
|
case csiState.parser.csiParam:
|
||||||
switch {
|
switch {
|
||||||
case sliceContains(CsiParams, csiState.parser.context.currentChar):
|
case sliceContains(csiParams, csiState.parser.context.currentChar):
|
||||||
csiState.parser.collectParam()
|
csiState.parser.collectParam()
|
||||||
case sliceContains(Intermeds, csiState.parser.context.currentChar):
|
case sliceContains(intermeds, csiState.parser.context.currentChar):
|
||||||
csiState.parser.collectInter()
|
csiState.parser.collectInter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@ func (csiState CsiEntryState) Transition(s State) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (csiState CsiEntryState) Enter() error {
|
func (csiState csiEntryState) Enter() error {
|
||||||
csiState.parser.clear()
|
csiState.parser.clear()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
22
vendor/github.com/Azure/go-ansiterm/csi_param_state.go
generated
vendored
22
vendor/github.com/Azure/go-ansiterm/csi_param_state.go
generated
vendored
@ -1,36 +1,36 @@
|
|||||||
package ansiterm
|
package ansiterm
|
||||||
|
|
||||||
type CsiParamState struct {
|
type csiParamState struct {
|
||||||
BaseState
|
baseState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (csiState CsiParamState) Handle(b byte) (s State, e error) {
|
func (csiState csiParamState) Handle(b byte) (s state, e error) {
|
||||||
logger.Infof("CsiParam::Handle %#x", b)
|
logger.Infof("CsiParam::Handle %#x", b)
|
||||||
|
|
||||||
nextState, err := csiState.BaseState.Handle(b)
|
nextState, err := csiState.baseState.Handle(b)
|
||||||
if nextState != nil || err != nil {
|
if nextState != nil || err != nil {
|
||||||
return nextState, err
|
return nextState, err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case sliceContains(Alphabetics, b):
|
case sliceContains(alphabetics, b):
|
||||||
return csiState.parser.Ground, nil
|
return csiState.parser.ground, nil
|
||||||
case sliceContains(CsiCollectables, b):
|
case sliceContains(csiCollectables, b):
|
||||||
csiState.parser.collectParam()
|
csiState.parser.collectParam()
|
||||||
return csiState, nil
|
return csiState, nil
|
||||||
case sliceContains(Executors, b):
|
case sliceContains(executors, b):
|
||||||
return csiState, csiState.parser.execute()
|
return csiState, csiState.parser.execute()
|
||||||
}
|
}
|
||||||
|
|
||||||
return csiState, nil
|
return csiState, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (csiState CsiParamState) Transition(s State) error {
|
func (csiState csiParamState) Transition(s state) error {
|
||||||
logger.Infof("CsiParam::Transition %s --> %s", csiState.Name(), s.Name())
|
logger.Infof("CsiParam::Transition %s --> %s", csiState.Name(), s.Name())
|
||||||
csiState.BaseState.Transition(s)
|
csiState.baseState.Transition(s)
|
||||||
|
|
||||||
switch s {
|
switch s {
|
||||||
case csiState.parser.Ground:
|
case csiState.parser.ground:
|
||||||
return csiState.parser.csiDispatch()
|
return csiState.parser.csiDispatch()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
26
vendor/github.com/Azure/go-ansiterm/escape_intermediate_state.go
generated
vendored
26
vendor/github.com/Azure/go-ansiterm/escape_intermediate_state.go
generated
vendored
@ -1,34 +1,34 @@
|
|||||||
package ansiterm
|
package ansiterm
|
||||||
|
|
||||||
type EscapeIntermediateState struct {
|
type escapeIntermediateState struct {
|
||||||
BaseState
|
baseState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (escState EscapeIntermediateState) Handle(b byte) (s State, e error) {
|
func (escState escapeIntermediateState) Handle(b byte) (s state, e error) {
|
||||||
logger.Infof("EscapeIntermediateState::Handle %#x", b)
|
logger.Infof("escapeIntermediateState::Handle %#x", b)
|
||||||
nextState, err := escState.BaseState.Handle(b)
|
nextState, err := escState.baseState.Handle(b)
|
||||||
if nextState != nil || err != nil {
|
if nextState != nil || err != nil {
|
||||||
return nextState, err
|
return nextState, err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case sliceContains(Intermeds, b):
|
case sliceContains(intermeds, b):
|
||||||
return escState, escState.parser.collectInter()
|
return escState, escState.parser.collectInter()
|
||||||
case sliceContains(Executors, b):
|
case sliceContains(executors, b):
|
||||||
return escState, escState.parser.execute()
|
return escState, escState.parser.execute()
|
||||||
case sliceContains(EscapeIntermediateToGroundBytes, b):
|
case sliceContains(escapeIntermediateToGroundBytes, b):
|
||||||
return escState.parser.Ground, nil
|
return escState.parser.ground, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return escState, nil
|
return escState, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (escState EscapeIntermediateState) Transition(s State) error {
|
func (escState escapeIntermediateState) Transition(s state) error {
|
||||||
logger.Infof("EscapeIntermediateState::Transition %s --> %s", escState.Name(), s.Name())
|
logger.Infof("escapeIntermediateState::Transition %s --> %s", escState.Name(), s.Name())
|
||||||
escState.BaseState.Transition(s)
|
escState.baseState.Transition(s)
|
||||||
|
|
||||||
switch s {
|
switch s {
|
||||||
case escState.parser.Ground:
|
case escState.parser.ground:
|
||||||
return escState.parser.escDispatch()
|
return escState.parser.escDispatch()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
34
vendor/github.com/Azure/go-ansiterm/escape_state.go
generated
vendored
34
vendor/github.com/Azure/go-ansiterm/escape_state.go
generated
vendored
@ -1,47 +1,47 @@
|
|||||||
package ansiterm
|
package ansiterm
|
||||||
|
|
||||||
type EscapeState struct {
|
type escapeState struct {
|
||||||
BaseState
|
baseState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (escState EscapeState) Handle(b byte) (s State, e error) {
|
func (escState escapeState) Handle(b byte) (s state, e error) {
|
||||||
logger.Infof("EscapeState::Handle %#x", b)
|
logger.Infof("escapeState::Handle %#x", b)
|
||||||
nextState, err := escState.BaseState.Handle(b)
|
nextState, err := escState.baseState.Handle(b)
|
||||||
if nextState != nil || err != nil {
|
if nextState != nil || err != nil {
|
||||||
return nextState, err
|
return nextState, err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case b == ANSI_ESCAPE_SECONDARY:
|
case b == ANSI_ESCAPE_SECONDARY:
|
||||||
return escState.parser.CsiEntry, nil
|
return escState.parser.csiEntry, nil
|
||||||
case b == ANSI_OSC_STRING_ENTRY:
|
case b == ANSI_OSC_STRING_ENTRY:
|
||||||
return escState.parser.OscString, nil
|
return escState.parser.oscString, nil
|
||||||
case sliceContains(Executors, b):
|
case sliceContains(executors, b):
|
||||||
return escState, escState.parser.execute()
|
return escState, escState.parser.execute()
|
||||||
case sliceContains(EscapeToGroundBytes, b):
|
case sliceContains(escapeToGroundBytes, b):
|
||||||
return escState.parser.Ground, nil
|
return escState.parser.ground, nil
|
||||||
case sliceContains(Intermeds, b):
|
case sliceContains(intermeds, b):
|
||||||
return escState.parser.EscapeIntermediate, nil
|
return escState.parser.escapeIntermediate, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return escState, nil
|
return escState, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (escState EscapeState) Transition(s State) error {
|
func (escState escapeState) Transition(s state) error {
|
||||||
logger.Infof("Escape::Transition %s --> %s", escState.Name(), s.Name())
|
logger.Infof("Escape::Transition %s --> %s", escState.Name(), s.Name())
|
||||||
escState.BaseState.Transition(s)
|
escState.baseState.Transition(s)
|
||||||
|
|
||||||
switch s {
|
switch s {
|
||||||
case escState.parser.Ground:
|
case escState.parser.ground:
|
||||||
return escState.parser.escDispatch()
|
return escState.parser.escDispatch()
|
||||||
case escState.parser.EscapeIntermediate:
|
case escState.parser.escapeIntermediate:
|
||||||
return escState.parser.collectInter()
|
return escState.parser.collectInter()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (escState EscapeState) Enter() error {
|
func (escState escapeState) Enter() error {
|
||||||
escState.parser.clear()
|
escState.parser.clear()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
12
vendor/github.com/Azure/go-ansiterm/ground_state.go
generated
vendored
12
vendor/github.com/Azure/go-ansiterm/ground_state.go
generated
vendored
@ -1,22 +1,22 @@
|
|||||||
package ansiterm
|
package ansiterm
|
||||||
|
|
||||||
type GroundState struct {
|
type groundState struct {
|
||||||
BaseState
|
baseState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gs GroundState) Handle(b byte) (s State, e error) {
|
func (gs groundState) Handle(b byte) (s state, e error) {
|
||||||
gs.parser.context.currentChar = b
|
gs.parser.context.currentChar = b
|
||||||
|
|
||||||
nextState, err := gs.BaseState.Handle(b)
|
nextState, err := gs.baseState.Handle(b)
|
||||||
if nextState != nil || err != nil {
|
if nextState != nil || err != nil {
|
||||||
return nextState, err
|
return nextState, err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case sliceContains(Printables, b):
|
case sliceContains(printables, b):
|
||||||
return gs, gs.parser.print()
|
return gs, gs.parser.print()
|
||||||
|
|
||||||
case sliceContains(Executors, b):
|
case sliceContains(executors, b):
|
||||||
return gs, gs.parser.execute()
|
return gs, gs.parser.execute()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
10
vendor/github.com/Azure/go-ansiterm/osc_string_state.go
generated
vendored
10
vendor/github.com/Azure/go-ansiterm/osc_string_state.go
generated
vendored
@ -1,19 +1,19 @@
|
|||||||
package ansiterm
|
package ansiterm
|
||||||
|
|
||||||
type OscStringState struct {
|
type oscStringState struct {
|
||||||
BaseState
|
baseState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (oscState OscStringState) Handle(b byte) (s State, e error) {
|
func (oscState oscStringState) Handle(b byte) (s state, e error) {
|
||||||
logger.Infof("OscString::Handle %#x", b)
|
logger.Infof("OscString::Handle %#x", b)
|
||||||
nextState, err := oscState.BaseState.Handle(b)
|
nextState, err := oscState.baseState.Handle(b)
|
||||||
if nextState != nil || err != nil {
|
if nextState != nil || err != nil {
|
||||||
return nextState, err
|
return nextState, err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case isOscStringTerminator(b):
|
case isOscStringTerminator(b):
|
||||||
return oscState.parser.Ground, nil
|
return oscState.parser.ground, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return oscState, nil
|
return oscState, nil
|
||||||
|
|||||||
65
vendor/github.com/Azure/go-ansiterm/parser.go
generated
vendored
65
vendor/github.com/Azure/go-ansiterm/parser.go
generated
vendored
@ -2,7 +2,6 @@ package ansiterm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@ -12,18 +11,18 @@ import (
|
|||||||
var logger *logrus.Logger
|
var logger *logrus.Logger
|
||||||
|
|
||||||
type AnsiParser struct {
|
type AnsiParser struct {
|
||||||
currState State
|
currState state
|
||||||
eventHandler AnsiEventHandler
|
eventHandler AnsiEventHandler
|
||||||
context *AnsiContext
|
context *ansiContext
|
||||||
CsiEntry State
|
csiEntry state
|
||||||
CsiParam State
|
csiParam state
|
||||||
DcsEntry State
|
dcsEntry state
|
||||||
Escape State
|
escape state
|
||||||
EscapeIntermediate State
|
escapeIntermediate state
|
||||||
Error State
|
error state
|
||||||
Ground State
|
ground state
|
||||||
OscString State
|
oscString state
|
||||||
stateMap []State
|
stateMap []state
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateParser(initialState string, evtHandler AnsiEventHandler) *AnsiParser {
|
func CreateParser(initialState string, evtHandler AnsiEventHandler) *AnsiParser {
|
||||||
@ -41,27 +40,27 @@ func CreateParser(initialState string, evtHandler AnsiEventHandler) *AnsiParser
|
|||||||
|
|
||||||
parser := &AnsiParser{
|
parser := &AnsiParser{
|
||||||
eventHandler: evtHandler,
|
eventHandler: evtHandler,
|
||||||
context: &AnsiContext{},
|
context: &ansiContext{},
|
||||||
}
|
}
|
||||||
|
|
||||||
parser.CsiEntry = CsiEntryState{BaseState{name: "CsiEntry", parser: parser}}
|
parser.csiEntry = csiEntryState{baseState{name: "CsiEntry", parser: parser}}
|
||||||
parser.CsiParam = CsiParamState{BaseState{name: "CsiParam", parser: parser}}
|
parser.csiParam = csiParamState{baseState{name: "CsiParam", parser: parser}}
|
||||||
parser.DcsEntry = DcsEntryState{BaseState{name: "DcsEntry", parser: parser}}
|
parser.dcsEntry = dcsEntryState{baseState{name: "DcsEntry", parser: parser}}
|
||||||
parser.Escape = EscapeState{BaseState{name: "Escape", parser: parser}}
|
parser.escape = escapeState{baseState{name: "Escape", parser: parser}}
|
||||||
parser.EscapeIntermediate = EscapeIntermediateState{BaseState{name: "EscapeIntermediate", parser: parser}}
|
parser.escapeIntermediate = escapeIntermediateState{baseState{name: "EscapeIntermediate", parser: parser}}
|
||||||
parser.Error = ErrorState{BaseState{name: "Error", parser: parser}}
|
parser.error = errorState{baseState{name: "Error", parser: parser}}
|
||||||
parser.Ground = GroundState{BaseState{name: "Ground", parser: parser}}
|
parser.ground = groundState{baseState{name: "Ground", parser: parser}}
|
||||||
parser.OscString = OscStringState{BaseState{name: "OscString", parser: parser}}
|
parser.oscString = oscStringState{baseState{name: "OscString", parser: parser}}
|
||||||
|
|
||||||
parser.stateMap = []State{
|
parser.stateMap = []state{
|
||||||
parser.CsiEntry,
|
parser.csiEntry,
|
||||||
parser.CsiParam,
|
parser.csiParam,
|
||||||
parser.DcsEntry,
|
parser.dcsEntry,
|
||||||
parser.Escape,
|
parser.escape,
|
||||||
parser.EscapeIntermediate,
|
parser.escapeIntermediate,
|
||||||
parser.Error,
|
parser.error,
|
||||||
parser.Ground,
|
parser.ground,
|
||||||
parser.OscString,
|
parser.oscString,
|
||||||
}
|
}
|
||||||
|
|
||||||
parser.currState = getState(initialState, parser.stateMap)
|
parser.currState = getState(initialState, parser.stateMap)
|
||||||
@ -70,7 +69,7 @@ func CreateParser(initialState string, evtHandler AnsiEventHandler) *AnsiParser
|
|||||||
return parser
|
return parser
|
||||||
}
|
}
|
||||||
|
|
||||||
func getState(name string, states []State) State {
|
func getState(name string, states []state) state {
|
||||||
for _, el := range states {
|
for _, el := range states {
|
||||||
if el.Name() == name {
|
if el.Name() == name {
|
||||||
return el
|
return el
|
||||||
@ -99,7 +98,7 @@ func (ap *AnsiParser) handle(b byte) error {
|
|||||||
|
|
||||||
if newState == nil {
|
if newState == nil {
|
||||||
logger.Warning("newState is nil")
|
logger.Warning("newState is nil")
|
||||||
return errors.New(fmt.Sprintf("New state of 'nil' is invalid."))
|
return errors.New("New state of 'nil' is invalid.")
|
||||||
}
|
}
|
||||||
|
|
||||||
if newState != ap.currState {
|
if newState != ap.currState {
|
||||||
@ -111,7 +110,7 @@ func (ap *AnsiParser) handle(b byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ap *AnsiParser) changeState(newState State) error {
|
func (ap *AnsiParser) changeState(newState state) error {
|
||||||
logger.Infof("ChangeState %s --> %s", ap.currState.Name(), newState.Name())
|
logger.Infof("ChangeState %s --> %s", ap.currState.Name(), newState.Name())
|
||||||
|
|
||||||
// Exit old state
|
// Exit old state
|
||||||
|
|||||||
2
vendor/github.com/Azure/go-ansiterm/parser_action_helpers.go
generated
vendored
2
vendor/github.com/Azure/go-ansiterm/parser_action_helpers.go
generated
vendored
@ -31,7 +31,7 @@ func parseParams(bytes []byte) ([]string, error) {
|
|||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseCmd(context AnsiContext) (string, error) {
|
func parseCmd(context ansiContext) (string, error) {
|
||||||
return string(context.currentChar), nil
|
return string(context.currentChar), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
vendor/github.com/Azure/go-ansiterm/parser_actions.go
generated
vendored
2
vendor/github.com/Azure/go-ansiterm/parser_actions.go
generated
vendored
@ -113,7 +113,7 @@ func (ap *AnsiParser) print() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ap *AnsiParser) clear() error {
|
func (ap *AnsiParser) clear() error {
|
||||||
ap.context = &AnsiContext{}
|
ap.context = &ansiContext{}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
114
vendor/github.com/Azure/go-ansiterm/parser_test_helpers.go
generated
vendored
114
vendor/github.com/Azure/go-ansiterm/parser_test_helpers.go
generated
vendored
@ -1,114 +0,0 @@
|
|||||||
package ansiterm
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getStateNames() []string {
|
|
||||||
parser, _ := createTestParser("Ground")
|
|
||||||
|
|
||||||
stateNames := []string{}
|
|
||||||
for _, state := range parser.stateMap {
|
|
||||||
stateNames = append(stateNames, state.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
return stateNames
|
|
||||||
}
|
|
||||||
|
|
||||||
func stateTransitionHelper(t *testing.T, start string, end string, bytes []byte) {
|
|
||||||
for _, b := range bytes {
|
|
||||||
bytes := []byte{byte(b)}
|
|
||||||
parser, _ := createTestParser(start)
|
|
||||||
parser.Parse(bytes)
|
|
||||||
validateState(t, parser.currState, end)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func anyToXHelper(t *testing.T, bytes []byte, expectedState string) {
|
|
||||||
for _, s := range getStateNames() {
|
|
||||||
stateTransitionHelper(t, s, expectedState, bytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func funcCallParamHelper(t *testing.T, bytes []byte, start string, expected string, expectedCalls []string) {
|
|
||||||
parser, evtHandler := createTestParser(start)
|
|
||||||
parser.Parse(bytes)
|
|
||||||
validateState(t, parser.currState, expected)
|
|
||||||
validateFuncCalls(t, evtHandler.FunctionCalls, expectedCalls)
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseParamsHelper(t *testing.T, bytes []byte, expectedParams []string) {
|
|
||||||
params, err := parseParams(bytes)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Parameter parse error: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(params) != len(expectedParams) {
|
|
||||||
t.Errorf("Parsed parameters: %v", params)
|
|
||||||
t.Errorf("Expected parameters: %v", expectedParams)
|
|
||||||
t.Errorf("Parameter length failure: %d != %d", len(params), len(expectedParams))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, v := range expectedParams {
|
|
||||||
if v != params[i] {
|
|
||||||
t.Errorf("Parsed parameters: %v", params)
|
|
||||||
t.Errorf("Expected parameters: %v", expectedParams)
|
|
||||||
t.Errorf("Parameter parse failure: %s != %s at position %d", v, params[i], i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func cursorSingleParamHelper(t *testing.T, command byte, funcName string) {
|
|
||||||
funcCallParamHelper(t, []byte{command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'0', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'2', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([2])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'2', '3', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([23])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'2', ';', '3', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([2])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'2', ';', '3', ';', '4', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([2])", funcName)})
|
|
||||||
}
|
|
||||||
|
|
||||||
func cursorTwoParamHelper(t *testing.T, command byte, funcName string) {
|
|
||||||
funcCallParamHelper(t, []byte{command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1 1])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'0', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1 1])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'2', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([2 1])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'2', '3', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([23 1])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'2', ';', '3', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([2 3])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'2', ';', '3', ';', '4', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([2 3])", funcName)})
|
|
||||||
}
|
|
||||||
|
|
||||||
func eraseHelper(t *testing.T, command byte, funcName string) {
|
|
||||||
funcCallParamHelper(t, []byte{command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([0])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'0', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([0])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'1', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'2', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([2])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'3', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([3])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'4', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([0])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'1', ';', '2', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1])", funcName)})
|
|
||||||
}
|
|
||||||
|
|
||||||
func scrollHelper(t *testing.T, command byte, funcName string) {
|
|
||||||
funcCallParamHelper(t, []byte{command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'0', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'1', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'5', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([5])", funcName)})
|
|
||||||
funcCallParamHelper(t, []byte{'4', ';', '6', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([4])", funcName)})
|
|
||||||
}
|
|
||||||
|
|
||||||
func clearOnStateChangeHelper(t *testing.T, start string, end string, bytes []byte) {
|
|
||||||
p, _ := createTestParser(start)
|
|
||||||
fillContext(p.context)
|
|
||||||
p.Parse(bytes)
|
|
||||||
validateState(t, p.currState, end)
|
|
||||||
validateEmptyContext(t, p.context)
|
|
||||||
}
|
|
||||||
|
|
||||||
func c0Helper(t *testing.T, bytes []byte, expectedState string, expectedCalls []string) {
|
|
||||||
parser, evtHandler := createTestParser("Ground")
|
|
||||||
parser.Parse(bytes)
|
|
||||||
validateState(t, parser.currState, expectedState)
|
|
||||||
validateFuncCalls(t, evtHandler.FunctionCalls, expectedCalls)
|
|
||||||
}
|
|
||||||
66
vendor/github.com/Azure/go-ansiterm/parser_test_utilities.go
generated
vendored
66
vendor/github.com/Azure/go-ansiterm/parser_test_utilities.go
generated
vendored
@ -1,66 +0,0 @@
|
|||||||
package ansiterm
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func createTestParser(s string) (*AnsiParser, *TestAnsiEventHandler) {
|
|
||||||
evtHandler := CreateTestAnsiEventHandler()
|
|
||||||
parser := CreateParser(s, evtHandler)
|
|
||||||
|
|
||||||
return parser, evtHandler
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateState(t *testing.T, actualState State, expectedStateName string) {
|
|
||||||
actualName := "Nil"
|
|
||||||
|
|
||||||
if actualState != nil {
|
|
||||||
actualName = actualState.Name()
|
|
||||||
}
|
|
||||||
|
|
||||||
if actualName != expectedStateName {
|
|
||||||
t.Errorf("Invalid State: '%s' != '%s'", actualName, expectedStateName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateFuncCalls(t *testing.T, actualCalls []string, expectedCalls []string) {
|
|
||||||
actualCount := len(actualCalls)
|
|
||||||
expectedCount := len(expectedCalls)
|
|
||||||
|
|
||||||
if actualCount != expectedCount {
|
|
||||||
t.Errorf("Actual calls: %v", actualCalls)
|
|
||||||
t.Errorf("Expected calls: %v", expectedCalls)
|
|
||||||
t.Errorf("Call count error: %d != %d", actualCount, expectedCount)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, v := range actualCalls {
|
|
||||||
if v != expectedCalls[i] {
|
|
||||||
t.Errorf("Actual calls: %v", actualCalls)
|
|
||||||
t.Errorf("Expected calls: %v", expectedCalls)
|
|
||||||
t.Errorf("Mismatched calls: %s != %s with lengths %d and %d", v, expectedCalls[i], len(v), len(expectedCalls[i]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func fillContext(context *AnsiContext) {
|
|
||||||
context.currentChar = 'A'
|
|
||||||
context.paramBuffer = []byte{'C', 'D', 'E'}
|
|
||||||
context.interBuffer = []byte{'F', 'G', 'H'}
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateEmptyContext(t *testing.T, context *AnsiContext) {
|
|
||||||
var expectedCurrChar byte = 0x0
|
|
||||||
if context.currentChar != expectedCurrChar {
|
|
||||||
t.Errorf("Currentchar mismatch '%#x' != '%#x'", context.currentChar, expectedCurrChar)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(context.paramBuffer) != 0 {
|
|
||||||
t.Errorf("Non-empty parameter buffer: %v", context.paramBuffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(context.paramBuffer) != 0 {
|
|
||||||
t.Errorf("Non-empty intermediate buffer: %v", context.interBuffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
42
vendor/github.com/Azure/go-ansiterm/states.go
generated
vendored
42
vendor/github.com/Azure/go-ansiterm/states.go
generated
vendored
@ -1,52 +1,52 @@
|
|||||||
package ansiterm
|
package ansiterm
|
||||||
|
|
||||||
type StateId int
|
type stateID int
|
||||||
|
|
||||||
type State interface {
|
type state interface {
|
||||||
Enter() error
|
Enter() error
|
||||||
Exit() error
|
Exit() error
|
||||||
Handle(byte) (State, error)
|
Handle(byte) (state, error)
|
||||||
Name() string
|
Name() string
|
||||||
Transition(State) error
|
Transition(state) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type BaseState struct {
|
type baseState struct {
|
||||||
name string
|
name string
|
||||||
parser *AnsiParser
|
parser *AnsiParser
|
||||||
}
|
}
|
||||||
|
|
||||||
func (base BaseState) Enter() error {
|
func (base baseState) Enter() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (base BaseState) Exit() error {
|
func (base baseState) Exit() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (base BaseState) Handle(b byte) (s State, e error) {
|
func (base baseState) Handle(b byte) (s state, e error) {
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case b == CSI_ENTRY:
|
case b == CSI_ENTRY:
|
||||||
return base.parser.CsiEntry, nil
|
return base.parser.csiEntry, nil
|
||||||
case b == DCS_ENTRY:
|
case b == DCS_ENTRY:
|
||||||
return base.parser.DcsEntry, nil
|
return base.parser.dcsEntry, nil
|
||||||
case b == ANSI_ESCAPE_PRIMARY:
|
case b == ANSI_ESCAPE_PRIMARY:
|
||||||
return base.parser.Escape, nil
|
return base.parser.escape, nil
|
||||||
case b == OSC_STRING:
|
case b == OSC_STRING:
|
||||||
return base.parser.OscString, nil
|
return base.parser.oscString, nil
|
||||||
case sliceContains(ToGroundBytes, b):
|
case sliceContains(toGroundBytes, b):
|
||||||
return base.parser.Ground, nil
|
return base.parser.ground, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (base BaseState) Name() string {
|
func (base baseState) Name() string {
|
||||||
return base.name
|
return base.name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (base BaseState) Transition(s State) error {
|
func (base baseState) Transition(s state) error {
|
||||||
if s == base.parser.Ground {
|
if s == base.parser.ground {
|
||||||
execBytes := []byte{0x18}
|
execBytes := []byte{0x18}
|
||||||
execBytes = append(execBytes, 0x1A)
|
execBytes = append(execBytes, 0x1A)
|
||||||
execBytes = append(execBytes, getByteRange(0x80, 0x8F)...)
|
execBytes = append(execBytes, getByteRange(0x80, 0x8F)...)
|
||||||
@ -62,10 +62,10 @@ func (base BaseState) Transition(s State) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type DcsEntryState struct {
|
type dcsEntryState struct {
|
||||||
BaseState
|
baseState
|
||||||
}
|
}
|
||||||
|
|
||||||
type ErrorState struct {
|
type errorState struct {
|
||||||
BaseState
|
baseState
|
||||||
}
|
}
|
||||||
|
|||||||
173
vendor/github.com/Azure/go-ansiterm/test_event_handler.go
generated
vendored
173
vendor/github.com/Azure/go-ansiterm/test_event_handler.go
generated
vendored
@ -1,173 +0,0 @@
|
|||||||
package ansiterm
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TestAnsiEventHandler struct {
|
|
||||||
FunctionCalls []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateTestAnsiEventHandler() *TestAnsiEventHandler {
|
|
||||||
evtHandler := TestAnsiEventHandler{}
|
|
||||||
evtHandler.FunctionCalls = make([]string, 0)
|
|
||||||
return &evtHandler
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) recordCall(call string, params []string) {
|
|
||||||
s := fmt.Sprintf("%s(%v)", call, params)
|
|
||||||
h.FunctionCalls = append(h.FunctionCalls, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) Print(b byte) error {
|
|
||||||
h.recordCall("Print", []string{string(b)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) Execute(b byte) error {
|
|
||||||
h.recordCall("Execute", []string{string(b)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) CUU(param int) error {
|
|
||||||
h.recordCall("CUU", []string{strconv.Itoa(param)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) CUD(param int) error {
|
|
||||||
h.recordCall("CUD", []string{strconv.Itoa(param)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) CUF(param int) error {
|
|
||||||
h.recordCall("CUF", []string{strconv.Itoa(param)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) CUB(param int) error {
|
|
||||||
h.recordCall("CUB", []string{strconv.Itoa(param)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) CNL(param int) error {
|
|
||||||
h.recordCall("CNL", []string{strconv.Itoa(param)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) CPL(param int) error {
|
|
||||||
h.recordCall("CPL", []string{strconv.Itoa(param)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) CHA(param int) error {
|
|
||||||
h.recordCall("CHA", []string{strconv.Itoa(param)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) VPA(param int) error {
|
|
||||||
h.recordCall("VPA", []string{strconv.Itoa(param)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) CUP(x int, y int) error {
|
|
||||||
xS, yS := strconv.Itoa(x), strconv.Itoa(y)
|
|
||||||
h.recordCall("CUP", []string{xS, yS})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) HVP(x int, y int) error {
|
|
||||||
xS, yS := strconv.Itoa(x), strconv.Itoa(y)
|
|
||||||
h.recordCall("HVP", []string{xS, yS})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) DECTCEM(visible bool) error {
|
|
||||||
h.recordCall("DECTCEM", []string{strconv.FormatBool(visible)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) DECOM(visible bool) error {
|
|
||||||
h.recordCall("DECOM", []string{strconv.FormatBool(visible)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) DECCOLM(use132 bool) error {
|
|
||||||
h.recordCall("DECOLM", []string{strconv.FormatBool(use132)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) ED(param int) error {
|
|
||||||
h.recordCall("ED", []string{strconv.Itoa(param)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) EL(param int) error {
|
|
||||||
h.recordCall("EL", []string{strconv.Itoa(param)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) IL(param int) error {
|
|
||||||
h.recordCall("IL", []string{strconv.Itoa(param)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) DL(param int) error {
|
|
||||||
h.recordCall("DL", []string{strconv.Itoa(param)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) ICH(param int) error {
|
|
||||||
h.recordCall("ICH", []string{strconv.Itoa(param)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) DCH(param int) error {
|
|
||||||
h.recordCall("DCH", []string{strconv.Itoa(param)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) SGR(params []int) error {
|
|
||||||
strings := []string{}
|
|
||||||
for _, v := range params {
|
|
||||||
strings = append(strings, strconv.Itoa(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
h.recordCall("SGR", strings)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) SU(param int) error {
|
|
||||||
h.recordCall("SU", []string{strconv.Itoa(param)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) SD(param int) error {
|
|
||||||
h.recordCall("SD", []string{strconv.Itoa(param)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) DA(params []string) error {
|
|
||||||
h.recordCall("DA", params)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) DECSTBM(top int, bottom int) error {
|
|
||||||
topS, bottomS := strconv.Itoa(top), strconv.Itoa(bottom)
|
|
||||||
h.recordCall("DECSTBM", []string{topS, bottomS})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) RI() error {
|
|
||||||
h.recordCall("RI", nil)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) IND() error {
|
|
||||||
h.recordCall("IND", nil)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *TestAnsiEventHandler) Flush() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
22
vendor/github.com/Azure/go-ansiterm/winterm/ansi.go
generated
vendored
22
vendor/github.com/Azure/go-ansiterm/winterm/ansi.go
generated
vendored
@ -9,7 +9,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
. "github.com/Azure/go-ansiterm"
|
"github.com/Azure/go-ansiterm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Windows keyboard constants
|
// Windows keyboard constants
|
||||||
@ -85,17 +85,17 @@ func newAnsiCommand(command []byte) *ansiCommand {
|
|||||||
if lastCharIndex != 0 {
|
if lastCharIndex != 0 {
|
||||||
start := 1
|
start := 1
|
||||||
// skip if double char escape sequence
|
// skip if double char escape sequence
|
||||||
if command[0] == ANSI_ESCAPE_PRIMARY && command[1] == ANSI_ESCAPE_SECONDARY {
|
if command[0] == ansiterm.ANSI_ESCAPE_PRIMARY && command[1] == ansiterm.ANSI_ESCAPE_SECONDARY {
|
||||||
start++
|
start++
|
||||||
}
|
}
|
||||||
// convert this to GetNextParam method
|
// convert this to GetNextParam method
|
||||||
ac.Parameters = strings.Split(string(command[start:lastCharIndex]), ANSI_PARAMETER_SEP)
|
ac.Parameters = strings.Split(string(command[start:lastCharIndex]), ansiterm.ANSI_PARAMETER_SEP)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ac
|
return ac
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ac *ansiCommand) paramAsSHORT(index int, defaultValue SHORT) SHORT {
|
func (ac *ansiCommand) paramAsSHORT(index int, defaultValue int16) int16 {
|
||||||
if index < 0 || index >= len(ac.Parameters) {
|
if index < 0 || index >= len(ac.Parameters) {
|
||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
@ -105,7 +105,7 @@ func (ac *ansiCommand) paramAsSHORT(index int, defaultValue SHORT) SHORT {
|
|||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
return SHORT(param)
|
return int16(param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ac *ansiCommand) String() string {
|
func (ac *ansiCommand) String() string {
|
||||||
@ -119,12 +119,12 @@ func (ac *ansiCommand) String() string {
|
|||||||
// See http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html.
|
// See http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html.
|
||||||
func isAnsiCommandChar(b byte) bool {
|
func isAnsiCommandChar(b byte) bool {
|
||||||
switch {
|
switch {
|
||||||
case ANSI_COMMAND_FIRST <= b && b <= ANSI_COMMAND_LAST && b != ANSI_ESCAPE_SECONDARY:
|
case ansiterm.ANSI_COMMAND_FIRST <= b && b <= ansiterm.ANSI_COMMAND_LAST && b != ansiterm.ANSI_ESCAPE_SECONDARY:
|
||||||
return true
|
return true
|
||||||
case b == ANSI_CMD_G1 || b == ANSI_CMD_OSC || b == ANSI_CMD_DECPAM || b == ANSI_CMD_DECPNM:
|
case b == ansiterm.ANSI_CMD_G1 || b == ansiterm.ANSI_CMD_OSC || b == ansiterm.ANSI_CMD_DECPAM || b == ansiterm.ANSI_CMD_DECPNM:
|
||||||
// non-CSI escape sequence terminator
|
// non-CSI escape sequence terminator
|
||||||
return true
|
return true
|
||||||
case b == ANSI_CMD_STR_TERM || b == ANSI_BEL:
|
case b == ansiterm.ANSI_CMD_STR_TERM || b == ansiterm.ANSI_BEL:
|
||||||
// String escape sequence terminator
|
// String escape sequence terminator
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -132,11 +132,11 @@ func isAnsiCommandChar(b byte) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func isXtermOscSequence(command []byte, current byte) bool {
|
func isXtermOscSequence(command []byte, current byte) bool {
|
||||||
return (len(command) >= 2 && command[0] == ANSI_ESCAPE_PRIMARY && command[1] == ANSI_CMD_OSC && current != ANSI_BEL)
|
return (len(command) >= 2 && command[0] == ansiterm.ANSI_ESCAPE_PRIMARY && command[1] == ansiterm.ANSI_CMD_OSC && current != ansiterm.ANSI_BEL)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isCharacterSelectionCmdChar(b byte) bool {
|
func isCharacterSelectionCmdChar(b byte) bool {
|
||||||
return (b == ANSI_CMD_G0 || b == ANSI_CMD_G1 || b == ANSI_CMD_G2 || b == ANSI_CMD_G3)
|
return (b == ansiterm.ANSI_CMD_G0 || b == ansiterm.ANSI_CMD_G1 || b == ansiterm.ANSI_CMD_G2 || b == ansiterm.ANSI_CMD_G3)
|
||||||
}
|
}
|
||||||
|
|
||||||
// bytesToHex converts a slice of bytes to a human-readable string.
|
// bytesToHex converts a slice of bytes to a human-readable string.
|
||||||
@ -150,7 +150,7 @@ func bytesToHex(b []byte) string {
|
|||||||
|
|
||||||
// ensureInRange adjusts the passed value, if necessary, to ensure it is within
|
// ensureInRange adjusts the passed value, if necessary, to ensure it is within
|
||||||
// the passed min / max range.
|
// the passed min / max range.
|
||||||
func ensureInRange(n SHORT, min SHORT, max SHORT) SHORT {
|
func ensureInRange(n int16, min int16, max int16) int16 {
|
||||||
if n < min {
|
if n < min {
|
||||||
return min
|
return min
|
||||||
} else if n > max {
|
} else if n > max {
|
||||||
|
|||||||
85
vendor/github.com/Azure/go-ansiterm/winterm/api.go
generated
vendored
85
vendor/github.com/Azure/go-ansiterm/winterm/api.go
generated
vendored
@ -66,21 +66,21 @@ const (
|
|||||||
// -- The attributes are combined to produce various colors (e.g., Blue + Green will create Cyan).
|
// -- The attributes are combined to produce various colors (e.g., Blue + Green will create Cyan).
|
||||||
// Clearing all foreground or background colors results in black; setting all creates white.
|
// Clearing all foreground or background colors results in black; setting all creates white.
|
||||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682088(v=vs.85).aspx#_win32_character_attributes.
|
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682088(v=vs.85).aspx#_win32_character_attributes.
|
||||||
FOREGROUND_BLUE WORD = 0x0001
|
FOREGROUND_BLUE uint16 = 0x0001
|
||||||
FOREGROUND_GREEN WORD = 0x0002
|
FOREGROUND_GREEN uint16 = 0x0002
|
||||||
FOREGROUND_RED WORD = 0x0004
|
FOREGROUND_RED uint16 = 0x0004
|
||||||
FOREGROUND_INTENSITY WORD = 0x0008
|
FOREGROUND_INTENSITY uint16 = 0x0008
|
||||||
FOREGROUND_MASK WORD = 0x000F
|
FOREGROUND_MASK uint16 = 0x000F
|
||||||
|
|
||||||
BACKGROUND_BLUE WORD = 0x0010
|
BACKGROUND_BLUE uint16 = 0x0010
|
||||||
BACKGROUND_GREEN WORD = 0x0020
|
BACKGROUND_GREEN uint16 = 0x0020
|
||||||
BACKGROUND_RED WORD = 0x0040
|
BACKGROUND_RED uint16 = 0x0040
|
||||||
BACKGROUND_INTENSITY WORD = 0x0080
|
BACKGROUND_INTENSITY uint16 = 0x0080
|
||||||
BACKGROUND_MASK WORD = 0x00F0
|
BACKGROUND_MASK uint16 = 0x00F0
|
||||||
|
|
||||||
COMMON_LVB_MASK WORD = 0xFF00
|
COMMON_LVB_MASK uint16 = 0xFF00
|
||||||
COMMON_LVB_REVERSE_VIDEO WORD = 0x4000
|
COMMON_LVB_REVERSE_VIDEO uint16 = 0x4000
|
||||||
COMMON_LVB_UNDERSCORE WORD = 0x8000
|
COMMON_LVB_UNDERSCORE uint16 = 0x8000
|
||||||
|
|
||||||
// Input event types
|
// Input event types
|
||||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx.
|
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx.
|
||||||
@ -104,60 +104,53 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Windows API Console types
|
// Windows API Console types
|
||||||
// -- See https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx for core types (e.g., SHORT)
|
|
||||||
// -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682101(v=vs.85).aspx for Console specific types (e.g., COORD)
|
// -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682101(v=vs.85).aspx for Console specific types (e.g., COORD)
|
||||||
// -- See https://msdn.microsoft.com/en-us/library/aa296569(v=vs.60).aspx for comments on alignment
|
// -- See https://msdn.microsoft.com/en-us/library/aa296569(v=vs.60).aspx for comments on alignment
|
||||||
type (
|
type (
|
||||||
SHORT int16
|
|
||||||
BOOL int32
|
|
||||||
WORD uint16
|
|
||||||
WCHAR uint16
|
|
||||||
DWORD uint32
|
|
||||||
|
|
||||||
CHAR_INFO struct {
|
CHAR_INFO struct {
|
||||||
UnicodeChar WCHAR
|
UnicodeChar uint16
|
||||||
Attributes WORD
|
Attributes uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
CONSOLE_CURSOR_INFO struct {
|
CONSOLE_CURSOR_INFO struct {
|
||||||
Size DWORD
|
Size uint32
|
||||||
Visible BOOL
|
Visible int32
|
||||||
}
|
}
|
||||||
|
|
||||||
CONSOLE_SCREEN_BUFFER_INFO struct {
|
CONSOLE_SCREEN_BUFFER_INFO struct {
|
||||||
Size COORD
|
Size COORD
|
||||||
CursorPosition COORD
|
CursorPosition COORD
|
||||||
Attributes WORD
|
Attributes uint16
|
||||||
Window SMALL_RECT
|
Window SMALL_RECT
|
||||||
MaximumWindowSize COORD
|
MaximumWindowSize COORD
|
||||||
}
|
}
|
||||||
|
|
||||||
COORD struct {
|
COORD struct {
|
||||||
X SHORT
|
X int16
|
||||||
Y SHORT
|
Y int16
|
||||||
}
|
}
|
||||||
|
|
||||||
SMALL_RECT struct {
|
SMALL_RECT struct {
|
||||||
Left SHORT
|
Left int16
|
||||||
Top SHORT
|
Top int16
|
||||||
Right SHORT
|
Right int16
|
||||||
Bottom SHORT
|
Bottom int16
|
||||||
}
|
}
|
||||||
|
|
||||||
// INPUT_RECORD is a C/C++ union of which KEY_EVENT_RECORD is one case, it is also the largest
|
// INPUT_RECORD is a C/C++ union of which KEY_EVENT_RECORD is one case, it is also the largest
|
||||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx.
|
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx.
|
||||||
INPUT_RECORD struct {
|
INPUT_RECORD struct {
|
||||||
EventType WORD
|
EventType uint16
|
||||||
KeyEvent KEY_EVENT_RECORD
|
KeyEvent KEY_EVENT_RECORD
|
||||||
}
|
}
|
||||||
|
|
||||||
KEY_EVENT_RECORD struct {
|
KEY_EVENT_RECORD struct {
|
||||||
KeyDown BOOL
|
KeyDown int32
|
||||||
RepeatCount WORD
|
RepeatCount uint16
|
||||||
VirtualKeyCode WORD
|
VirtualKeyCode uint16
|
||||||
VirtualScanCode WORD
|
VirtualScanCode uint16
|
||||||
UnicodeChar WCHAR
|
UnicodeChar uint16
|
||||||
ControlKeyState DWORD
|
ControlKeyState uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
WINDOW_BUFFER_SIZE struct {
|
WINDOW_BUFFER_SIZE struct {
|
||||||
@ -165,12 +158,12 @@ type (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// boolToBOOL converts a Go bool into a Windows BOOL.
|
// boolToBOOL converts a Go bool into a Windows int32.
|
||||||
func boolToBOOL(f bool) BOOL {
|
func boolToBOOL(f bool) int32 {
|
||||||
if f {
|
if f {
|
||||||
return BOOL(1)
|
return int32(1)
|
||||||
} else {
|
} else {
|
||||||
return BOOL(0)
|
return int32(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +235,7 @@ func SetConsoleScreenBufferSize(handle uintptr, coord COORD) error {
|
|||||||
// SetConsoleTextAttribute sets the attributes of characters written to the
|
// SetConsoleTextAttribute sets the attributes of characters written to the
|
||||||
// console screen buffer by the WriteFile or WriteConsole function.
|
// console screen buffer by the WriteFile or WriteConsole function.
|
||||||
// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047(v=vs.85).aspx.
|
// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047(v=vs.85).aspx.
|
||||||
func SetConsoleTextAttribute(handle uintptr, attribute WORD) error {
|
func SetConsoleTextAttribute(handle uintptr, attribute uint16) error {
|
||||||
r1, r2, err := setConsoleTextAttributeProc.Call(handle, uintptr(attribute), 0)
|
r1, r2, err := setConsoleTextAttributeProc.Call(handle, uintptr(attribute), 0)
|
||||||
use(attribute)
|
use(attribute)
|
||||||
return checkError(r1, r2, err)
|
return checkError(r1, r2, err)
|
||||||
@ -280,7 +273,7 @@ func ReadConsoleInput(handle uintptr, buffer []INPUT_RECORD, count *uint32) erro
|
|||||||
// It returns true if the handle was signaled; false otherwise.
|
// It returns true if the handle was signaled; false otherwise.
|
||||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx.
|
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx.
|
||||||
func WaitForSingleObject(handle uintptr, msWait uint32) (bool, error) {
|
func WaitForSingleObject(handle uintptr, msWait uint32) (bool, error) {
|
||||||
r1, _, err := waitForSingleObjectProc.Call(handle, uintptr(DWORD(msWait)))
|
r1, _, err := waitForSingleObjectProc.Call(handle, uintptr(uint32(msWait)))
|
||||||
switch r1 {
|
switch r1 {
|
||||||
case WAIT_ABANDONED, WAIT_TIMEOUT:
|
case WAIT_ABANDONED, WAIT_TIMEOUT:
|
||||||
return false, nil
|
return false, nil
|
||||||
@ -320,8 +313,8 @@ func checkError(r1, r2 uintptr, err error) error {
|
|||||||
|
|
||||||
// coordToPointer converts a COORD into a uintptr (by fooling the type system).
|
// coordToPointer converts a COORD into a uintptr (by fooling the type system).
|
||||||
func coordToPointer(c COORD) uintptr {
|
func coordToPointer(c COORD) uintptr {
|
||||||
// Note: This code assumes the two SHORTs are correctly laid out; the "cast" to DWORD is just to get a pointer to pass.
|
// Note: This code assumes the two SHORTs are correctly laid out; the "cast" to uint32 is just to get a pointer to pass.
|
||||||
return uintptr(*((*DWORD)(unsafe.Pointer(&c))))
|
return uintptr(*((*uint32)(unsafe.Pointer(&c))))
|
||||||
}
|
}
|
||||||
|
|
||||||
// use is a no-op, but the compiler cannot see that it is.
|
// use is a no-op, but the compiler cannot see that it is.
|
||||||
|
|||||||
56
vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go
generated
vendored
56
vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go
generated
vendored
@ -2,9 +2,7 @@
|
|||||||
|
|
||||||
package winterm
|
package winterm
|
||||||
|
|
||||||
import (
|
import "github.com/Azure/go-ansiterm"
|
||||||
. "github.com/Azure/go-ansiterm"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
FOREGROUND_COLOR_MASK = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
|
FOREGROUND_COLOR_MASK = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
|
||||||
@ -13,83 +11,83 @@ const (
|
|||||||
|
|
||||||
// collectAnsiIntoWindowsAttributes modifies the passed Windows text mode flags to reflect the
|
// collectAnsiIntoWindowsAttributes modifies the passed Windows text mode flags to reflect the
|
||||||
// request represented by the passed ANSI mode.
|
// request represented by the passed ANSI mode.
|
||||||
func collectAnsiIntoWindowsAttributes(windowsMode WORD, inverted bool, baseMode WORD, ansiMode SHORT) (WORD, bool) {
|
func collectAnsiIntoWindowsAttributes(windowsMode uint16, inverted bool, baseMode uint16, ansiMode int16) (uint16, bool) {
|
||||||
switch ansiMode {
|
switch ansiMode {
|
||||||
|
|
||||||
// Mode styles
|
// Mode styles
|
||||||
case ANSI_SGR_BOLD:
|
case ansiterm.ANSI_SGR_BOLD:
|
||||||
windowsMode = windowsMode | FOREGROUND_INTENSITY
|
windowsMode = windowsMode | FOREGROUND_INTENSITY
|
||||||
|
|
||||||
case ANSI_SGR_DIM, ANSI_SGR_BOLD_DIM_OFF:
|
case ansiterm.ANSI_SGR_DIM, ansiterm.ANSI_SGR_BOLD_DIM_OFF:
|
||||||
windowsMode &^= FOREGROUND_INTENSITY
|
windowsMode &^= FOREGROUND_INTENSITY
|
||||||
|
|
||||||
case ANSI_SGR_UNDERLINE:
|
case ansiterm.ANSI_SGR_UNDERLINE:
|
||||||
windowsMode = windowsMode | COMMON_LVB_UNDERSCORE
|
windowsMode = windowsMode | COMMON_LVB_UNDERSCORE
|
||||||
|
|
||||||
case ANSI_SGR_REVERSE:
|
case ansiterm.ANSI_SGR_REVERSE:
|
||||||
inverted = true
|
inverted = true
|
||||||
|
|
||||||
case ANSI_SGR_REVERSE_OFF:
|
case ansiterm.ANSI_SGR_REVERSE_OFF:
|
||||||
inverted = false
|
inverted = false
|
||||||
|
|
||||||
case ANSI_SGR_UNDERLINE_OFF:
|
case ansiterm.ANSI_SGR_UNDERLINE_OFF:
|
||||||
windowsMode &^= COMMON_LVB_UNDERSCORE
|
windowsMode &^= COMMON_LVB_UNDERSCORE
|
||||||
|
|
||||||
// Foreground colors
|
// Foreground colors
|
||||||
case ANSI_SGR_FOREGROUND_DEFAULT:
|
case ansiterm.ANSI_SGR_FOREGROUND_DEFAULT:
|
||||||
windowsMode = (windowsMode &^ FOREGROUND_MASK) | (baseMode & FOREGROUND_MASK)
|
windowsMode = (windowsMode &^ FOREGROUND_MASK) | (baseMode & FOREGROUND_MASK)
|
||||||
|
|
||||||
case ANSI_SGR_FOREGROUND_BLACK:
|
case ansiterm.ANSI_SGR_FOREGROUND_BLACK:
|
||||||
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK)
|
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK)
|
||||||
|
|
||||||
case ANSI_SGR_FOREGROUND_RED:
|
case ansiterm.ANSI_SGR_FOREGROUND_RED:
|
||||||
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED
|
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED
|
||||||
|
|
||||||
case ANSI_SGR_FOREGROUND_GREEN:
|
case ansiterm.ANSI_SGR_FOREGROUND_GREEN:
|
||||||
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN
|
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN
|
||||||
|
|
||||||
case ANSI_SGR_FOREGROUND_YELLOW:
|
case ansiterm.ANSI_SGR_FOREGROUND_YELLOW:
|
||||||
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN
|
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN
|
||||||
|
|
||||||
case ANSI_SGR_FOREGROUND_BLUE:
|
case ansiterm.ANSI_SGR_FOREGROUND_BLUE:
|
||||||
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_BLUE
|
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_BLUE
|
||||||
|
|
||||||
case ANSI_SGR_FOREGROUND_MAGENTA:
|
case ansiterm.ANSI_SGR_FOREGROUND_MAGENTA:
|
||||||
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_BLUE
|
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_BLUE
|
||||||
|
|
||||||
case ANSI_SGR_FOREGROUND_CYAN:
|
case ansiterm.ANSI_SGR_FOREGROUND_CYAN:
|
||||||
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN | FOREGROUND_BLUE
|
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN | FOREGROUND_BLUE
|
||||||
|
|
||||||
case ANSI_SGR_FOREGROUND_WHITE:
|
case ansiterm.ANSI_SGR_FOREGROUND_WHITE:
|
||||||
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
|
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
|
||||||
|
|
||||||
// Background colors
|
// Background colors
|
||||||
case ANSI_SGR_BACKGROUND_DEFAULT:
|
case ansiterm.ANSI_SGR_BACKGROUND_DEFAULT:
|
||||||
// Black with no intensity
|
// Black with no intensity
|
||||||
windowsMode = (windowsMode &^ BACKGROUND_MASK) | (baseMode & BACKGROUND_MASK)
|
windowsMode = (windowsMode &^ BACKGROUND_MASK) | (baseMode & BACKGROUND_MASK)
|
||||||
|
|
||||||
case ANSI_SGR_BACKGROUND_BLACK:
|
case ansiterm.ANSI_SGR_BACKGROUND_BLACK:
|
||||||
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK)
|
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK)
|
||||||
|
|
||||||
case ANSI_SGR_BACKGROUND_RED:
|
case ansiterm.ANSI_SGR_BACKGROUND_RED:
|
||||||
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED
|
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED
|
||||||
|
|
||||||
case ANSI_SGR_BACKGROUND_GREEN:
|
case ansiterm.ANSI_SGR_BACKGROUND_GREEN:
|
||||||
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN
|
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN
|
||||||
|
|
||||||
case ANSI_SGR_BACKGROUND_YELLOW:
|
case ansiterm.ANSI_SGR_BACKGROUND_YELLOW:
|
||||||
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN
|
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN
|
||||||
|
|
||||||
case ANSI_SGR_BACKGROUND_BLUE:
|
case ansiterm.ANSI_SGR_BACKGROUND_BLUE:
|
||||||
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_BLUE
|
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_BLUE
|
||||||
|
|
||||||
case ANSI_SGR_BACKGROUND_MAGENTA:
|
case ansiterm.ANSI_SGR_BACKGROUND_MAGENTA:
|
||||||
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_BLUE
|
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_BLUE
|
||||||
|
|
||||||
case ANSI_SGR_BACKGROUND_CYAN:
|
case ansiterm.ANSI_SGR_BACKGROUND_CYAN:
|
||||||
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN | BACKGROUND_BLUE
|
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN | BACKGROUND_BLUE
|
||||||
|
|
||||||
case ANSI_SGR_BACKGROUND_WHITE:
|
case ansiterm.ANSI_SGR_BACKGROUND_WHITE:
|
||||||
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
|
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,6 +95,6 @@ func collectAnsiIntoWindowsAttributes(windowsMode WORD, inverted bool, baseMode
|
|||||||
}
|
}
|
||||||
|
|
||||||
// invertAttributes inverts the foreground and background colors of a Windows attributes value
|
// invertAttributes inverts the foreground and background colors of a Windows attributes value
|
||||||
func invertAttributes(windowsMode WORD) WORD {
|
func invertAttributes(windowsMode uint16) uint16 {
|
||||||
return (COMMON_LVB_MASK & windowsMode) | ((FOREGROUND_MASK & windowsMode) << 4) | ((BACKGROUND_MASK & windowsMode) >> 4)
|
return (COMMON_LVB_MASK & windowsMode) | ((FOREGROUND_MASK & windowsMode) << 4) | ((BACKGROUND_MASK & windowsMode) >> 4)
|
||||||
}
|
}
|
||||||
|
|||||||
34
vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go
generated
vendored
34
vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go
generated
vendored
@ -3,11 +3,11 @@
|
|||||||
package winterm
|
package winterm
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Horizontal = iota
|
horizontal = iota
|
||||||
Vertical
|
vertical
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) getCursorWindow(info *CONSOLE_SCREEN_BUFFER_INFO) SMALL_RECT {
|
func (h *windowsAnsiEventHandler) getCursorWindow(info *CONSOLE_SCREEN_BUFFER_INFO) SMALL_RECT {
|
||||||
if h.originMode {
|
if h.originMode {
|
||||||
sr := h.effectiveSr(info.Window)
|
sr := h.effectiveSr(info.Window)
|
||||||
return SMALL_RECT{
|
return SMALL_RECT{
|
||||||
@ -27,7 +27,7 @@ func (h *WindowsAnsiEventHandler) getCursorWindow(info *CONSOLE_SCREEN_BUFFER_IN
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setCursorPosition sets the cursor to the specified position, bounded to the screen size
|
// setCursorPosition sets the cursor to the specified position, bounded to the screen size
|
||||||
func (h *WindowsAnsiEventHandler) setCursorPosition(position COORD, window SMALL_RECT) error {
|
func (h *windowsAnsiEventHandler) setCursorPosition(position COORD, window SMALL_RECT) error {
|
||||||
position.X = ensureInRange(position.X, window.Left, window.Right)
|
position.X = ensureInRange(position.X, window.Left, window.Right)
|
||||||
position.Y = ensureInRange(position.Y, window.Top, window.Bottom)
|
position.Y = ensureInRange(position.Y, window.Top, window.Bottom)
|
||||||
err := SetConsoleCursorPosition(h.fd, position)
|
err := SetConsoleCursorPosition(h.fd, position)
|
||||||
@ -38,15 +38,15 @@ func (h *WindowsAnsiEventHandler) setCursorPosition(position COORD, window SMALL
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) moveCursorVertical(param int) error {
|
func (h *windowsAnsiEventHandler) moveCursorVertical(param int) error {
|
||||||
return h.moveCursor(Vertical, param)
|
return h.moveCursor(vertical, param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) moveCursorHorizontal(param int) error {
|
func (h *windowsAnsiEventHandler) moveCursorHorizontal(param int) error {
|
||||||
return h.moveCursor(Horizontal, param)
|
return h.moveCursor(horizontal, param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) moveCursor(moveMode int, param int) error {
|
func (h *windowsAnsiEventHandler) moveCursor(moveMode int, param int) error {
|
||||||
info, err := GetConsoleScreenBufferInfo(h.fd)
|
info, err := GetConsoleScreenBufferInfo(h.fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -54,10 +54,10 @@ func (h *WindowsAnsiEventHandler) moveCursor(moveMode int, param int) error {
|
|||||||
|
|
||||||
position := info.CursorPosition
|
position := info.CursorPosition
|
||||||
switch moveMode {
|
switch moveMode {
|
||||||
case Horizontal:
|
case horizontal:
|
||||||
position.X += SHORT(param)
|
position.X += int16(param)
|
||||||
case Vertical:
|
case vertical:
|
||||||
position.Y += SHORT(param)
|
position.Y += int16(param)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {
|
if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {
|
||||||
@ -67,7 +67,7 @@ func (h *WindowsAnsiEventHandler) moveCursor(moveMode int, param int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) moveCursorLine(param int) error {
|
func (h *windowsAnsiEventHandler) moveCursorLine(param int) error {
|
||||||
info, err := GetConsoleScreenBufferInfo(h.fd)
|
info, err := GetConsoleScreenBufferInfo(h.fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -75,7 +75,7 @@ func (h *WindowsAnsiEventHandler) moveCursorLine(param int) error {
|
|||||||
|
|
||||||
position := info.CursorPosition
|
position := info.CursorPosition
|
||||||
position.X = 0
|
position.X = 0
|
||||||
position.Y += SHORT(param)
|
position.Y += int16(param)
|
||||||
|
|
||||||
if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {
|
if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -84,14 +84,14 @@ func (h *WindowsAnsiEventHandler) moveCursorLine(param int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) moveCursorColumn(param int) error {
|
func (h *windowsAnsiEventHandler) moveCursorColumn(param int) error {
|
||||||
info, err := GetConsoleScreenBufferInfo(h.fd)
|
info, err := GetConsoleScreenBufferInfo(h.fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
position := info.CursorPosition
|
position := info.CursorPosition
|
||||||
position.X = SHORT(param) - 1
|
position.X = int16(param) - 1
|
||||||
|
|
||||||
if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {
|
if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
10
vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go
generated
vendored
10
vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go
generated
vendored
@ -2,11 +2,9 @@
|
|||||||
|
|
||||||
package winterm
|
package winterm
|
||||||
|
|
||||||
import (
|
import "github.com/Azure/go-ansiterm"
|
||||||
. "github.com/Azure/go-ansiterm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) clearRange(attributes WORD, fromCoord COORD, toCoord COORD) error {
|
func (h *windowsAnsiEventHandler) clearRange(attributes uint16, fromCoord COORD, toCoord COORD) error {
|
||||||
// Ignore an invalid (negative area) request
|
// Ignore an invalid (negative area) request
|
||||||
if toCoord.Y < fromCoord.Y {
|
if toCoord.Y < fromCoord.Y {
|
||||||
return nil
|
return nil
|
||||||
@ -60,7 +58,7 @@ func (h *WindowsAnsiEventHandler) clearRange(attributes WORD, fromCoord COORD, t
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) clearRect(attributes WORD, fromCoord COORD, toCoord COORD) error {
|
func (h *windowsAnsiEventHandler) clearRect(attributes uint16, fromCoord COORD, toCoord COORD) error {
|
||||||
region := SMALL_RECT{Top: fromCoord.Y, Left: fromCoord.X, Bottom: toCoord.Y, Right: toCoord.X}
|
region := SMALL_RECT{Top: fromCoord.Y, Left: fromCoord.X, Bottom: toCoord.Y, Right: toCoord.X}
|
||||||
width := toCoord.X - fromCoord.X + 1
|
width := toCoord.X - fromCoord.X + 1
|
||||||
height := toCoord.Y - fromCoord.Y + 1
|
height := toCoord.Y - fromCoord.Y + 1
|
||||||
@ -72,7 +70,7 @@ func (h *WindowsAnsiEventHandler) clearRect(attributes WORD, fromCoord COORD, to
|
|||||||
|
|
||||||
buffer := make([]CHAR_INFO, size)
|
buffer := make([]CHAR_INFO, size)
|
||||||
|
|
||||||
char := CHAR_INFO{WCHAR(FILL_CHARACTER), attributes}
|
char := CHAR_INFO{ansiterm.FILL_CHARACTER, attributes}
|
||||||
for i := 0; i < int(size); i++ {
|
for i := 0; i < int(size); i++ {
|
||||||
buffer[i] = char
|
buffer[i] = char
|
||||||
}
|
}
|
||||||
|
|||||||
26
vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go
generated
vendored
26
vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go
generated
vendored
@ -3,9 +3,9 @@
|
|||||||
package winterm
|
package winterm
|
||||||
|
|
||||||
// effectiveSr gets the current effective scroll region in buffer coordinates
|
// effectiveSr gets the current effective scroll region in buffer coordinates
|
||||||
func (h *WindowsAnsiEventHandler) effectiveSr(window SMALL_RECT) scrollRegion {
|
func (h *windowsAnsiEventHandler) effectiveSr(window SMALL_RECT) scrollRegion {
|
||||||
top := AddInRange(window.Top, h.sr.top, window.Top, window.Bottom)
|
top := addInRange(window.Top, h.sr.top, window.Top, window.Bottom)
|
||||||
bottom := AddInRange(window.Top, h.sr.bottom, window.Top, window.Bottom)
|
bottom := addInRange(window.Top, h.sr.bottom, window.Top, window.Bottom)
|
||||||
if top >= bottom {
|
if top >= bottom {
|
||||||
top = window.Top
|
top = window.Top
|
||||||
bottom = window.Bottom
|
bottom = window.Bottom
|
||||||
@ -13,7 +13,7 @@ func (h *WindowsAnsiEventHandler) effectiveSr(window SMALL_RECT) scrollRegion {
|
|||||||
return scrollRegion{top: top, bottom: bottom}
|
return scrollRegion{top: top, bottom: bottom}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) scrollUp(param int) error {
|
func (h *windowsAnsiEventHandler) scrollUp(param int) error {
|
||||||
info, err := GetConsoleScreenBufferInfo(h.fd)
|
info, err := GetConsoleScreenBufferInfo(h.fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -23,11 +23,11 @@ func (h *WindowsAnsiEventHandler) scrollUp(param int) error {
|
|||||||
return h.scroll(param, sr, info)
|
return h.scroll(param, sr, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) scrollDown(param int) error {
|
func (h *windowsAnsiEventHandler) scrollDown(param int) error {
|
||||||
return h.scrollUp(-param)
|
return h.scrollUp(-param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) deleteLines(param int) error {
|
func (h *windowsAnsiEventHandler) deleteLines(param int) error {
|
||||||
info, err := GetConsoleScreenBufferInfo(h.fd)
|
info, err := GetConsoleScreenBufferInfo(h.fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -44,12 +44,12 @@ func (h *WindowsAnsiEventHandler) deleteLines(param int) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) insertLines(param int) error {
|
func (h *windowsAnsiEventHandler) insertLines(param int) error {
|
||||||
return h.deleteLines(-param)
|
return h.deleteLines(-param)
|
||||||
}
|
}
|
||||||
|
|
||||||
// scroll scrolls the provided scroll region by param lines. The scroll region is in buffer coordinates.
|
// scroll scrolls the provided scroll region by param lines. The scroll region is in buffer coordinates.
|
||||||
func (h *WindowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSOLE_SCREEN_BUFFER_INFO) error {
|
func (h *windowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSOLE_SCREEN_BUFFER_INFO) error {
|
||||||
logger.Infof("scroll: scrollTop: %d, scrollBottom: %d", sr.top, sr.bottom)
|
logger.Infof("scroll: scrollTop: %d, scrollBottom: %d", sr.top, sr.bottom)
|
||||||
logger.Infof("scroll: windowTop: %d, windowBottom: %d", info.Window.Top, info.Window.Bottom)
|
logger.Infof("scroll: windowTop: %d, windowBottom: %d", info.Window.Top, info.Window.Bottom)
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ func (h *WindowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSO
|
|||||||
// Origin to which area should be copied
|
// Origin to which area should be copied
|
||||||
destOrigin := COORD{
|
destOrigin := COORD{
|
||||||
X: 0,
|
X: 0,
|
||||||
Y: sr.top - SHORT(param),
|
Y: sr.top - int16(param),
|
||||||
}
|
}
|
||||||
|
|
||||||
char := CHAR_INFO{
|
char := CHAR_INFO{
|
||||||
@ -78,7 +78,7 @@ func (h *WindowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSO
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) deleteCharacters(param int) error {
|
func (h *windowsAnsiEventHandler) deleteCharacters(param int) error {
|
||||||
info, err := GetConsoleScreenBufferInfo(h.fd)
|
info, err := GetConsoleScreenBufferInfo(h.fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -86,12 +86,12 @@ func (h *WindowsAnsiEventHandler) deleteCharacters(param int) error {
|
|||||||
return h.scrollLine(param, info.CursorPosition, info)
|
return h.scrollLine(param, info.CursorPosition, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) insertCharacters(param int) error {
|
func (h *windowsAnsiEventHandler) insertCharacters(param int) error {
|
||||||
return h.deleteCharacters(-param)
|
return h.deleteCharacters(-param)
|
||||||
}
|
}
|
||||||
|
|
||||||
// scrollLine scrolls a line horizontally starting at the provided position by a number of columns.
|
// scrollLine scrolls a line horizontally starting at the provided position by a number of columns.
|
||||||
func (h *WindowsAnsiEventHandler) scrollLine(columns int, position COORD, info *CONSOLE_SCREEN_BUFFER_INFO) error {
|
func (h *windowsAnsiEventHandler) scrollLine(columns int, position COORD, info *CONSOLE_SCREEN_BUFFER_INFO) error {
|
||||||
// Copy from and clip to the scroll region (full buffer width)
|
// Copy from and clip to the scroll region (full buffer width)
|
||||||
scrollRect := SMALL_RECT{
|
scrollRect := SMALL_RECT{
|
||||||
Top: position.Y,
|
Top: position.Y,
|
||||||
@ -102,7 +102,7 @@ func (h *WindowsAnsiEventHandler) scrollLine(columns int, position COORD, info *
|
|||||||
|
|
||||||
// Origin to which area should be copied
|
// Origin to which area should be copied
|
||||||
destOrigin := COORD{
|
destOrigin := COORD{
|
||||||
X: position.X - SHORT(columns),
|
X: position.X - int16(columns),
|
||||||
Y: position.Y,
|
Y: position.Y,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
vendor/github.com/Azure/go-ansiterm/winterm/utilities.go
generated
vendored
2
vendor/github.com/Azure/go-ansiterm/winterm/utilities.go
generated
vendored
@ -4,6 +4,6 @@ package winterm
|
|||||||
|
|
||||||
// AddInRange increments a value by the passed quantity while ensuring the values
|
// AddInRange increments a value by the passed quantity while ensuring the values
|
||||||
// always remain within the supplied min / max range.
|
// always remain within the supplied min / max range.
|
||||||
func AddInRange(n SHORT, increment SHORT, min SHORT, max SHORT) SHORT {
|
func addInRange(n int16, increment int16, min int16, max int16) int16 {
|
||||||
return ensureInRange(n+increment, min, max)
|
return ensureInRange(n+increment, min, max)
|
||||||
}
|
}
|
||||||
|
|||||||
133
vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go
generated
vendored
133
vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go
generated
vendored
@ -8,19 +8,19 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
. "github.com/Azure/go-ansiterm"
|
"github.com/Azure/go-ansiterm"
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var logger *logrus.Logger
|
var logger *logrus.Logger
|
||||||
|
|
||||||
type WindowsAnsiEventHandler struct {
|
type windowsAnsiEventHandler struct {
|
||||||
fd uintptr
|
fd uintptr
|
||||||
file *os.File
|
file *os.File
|
||||||
infoReset *CONSOLE_SCREEN_BUFFER_INFO
|
infoReset *CONSOLE_SCREEN_BUFFER_INFO
|
||||||
sr scrollRegion
|
sr scrollRegion
|
||||||
buffer bytes.Buffer
|
buffer bytes.Buffer
|
||||||
attributes WORD
|
attributes uint16
|
||||||
inverted bool
|
inverted bool
|
||||||
wrapNext bool
|
wrapNext bool
|
||||||
drewMarginByte bool
|
drewMarginByte bool
|
||||||
@ -30,10 +30,10 @@ type WindowsAnsiEventHandler struct {
|
|||||||
curPos COORD
|
curPos COORD
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateWinEventHandler(fd uintptr, file *os.File) AnsiEventHandler {
|
func CreateWinEventHandler(fd uintptr, file *os.File) ansiterm.AnsiEventHandler {
|
||||||
logFile := ioutil.Discard
|
logFile := ioutil.Discard
|
||||||
|
|
||||||
if isDebugEnv := os.Getenv(LogEnv); isDebugEnv == "1" {
|
if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" {
|
||||||
logFile, _ = os.Create("winEventHandler.log")
|
logFile, _ = os.Create("winEventHandler.log")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ func CreateWinEventHandler(fd uintptr, file *os.File) AnsiEventHandler {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &WindowsAnsiEventHandler{
|
return &windowsAnsiEventHandler{
|
||||||
fd: fd,
|
fd: fd,
|
||||||
file: file,
|
file: file,
|
||||||
infoReset: infoReset,
|
infoReset: infoReset,
|
||||||
@ -57,8 +57,8 @@ func CreateWinEventHandler(fd uintptr, file *os.File) AnsiEventHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type scrollRegion struct {
|
type scrollRegion struct {
|
||||||
top SHORT
|
top int16
|
||||||
bottom SHORT
|
bottom int16
|
||||||
}
|
}
|
||||||
|
|
||||||
// simulateLF simulates a LF or CR+LF by scrolling if necessary to handle the
|
// simulateLF simulates a LF or CR+LF by scrolling if necessary to handle the
|
||||||
@ -68,7 +68,7 @@ type scrollRegion struct {
|
|||||||
//
|
//
|
||||||
// In the false case, the caller should ensure that a carriage return
|
// In the false case, the caller should ensure that a carriage return
|
||||||
// and line feed are inserted or that the text is otherwise wrapped.
|
// and line feed are inserted or that the text is otherwise wrapped.
|
||||||
func (h *WindowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) {
|
func (h *windowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) {
|
||||||
if h.wrapNext {
|
if h.wrapNext {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
@ -89,7 +89,8 @@ func (h *WindowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) {
|
|||||||
h.updatePos(pos)
|
h.updatePos(pos)
|
||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
} else {
|
}
|
||||||
|
|
||||||
// A custom scroll region is active. Scroll the window manually to simulate
|
// A custom scroll region is active. Scroll the window manually to simulate
|
||||||
// the LF.
|
// the LF.
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
@ -106,7 +107,7 @@ func (h *WindowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
|
||||||
} else if pos.Y < info.Window.Bottom {
|
} else if pos.Y < info.Window.Bottom {
|
||||||
// Let Windows handle the LF.
|
// Let Windows handle the LF.
|
||||||
pos.Y++
|
pos.Y++
|
||||||
@ -133,7 +134,7 @@ func (h *WindowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// executeLF executes a LF without a CR.
|
// executeLF executes a LF without a CR.
|
||||||
func (h *WindowsAnsiEventHandler) executeLF() error {
|
func (h *windowsAnsiEventHandler) executeLF() error {
|
||||||
handled, err := h.simulateLF(false)
|
handled, err := h.simulateLF(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -145,7 +146,7 @@ func (h *WindowsAnsiEventHandler) executeLF() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
h.buffer.WriteByte(ANSI_LINE_FEED)
|
h.buffer.WriteByte(ansiterm.ANSI_LINE_FEED)
|
||||||
if pos.X != 0 {
|
if pos.X != 0 {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -159,7 +160,7 @@ func (h *WindowsAnsiEventHandler) executeLF() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) Print(b byte) error {
|
func (h *windowsAnsiEventHandler) Print(b byte) error {
|
||||||
if h.wrapNext {
|
if h.wrapNext {
|
||||||
h.buffer.WriteByte(h.marginByte)
|
h.buffer.WriteByte(h.marginByte)
|
||||||
h.clearWrap()
|
h.clearWrap()
|
||||||
@ -182,9 +183,9 @@ func (h *WindowsAnsiEventHandler) Print(b byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) Execute(b byte) error {
|
func (h *windowsAnsiEventHandler) Execute(b byte) error {
|
||||||
switch b {
|
switch b {
|
||||||
case ANSI_TAB:
|
case ansiterm.ANSI_TAB:
|
||||||
logger.Info("Execute(TAB)")
|
logger.Info("Execute(TAB)")
|
||||||
// Move to the next tab stop, but preserve auto-wrap if already set.
|
// Move to the next tab stop, but preserve auto-wrap if already set.
|
||||||
if !h.wrapNext {
|
if !h.wrapNext {
|
||||||
@ -205,11 +206,11 @@ func (h *WindowsAnsiEventHandler) Execute(b byte) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case ANSI_BEL:
|
case ansiterm.ANSI_BEL:
|
||||||
h.buffer.WriteByte(ANSI_BEL)
|
h.buffer.WriteByte(ansiterm.ANSI_BEL)
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case ANSI_BACKSPACE:
|
case ansiterm.ANSI_BACKSPACE:
|
||||||
if h.wrapNext {
|
if h.wrapNext {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -223,15 +224,15 @@ func (h *WindowsAnsiEventHandler) Execute(b byte) error {
|
|||||||
if pos.X > 0 {
|
if pos.X > 0 {
|
||||||
pos.X--
|
pos.X--
|
||||||
h.updatePos(pos)
|
h.updatePos(pos)
|
||||||
h.buffer.WriteByte(ANSI_BACKSPACE)
|
h.buffer.WriteByte(ansiterm.ANSI_BACKSPACE)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case ANSI_VERTICAL_TAB, ANSI_FORM_FEED:
|
case ansiterm.ANSI_VERTICAL_TAB, ansiterm.ANSI_FORM_FEED:
|
||||||
// Treat as true LF.
|
// Treat as true LF.
|
||||||
return h.executeLF()
|
return h.executeLF()
|
||||||
|
|
||||||
case ANSI_LINE_FEED:
|
case ansiterm.ANSI_LINE_FEED:
|
||||||
// Simulate a CR and LF for now since there is no way in go-ansiterm
|
// Simulate a CR and LF for now since there is no way in go-ansiterm
|
||||||
// to tell if the LF should include CR (and more things break when it's
|
// to tell if the LF should include CR (and more things break when it's
|
||||||
// missing than when it's incorrectly added).
|
// missing than when it's incorrectly added).
|
||||||
@ -239,9 +240,9 @@ func (h *WindowsAnsiEventHandler) Execute(b byte) error {
|
|||||||
if handled || err != nil {
|
if handled || err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return h.buffer.WriteByte(ANSI_LINE_FEED)
|
return h.buffer.WriteByte(ansiterm.ANSI_LINE_FEED)
|
||||||
|
|
||||||
case ANSI_CARRIAGE_RETURN:
|
case ansiterm.ANSI_CARRIAGE_RETURN:
|
||||||
if h.wrapNext {
|
if h.wrapNext {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -255,7 +256,7 @@ func (h *WindowsAnsiEventHandler) Execute(b byte) error {
|
|||||||
if pos.X != 0 {
|
if pos.X != 0 {
|
||||||
pos.X = 0
|
pos.X = 0
|
||||||
h.updatePos(pos)
|
h.updatePos(pos)
|
||||||
h.buffer.WriteByte(ANSI_CARRIAGE_RETURN)
|
h.buffer.WriteByte(ansiterm.ANSI_CARRIAGE_RETURN)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
@ -264,7 +265,7 @@ func (h *WindowsAnsiEventHandler) Execute(b byte) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) CUU(param int) error {
|
func (h *windowsAnsiEventHandler) CUU(param int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -273,7 +274,7 @@ func (h *WindowsAnsiEventHandler) CUU(param int) error {
|
|||||||
return h.moveCursorVertical(-param)
|
return h.moveCursorVertical(-param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) CUD(param int) error {
|
func (h *windowsAnsiEventHandler) CUD(param int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -282,7 +283,7 @@ func (h *WindowsAnsiEventHandler) CUD(param int) error {
|
|||||||
return h.moveCursorVertical(param)
|
return h.moveCursorVertical(param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) CUF(param int) error {
|
func (h *windowsAnsiEventHandler) CUF(param int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -291,7 +292,7 @@ func (h *WindowsAnsiEventHandler) CUF(param int) error {
|
|||||||
return h.moveCursorHorizontal(param)
|
return h.moveCursorHorizontal(param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) CUB(param int) error {
|
func (h *windowsAnsiEventHandler) CUB(param int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -300,7 +301,7 @@ func (h *WindowsAnsiEventHandler) CUB(param int) error {
|
|||||||
return h.moveCursorHorizontal(-param)
|
return h.moveCursorHorizontal(-param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) CNL(param int) error {
|
func (h *windowsAnsiEventHandler) CNL(param int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -309,7 +310,7 @@ func (h *WindowsAnsiEventHandler) CNL(param int) error {
|
|||||||
return h.moveCursorLine(param)
|
return h.moveCursorLine(param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) CPL(param int) error {
|
func (h *windowsAnsiEventHandler) CPL(param int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -318,7 +319,7 @@ func (h *WindowsAnsiEventHandler) CPL(param int) error {
|
|||||||
return h.moveCursorLine(-param)
|
return h.moveCursorLine(-param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) CHA(param int) error {
|
func (h *windowsAnsiEventHandler) CHA(param int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -327,7 +328,7 @@ func (h *WindowsAnsiEventHandler) CHA(param int) error {
|
|||||||
return h.moveCursorColumn(param)
|
return h.moveCursorColumn(param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) VPA(param int) error {
|
func (h *windowsAnsiEventHandler) VPA(param int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -339,11 +340,11 @@ func (h *WindowsAnsiEventHandler) VPA(param int) error {
|
|||||||
}
|
}
|
||||||
window := h.getCursorWindow(info)
|
window := h.getCursorWindow(info)
|
||||||
position := info.CursorPosition
|
position := info.CursorPosition
|
||||||
position.Y = window.Top + SHORT(param) - 1
|
position.Y = window.Top + int16(param) - 1
|
||||||
return h.setCursorPosition(position, window)
|
return h.setCursorPosition(position, window)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) CUP(row int, col int) error {
|
func (h *windowsAnsiEventHandler) CUP(row int, col int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -355,11 +356,11 @@ func (h *WindowsAnsiEventHandler) CUP(row int, col int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window := h.getCursorWindow(info)
|
window := h.getCursorWindow(info)
|
||||||
position := COORD{window.Left + SHORT(col) - 1, window.Top + SHORT(row) - 1}
|
position := COORD{window.Left + int16(col) - 1, window.Top + int16(row) - 1}
|
||||||
return h.setCursorPosition(position, window)
|
return h.setCursorPosition(position, window)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) HVP(row int, col int) error {
|
func (h *windowsAnsiEventHandler) HVP(row int, col int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -368,7 +369,7 @@ func (h *WindowsAnsiEventHandler) HVP(row int, col int) error {
|
|||||||
return h.CUP(row, col)
|
return h.CUP(row, col)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) DECTCEM(visible bool) error {
|
func (h *windowsAnsiEventHandler) DECTCEM(visible bool) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -377,7 +378,7 @@ func (h *WindowsAnsiEventHandler) DECTCEM(visible bool) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) DECOM(enable bool) error {
|
func (h *windowsAnsiEventHandler) DECOM(enable bool) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -387,7 +388,7 @@ func (h *WindowsAnsiEventHandler) DECOM(enable bool) error {
|
|||||||
return h.CUP(1, 1)
|
return h.CUP(1, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) DECCOLM(use132 bool) error {
|
func (h *windowsAnsiEventHandler) DECCOLM(use132 bool) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -400,7 +401,7 @@ func (h *WindowsAnsiEventHandler) DECCOLM(use132 bool) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
targetWidth := SHORT(80)
|
targetWidth := int16(80)
|
||||||
if use132 {
|
if use132 {
|
||||||
targetWidth = 132
|
targetWidth = 132
|
||||||
}
|
}
|
||||||
@ -426,7 +427,7 @@ func (h *WindowsAnsiEventHandler) DECCOLM(use132 bool) error {
|
|||||||
return SetConsoleCursorPosition(h.fd, COORD{0, 0})
|
return SetConsoleCursorPosition(h.fd, COORD{0, 0})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) ED(param int) error {
|
func (h *windowsAnsiEventHandler) ED(param int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -485,7 +486,7 @@ func (h *WindowsAnsiEventHandler) ED(param int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) EL(param int) error {
|
func (h *windowsAnsiEventHandler) EL(param int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -526,7 +527,7 @@ func (h *WindowsAnsiEventHandler) EL(param int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) IL(param int) error {
|
func (h *windowsAnsiEventHandler) IL(param int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -535,7 +536,7 @@ func (h *WindowsAnsiEventHandler) IL(param int) error {
|
|||||||
return h.insertLines(param)
|
return h.insertLines(param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) DL(param int) error {
|
func (h *windowsAnsiEventHandler) DL(param int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -544,7 +545,7 @@ func (h *WindowsAnsiEventHandler) DL(param int) error {
|
|||||||
return h.deleteLines(param)
|
return h.deleteLines(param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) ICH(param int) error {
|
func (h *windowsAnsiEventHandler) ICH(param int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -553,7 +554,7 @@ func (h *WindowsAnsiEventHandler) ICH(param int) error {
|
|||||||
return h.insertCharacters(param)
|
return h.insertCharacters(param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) DCH(param int) error {
|
func (h *windowsAnsiEventHandler) DCH(param int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -562,7 +563,7 @@ func (h *WindowsAnsiEventHandler) DCH(param int) error {
|
|||||||
return h.deleteCharacters(param)
|
return h.deleteCharacters(param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) SGR(params []int) error {
|
func (h *windowsAnsiEventHandler) SGR(params []int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -579,13 +580,13 @@ func (h *WindowsAnsiEventHandler) SGR(params []int) error {
|
|||||||
} else {
|
} else {
|
||||||
for _, attr := range params {
|
for _, attr := range params {
|
||||||
|
|
||||||
if attr == ANSI_SGR_RESET {
|
if attr == ansiterm.ANSI_SGR_RESET {
|
||||||
h.attributes = h.infoReset.Attributes
|
h.attributes = h.infoReset.Attributes
|
||||||
h.inverted = false
|
h.inverted = false
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
h.attributes, h.inverted = collectAnsiIntoWindowsAttributes(h.attributes, h.inverted, h.infoReset.Attributes, SHORT(attr))
|
h.attributes, h.inverted = collectAnsiIntoWindowsAttributes(h.attributes, h.inverted, h.infoReset.Attributes, int16(attr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,7 +602,7 @@ func (h *WindowsAnsiEventHandler) SGR(params []int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) SU(param int) error {
|
func (h *windowsAnsiEventHandler) SU(param int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -610,7 +611,7 @@ func (h *WindowsAnsiEventHandler) SU(param int) error {
|
|||||||
return h.scrollUp(param)
|
return h.scrollUp(param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) SD(param int) error {
|
func (h *windowsAnsiEventHandler) SD(param int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -619,29 +620,29 @@ func (h *WindowsAnsiEventHandler) SD(param int) error {
|
|||||||
return h.scrollDown(param)
|
return h.scrollDown(param)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) DA(params []string) error {
|
func (h *windowsAnsiEventHandler) DA(params []string) error {
|
||||||
logger.Infof("DA: [%v]", params)
|
logger.Infof("DA: [%v]", params)
|
||||||
// DA cannot be implemented because it must send data on the VT100 input stream,
|
// DA cannot be implemented because it must send data on the VT100 input stream,
|
||||||
// which is not available to go-ansiterm.
|
// which is not available to go-ansiterm.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) DECSTBM(top int, bottom int) error {
|
func (h *windowsAnsiEventHandler) DECSTBM(top int, bottom int) error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
logger.Infof("DECSTBM: [%d, %d]", top, bottom)
|
logger.Infof("DECSTBM: [%d, %d]", top, bottom)
|
||||||
|
|
||||||
// Windows is 0 indexed, Linux is 1 indexed
|
// Windows is 0 indexed, Linux is 1 indexed
|
||||||
h.sr.top = SHORT(top - 1)
|
h.sr.top = int16(top - 1)
|
||||||
h.sr.bottom = SHORT(bottom - 1)
|
h.sr.bottom = int16(bottom - 1)
|
||||||
|
|
||||||
// This command also moves the cursor to the origin.
|
// This command also moves the cursor to the origin.
|
||||||
h.clearWrap()
|
h.clearWrap()
|
||||||
return h.CUP(1, 1)
|
return h.CUP(1, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) RI() error {
|
func (h *windowsAnsiEventHandler) RI() error {
|
||||||
if err := h.Flush(); err != nil {
|
if err := h.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -656,17 +657,17 @@ func (h *WindowsAnsiEventHandler) RI() error {
|
|||||||
sr := h.effectiveSr(info.Window)
|
sr := h.effectiveSr(info.Window)
|
||||||
if info.CursorPosition.Y == sr.top {
|
if info.CursorPosition.Y == sr.top {
|
||||||
return h.scrollDown(1)
|
return h.scrollDown(1)
|
||||||
} else {
|
|
||||||
return h.moveCursorVertical(-1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) IND() error {
|
return h.moveCursorVertical(-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *windowsAnsiEventHandler) IND() error {
|
||||||
logger.Info("IND: []")
|
logger.Info("IND: []")
|
||||||
return h.executeLF()
|
return h.executeLF()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) Flush() error {
|
func (h *windowsAnsiEventHandler) Flush() error {
|
||||||
h.curInfo = nil
|
h.curInfo = nil
|
||||||
if h.buffer.Len() > 0 {
|
if h.buffer.Len() > 0 {
|
||||||
logger.Infof("Flush: [%s]", h.buffer.Bytes())
|
logger.Infof("Flush: [%s]", h.buffer.Bytes())
|
||||||
@ -683,7 +684,7 @@ func (h *WindowsAnsiEventHandler) Flush() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
charInfo := []CHAR_INFO{{UnicodeChar: WCHAR(h.marginByte), Attributes: info.Attributes}}
|
charInfo := []CHAR_INFO{{UnicodeChar: uint16(h.marginByte), Attributes: info.Attributes}}
|
||||||
size := COORD{1, 1}
|
size := COORD{1, 1}
|
||||||
position := COORD{0, 0}
|
position := COORD{0, 0}
|
||||||
region := SMALL_RECT{Left: info.CursorPosition.X, Top: info.CursorPosition.Y, Right: info.CursorPosition.X, Bottom: info.CursorPosition.Y}
|
region := SMALL_RECT{Left: info.CursorPosition.X, Top: info.CursorPosition.Y, Right: info.CursorPosition.X, Bottom: info.CursorPosition.Y}
|
||||||
@ -697,7 +698,7 @@ func (h *WindowsAnsiEventHandler) Flush() error {
|
|||||||
|
|
||||||
// cacheConsoleInfo ensures that the current console screen information has been queried
|
// cacheConsoleInfo ensures that the current console screen information has been queried
|
||||||
// since the last call to Flush(). It must be called before accessing h.curInfo or h.curPos.
|
// since the last call to Flush(). It must be called before accessing h.curInfo or h.curPos.
|
||||||
func (h *WindowsAnsiEventHandler) getCurrentInfo() (COORD, *CONSOLE_SCREEN_BUFFER_INFO, error) {
|
func (h *windowsAnsiEventHandler) getCurrentInfo() (COORD, *CONSOLE_SCREEN_BUFFER_INFO, error) {
|
||||||
if h.curInfo == nil {
|
if h.curInfo == nil {
|
||||||
info, err := GetConsoleScreenBufferInfo(h.fd)
|
info, err := GetConsoleScreenBufferInfo(h.fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -709,7 +710,7 @@ func (h *WindowsAnsiEventHandler) getCurrentInfo() (COORD, *CONSOLE_SCREEN_BUFFE
|
|||||||
return h.curPos, h.curInfo, nil
|
return h.curPos, h.curInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WindowsAnsiEventHandler) updatePos(pos COORD) {
|
func (h *windowsAnsiEventHandler) updatePos(pos COORD) {
|
||||||
if h.curInfo == nil {
|
if h.curInfo == nil {
|
||||||
panic("failed to call getCurrentInfo before calling updatePos")
|
panic("failed to call getCurrentInfo before calling updatePos")
|
||||||
}
|
}
|
||||||
@ -719,7 +720,7 @@ func (h *WindowsAnsiEventHandler) updatePos(pos COORD) {
|
|||||||
// clearWrap clears the state where the cursor is in the margin
|
// clearWrap clears the state where the cursor is in the margin
|
||||||
// waiting for the next character before wrapping the line. This must
|
// waiting for the next character before wrapping the line. This must
|
||||||
// be done before most operations that act on the cursor.
|
// be done before most operations that act on the cursor.
|
||||||
func (h *WindowsAnsiEventHandler) clearWrap() {
|
func (h *windowsAnsiEventHandler) clearWrap() {
|
||||||
h.wrapNext = false
|
h.wrapNext = false
|
||||||
h.drewMarginByte = false
|
h.drewMarginByte = false
|
||||||
}
|
}
|
||||||
|
|||||||
2
vendor/github.com/docker/docker/api/client/bundlefile/bundlefile.go
generated
vendored
2
vendor/github.com/docker/docker/api/client/bundlefile/bundlefile.go
generated
vendored
@ -1,3 +1,5 @@
|
|||||||
|
// +build experimental
|
||||||
|
|
||||||
package bundlefile
|
package bundlefile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
102
vendor/github.com/docker/libcompose/cli/logger/color_logger.go
generated
vendored
102
vendor/github.com/docker/libcompose/cli/logger/color_logger.go
generated
vendored
@ -1,102 +0,0 @@
|
|||||||
package logger
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/docker/libcompose/logger"
|
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ColorLoggerFactory implements logger.Factory interface using ColorLogger.
|
|
||||||
type ColorLoggerFactory struct {
|
|
||||||
maxLength int
|
|
||||||
tty bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// ColorLogger implements logger.Logger interface with color support.
|
|
||||||
type ColorLogger struct {
|
|
||||||
name string
|
|
||||||
colorPrefix string
|
|
||||||
factory *ColorLoggerFactory
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewColorLoggerFactory creates a new ColorLoggerFactory.
|
|
||||||
func NewColorLoggerFactory() *ColorLoggerFactory {
|
|
||||||
return &ColorLoggerFactory{
|
|
||||||
tty: terminal.IsTerminal(int(os.Stdout.Fd())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateContainerLogger implements logger.Factory.CreateContainerLogger.
|
|
||||||
func (c *ColorLoggerFactory) CreateContainerLogger(name string) logger.Logger {
|
|
||||||
return c.create(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateBuildLogger implements logger.Factory.CreateBuildLogger.
|
|
||||||
func (c *ColorLoggerFactory) CreateBuildLogger(name string) logger.Logger {
|
|
||||||
return &logger.RawLogger{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreatePullLogger implements logger.Factory.CreatePullLogger.
|
|
||||||
func (c *ColorLoggerFactory) CreatePullLogger(name string) logger.Logger {
|
|
||||||
return &logger.NullLogger{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateBuildLogger implements logger.Factory.CreateContainerLogger.
|
|
||||||
func (c *ColorLoggerFactory) create(name string) logger.Logger {
|
|
||||||
if c.maxLength < len(name) {
|
|
||||||
c.maxLength = len(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &ColorLogger{
|
|
||||||
name: name,
|
|
||||||
factory: c,
|
|
||||||
colorPrefix: <-colorPrefix,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Out implements logger.Logger.Out.
|
|
||||||
func (c *ColorLogger) Out(bytes []byte) {
|
|
||||||
if len(bytes) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
logFmt, name := c.getLogFmt()
|
|
||||||
message := fmt.Sprintf(logFmt, name, string(bytes))
|
|
||||||
fmt.Print(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Err implements logger.Logger.Err.
|
|
||||||
func (c *ColorLogger) Err(bytes []byte) {
|
|
||||||
if len(bytes) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
logFmt, name := c.getLogFmt()
|
|
||||||
message := fmt.Sprintf(logFmt, name, string(bytes))
|
|
||||||
fmt.Fprint(os.Stderr, message)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OutWriter returns the base writer
|
|
||||||
func (c *ColorLogger) OutWriter() io.Writer {
|
|
||||||
return os.Stdout
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrWriter returns the base writer
|
|
||||||
func (c *ColorLogger) ErrWriter() io.Writer {
|
|
||||||
return os.Stderr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ColorLogger) getLogFmt() (string, string) {
|
|
||||||
pad := c.factory.maxLength
|
|
||||||
|
|
||||||
logFmt := "%s | %s"
|
|
||||||
if c.factory.tty {
|
|
||||||
logFmt = c.colorPrefix + " %s"
|
|
||||||
}
|
|
||||||
|
|
||||||
name := fmt.Sprintf("%-"+strconv.Itoa(pad)+"s", c.name)
|
|
||||||
|
|
||||||
return logFmt, name
|
|
||||||
}
|
|
||||||
34
vendor/github.com/docker/libcompose/cli/logger/colors.go
generated
vendored
34
vendor/github.com/docker/libcompose/cli/logger/colors.go
generated
vendored
@ -1,34 +0,0 @@
|
|||||||
package logger
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
var (
|
|
||||||
colorPrefix = make(chan string)
|
|
||||||
)
|
|
||||||
|
|
||||||
func generateColors() {
|
|
||||||
i := 0
|
|
||||||
colorOrder := []string{
|
|
||||||
"36", // cyan
|
|
||||||
"33", // yellow
|
|
||||||
"32", // green
|
|
||||||
"35", // magenta
|
|
||||||
"31", // red
|
|
||||||
"34", // blue
|
|
||||||
"36;1", // intense cyan
|
|
||||||
"33;1", // intense yellow
|
|
||||||
"32;1", // intense green
|
|
||||||
"35;1", // intense magenta
|
|
||||||
"31;1", // intense red
|
|
||||||
"34;1", // intense blue
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
colorPrefix <- fmt.Sprintf("\033[%sm%%s |\033[0m", colorOrder[i])
|
|
||||||
i = (i + 1) % len(colorOrder)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
go generateColors()
|
|
||||||
}
|
|
||||||
27
vendor/golang.org/x/crypto/LICENSE
generated
vendored
27
vendor/golang.org/x/crypto/LICENSE
generated
vendored
@ -1,27 +0,0 @@
|
|||||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
* Neither the name of Google Inc. nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
22
vendor/golang.org/x/crypto/PATENTS
generated
vendored
22
vendor/golang.org/x/crypto/PATENTS
generated
vendored
@ -1,22 +0,0 @@
|
|||||||
Additional IP Rights Grant (Patents)
|
|
||||||
|
|
||||||
"This implementation" means the copyrightable works distributed by
|
|
||||||
Google as part of the Go project.
|
|
||||||
|
|
||||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
|
||||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
|
||||||
patent license to make, have made, use, offer to sell, sell, import,
|
|
||||||
transfer and otherwise run, modify and propagate the contents of this
|
|
||||||
implementation of Go, where such license applies only to those patent
|
|
||||||
claims, both currently owned or controlled by Google and acquired in
|
|
||||||
the future, licensable by Google that are necessarily infringed by this
|
|
||||||
implementation of Go. This grant does not include claims that would be
|
|
||||||
infringed only as a consequence of further modification of this
|
|
||||||
implementation. If you or your agent or exclusive licensee institute or
|
|
||||||
order or agree to the institution of patent litigation against any
|
|
||||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
|
||||||
that this implementation of Go or any code incorporated within this
|
|
||||||
implementation of Go constitutes direct or contributory patent
|
|
||||||
infringement, or inducement of patent infringement, then any patent
|
|
||||||
rights granted to you under this License for this implementation of Go
|
|
||||||
shall terminate as of the date such litigation is filed.
|
|
||||||
892
vendor/golang.org/x/crypto/ssh/terminal/terminal.go
generated
vendored
892
vendor/golang.org/x/crypto/ssh/terminal/terminal.go
generated
vendored
@ -1,892 +0,0 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package terminal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"sync"
|
|
||||||
"unicode/utf8"
|
|
||||||
)
|
|
||||||
|
|
||||||
// EscapeCodes contains escape sequences that can be written to the terminal in
|
|
||||||
// order to achieve different styles of text.
|
|
||||||
type EscapeCodes struct {
|
|
||||||
// Foreground colors
|
|
||||||
Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte
|
|
||||||
|
|
||||||
// Reset all attributes
|
|
||||||
Reset []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
var vt100EscapeCodes = EscapeCodes{
|
|
||||||
Black: []byte{keyEscape, '[', '3', '0', 'm'},
|
|
||||||
Red: []byte{keyEscape, '[', '3', '1', 'm'},
|
|
||||||
Green: []byte{keyEscape, '[', '3', '2', 'm'},
|
|
||||||
Yellow: []byte{keyEscape, '[', '3', '3', 'm'},
|
|
||||||
Blue: []byte{keyEscape, '[', '3', '4', 'm'},
|
|
||||||
Magenta: []byte{keyEscape, '[', '3', '5', 'm'},
|
|
||||||
Cyan: []byte{keyEscape, '[', '3', '6', 'm'},
|
|
||||||
White: []byte{keyEscape, '[', '3', '7', 'm'},
|
|
||||||
|
|
||||||
Reset: []byte{keyEscape, '[', '0', 'm'},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Terminal contains the state for running a VT100 terminal that is capable of
|
|
||||||
// reading lines of input.
|
|
||||||
type Terminal struct {
|
|
||||||
// AutoCompleteCallback, if non-null, is called for each keypress with
|
|
||||||
// the full input line and the current position of the cursor (in
|
|
||||||
// bytes, as an index into |line|). If it returns ok=false, the key
|
|
||||||
// press is processed normally. Otherwise it returns a replacement line
|
|
||||||
// and the new cursor position.
|
|
||||||
AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool)
|
|
||||||
|
|
||||||
// Escape contains a pointer to the escape codes for this terminal.
|
|
||||||
// It's always a valid pointer, although the escape codes themselves
|
|
||||||
// may be empty if the terminal doesn't support them.
|
|
||||||
Escape *EscapeCodes
|
|
||||||
|
|
||||||
// lock protects the terminal and the state in this object from
|
|
||||||
// concurrent processing of a key press and a Write() call.
|
|
||||||
lock sync.Mutex
|
|
||||||
|
|
||||||
c io.ReadWriter
|
|
||||||
prompt []rune
|
|
||||||
|
|
||||||
// line is the current line being entered.
|
|
||||||
line []rune
|
|
||||||
// pos is the logical position of the cursor in line
|
|
||||||
pos int
|
|
||||||
// echo is true if local echo is enabled
|
|
||||||
echo bool
|
|
||||||
// pasteActive is true iff there is a bracketed paste operation in
|
|
||||||
// progress.
|
|
||||||
pasteActive bool
|
|
||||||
|
|
||||||
// cursorX contains the current X value of the cursor where the left
|
|
||||||
// edge is 0. cursorY contains the row number where the first row of
|
|
||||||
// the current line is 0.
|
|
||||||
cursorX, cursorY int
|
|
||||||
// maxLine is the greatest value of cursorY so far.
|
|
||||||
maxLine int
|
|
||||||
|
|
||||||
termWidth, termHeight int
|
|
||||||
|
|
||||||
// outBuf contains the terminal data to be sent.
|
|
||||||
outBuf []byte
|
|
||||||
// remainder contains the remainder of any partial key sequences after
|
|
||||||
// a read. It aliases into inBuf.
|
|
||||||
remainder []byte
|
|
||||||
inBuf [256]byte
|
|
||||||
|
|
||||||
// history contains previously entered commands so that they can be
|
|
||||||
// accessed with the up and down keys.
|
|
||||||
history stRingBuffer
|
|
||||||
// historyIndex stores the currently accessed history entry, where zero
|
|
||||||
// means the immediately previous entry.
|
|
||||||
historyIndex int
|
|
||||||
// When navigating up and down the history it's possible to return to
|
|
||||||
// the incomplete, initial line. That value is stored in
|
|
||||||
// historyPending.
|
|
||||||
historyPending string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is
|
|
||||||
// a local terminal, that terminal must first have been put into raw mode.
|
|
||||||
// prompt is a string that is written at the start of each input line (i.e.
|
|
||||||
// "> ").
|
|
||||||
func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
|
|
||||||
return &Terminal{
|
|
||||||
Escape: &vt100EscapeCodes,
|
|
||||||
c: c,
|
|
||||||
prompt: []rune(prompt),
|
|
||||||
termWidth: 80,
|
|
||||||
termHeight: 24,
|
|
||||||
echo: true,
|
|
||||||
historyIndex: -1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
keyCtrlD = 4
|
|
||||||
keyCtrlU = 21
|
|
||||||
keyEnter = '\r'
|
|
||||||
keyEscape = 27
|
|
||||||
keyBackspace = 127
|
|
||||||
keyUnknown = 0xd800 /* UTF-16 surrogate area */ + iota
|
|
||||||
keyUp
|
|
||||||
keyDown
|
|
||||||
keyLeft
|
|
||||||
keyRight
|
|
||||||
keyAltLeft
|
|
||||||
keyAltRight
|
|
||||||
keyHome
|
|
||||||
keyEnd
|
|
||||||
keyDeleteWord
|
|
||||||
keyDeleteLine
|
|
||||||
keyClearScreen
|
|
||||||
keyPasteStart
|
|
||||||
keyPasteEnd
|
|
||||||
)
|
|
||||||
|
|
||||||
var pasteStart = []byte{keyEscape, '[', '2', '0', '0', '~'}
|
|
||||||
var pasteEnd = []byte{keyEscape, '[', '2', '0', '1', '~'}
|
|
||||||
|
|
||||||
// bytesToKey tries to parse a key sequence from b. If successful, it returns
|
|
||||||
// the key and the remainder of the input. Otherwise it returns utf8.RuneError.
|
|
||||||
func bytesToKey(b []byte, pasteActive bool) (rune, []byte) {
|
|
||||||
if len(b) == 0 {
|
|
||||||
return utf8.RuneError, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pasteActive {
|
|
||||||
switch b[0] {
|
|
||||||
case 1: // ^A
|
|
||||||
return keyHome, b[1:]
|
|
||||||
case 5: // ^E
|
|
||||||
return keyEnd, b[1:]
|
|
||||||
case 8: // ^H
|
|
||||||
return keyBackspace, b[1:]
|
|
||||||
case 11: // ^K
|
|
||||||
return keyDeleteLine, b[1:]
|
|
||||||
case 12: // ^L
|
|
||||||
return keyClearScreen, b[1:]
|
|
||||||
case 23: // ^W
|
|
||||||
return keyDeleteWord, b[1:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if b[0] != keyEscape {
|
|
||||||
if !utf8.FullRune(b) {
|
|
||||||
return utf8.RuneError, b
|
|
||||||
}
|
|
||||||
r, l := utf8.DecodeRune(b)
|
|
||||||
return r, b[l:]
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pasteActive && len(b) >= 3 && b[0] == keyEscape && b[1] == '[' {
|
|
||||||
switch b[2] {
|
|
||||||
case 'A':
|
|
||||||
return keyUp, b[3:]
|
|
||||||
case 'B':
|
|
||||||
return keyDown, b[3:]
|
|
||||||
case 'C':
|
|
||||||
return keyRight, b[3:]
|
|
||||||
case 'D':
|
|
||||||
return keyLeft, b[3:]
|
|
||||||
case 'H':
|
|
||||||
return keyHome, b[3:]
|
|
||||||
case 'F':
|
|
||||||
return keyEnd, b[3:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' {
|
|
||||||
switch b[5] {
|
|
||||||
case 'C':
|
|
||||||
return keyAltRight, b[6:]
|
|
||||||
case 'D':
|
|
||||||
return keyAltLeft, b[6:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteStart) {
|
|
||||||
return keyPasteStart, b[6:]
|
|
||||||
}
|
|
||||||
|
|
||||||
if pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteEnd) {
|
|
||||||
return keyPasteEnd, b[6:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we get here then we have a key that we don't recognise, or a
|
|
||||||
// partial sequence. It's not clear how one should find the end of a
|
|
||||||
// sequence without knowing them all, but it seems that [a-zA-Z~] only
|
|
||||||
// appears at the end of a sequence.
|
|
||||||
for i, c := range b[0:] {
|
|
||||||
if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '~' {
|
|
||||||
return keyUnknown, b[i+1:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return utf8.RuneError, b
|
|
||||||
}
|
|
||||||
|
|
||||||
// queue appends data to the end of t.outBuf
|
|
||||||
func (t *Terminal) queue(data []rune) {
|
|
||||||
t.outBuf = append(t.outBuf, []byte(string(data))...)
|
|
||||||
}
|
|
||||||
|
|
||||||
var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'}
|
|
||||||
var space = []rune{' '}
|
|
||||||
|
|
||||||
func isPrintable(key rune) bool {
|
|
||||||
isInSurrogateArea := key >= 0xd800 && key <= 0xdbff
|
|
||||||
return key >= 32 && !isInSurrogateArea
|
|
||||||
}
|
|
||||||
|
|
||||||
// moveCursorToPos appends data to t.outBuf which will move the cursor to the
|
|
||||||
// given, logical position in the text.
|
|
||||||
func (t *Terminal) moveCursorToPos(pos int) {
|
|
||||||
if !t.echo {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
x := visualLength(t.prompt) + pos
|
|
||||||
y := x / t.termWidth
|
|
||||||
x = x % t.termWidth
|
|
||||||
|
|
||||||
up := 0
|
|
||||||
if y < t.cursorY {
|
|
||||||
up = t.cursorY - y
|
|
||||||
}
|
|
||||||
|
|
||||||
down := 0
|
|
||||||
if y > t.cursorY {
|
|
||||||
down = y - t.cursorY
|
|
||||||
}
|
|
||||||
|
|
||||||
left := 0
|
|
||||||
if x < t.cursorX {
|
|
||||||
left = t.cursorX - x
|
|
||||||
}
|
|
||||||
|
|
||||||
right := 0
|
|
||||||
if x > t.cursorX {
|
|
||||||
right = x - t.cursorX
|
|
||||||
}
|
|
||||||
|
|
||||||
t.cursorX = x
|
|
||||||
t.cursorY = y
|
|
||||||
t.move(up, down, left, right)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Terminal) move(up, down, left, right int) {
|
|
||||||
movement := make([]rune, 3*(up+down+left+right))
|
|
||||||
m := movement
|
|
||||||
for i := 0; i < up; i++ {
|
|
||||||
m[0] = keyEscape
|
|
||||||
m[1] = '['
|
|
||||||
m[2] = 'A'
|
|
||||||
m = m[3:]
|
|
||||||
}
|
|
||||||
for i := 0; i < down; i++ {
|
|
||||||
m[0] = keyEscape
|
|
||||||
m[1] = '['
|
|
||||||
m[2] = 'B'
|
|
||||||
m = m[3:]
|
|
||||||
}
|
|
||||||
for i := 0; i < left; i++ {
|
|
||||||
m[0] = keyEscape
|
|
||||||
m[1] = '['
|
|
||||||
m[2] = 'D'
|
|
||||||
m = m[3:]
|
|
||||||
}
|
|
||||||
for i := 0; i < right; i++ {
|
|
||||||
m[0] = keyEscape
|
|
||||||
m[1] = '['
|
|
||||||
m[2] = 'C'
|
|
||||||
m = m[3:]
|
|
||||||
}
|
|
||||||
|
|
||||||
t.queue(movement)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Terminal) clearLineToRight() {
|
|
||||||
op := []rune{keyEscape, '[', 'K'}
|
|
||||||
t.queue(op)
|
|
||||||
}
|
|
||||||
|
|
||||||
const maxLineLength = 4096
|
|
||||||
|
|
||||||
func (t *Terminal) setLine(newLine []rune, newPos int) {
|
|
||||||
if t.echo {
|
|
||||||
t.moveCursorToPos(0)
|
|
||||||
t.writeLine(newLine)
|
|
||||||
for i := len(newLine); i < len(t.line); i++ {
|
|
||||||
t.writeLine(space)
|
|
||||||
}
|
|
||||||
t.moveCursorToPos(newPos)
|
|
||||||
}
|
|
||||||
t.line = newLine
|
|
||||||
t.pos = newPos
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Terminal) advanceCursor(places int) {
|
|
||||||
t.cursorX += places
|
|
||||||
t.cursorY += t.cursorX / t.termWidth
|
|
||||||
if t.cursorY > t.maxLine {
|
|
||||||
t.maxLine = t.cursorY
|
|
||||||
}
|
|
||||||
t.cursorX = t.cursorX % t.termWidth
|
|
||||||
|
|
||||||
if places > 0 && t.cursorX == 0 {
|
|
||||||
// Normally terminals will advance the current position
|
|
||||||
// when writing a character. But that doesn't happen
|
|
||||||
// for the last character in a line. However, when
|
|
||||||
// writing a character (except a new line) that causes
|
|
||||||
// a line wrap, the position will be advanced two
|
|
||||||
// places.
|
|
||||||
//
|
|
||||||
// So, if we are stopping at the end of a line, we
|
|
||||||
// need to write a newline so that our cursor can be
|
|
||||||
// advanced to the next line.
|
|
||||||
t.outBuf = append(t.outBuf, '\n')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Terminal) eraseNPreviousChars(n int) {
|
|
||||||
if n == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if t.pos < n {
|
|
||||||
n = t.pos
|
|
||||||
}
|
|
||||||
t.pos -= n
|
|
||||||
t.moveCursorToPos(t.pos)
|
|
||||||
|
|
||||||
copy(t.line[t.pos:], t.line[n+t.pos:])
|
|
||||||
t.line = t.line[:len(t.line)-n]
|
|
||||||
if t.echo {
|
|
||||||
t.writeLine(t.line[t.pos:])
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
t.queue(space)
|
|
||||||
}
|
|
||||||
t.advanceCursor(n)
|
|
||||||
t.moveCursorToPos(t.pos)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// countToLeftWord returns then number of characters from the cursor to the
|
|
||||||
// start of the previous word.
|
|
||||||
func (t *Terminal) countToLeftWord() int {
|
|
||||||
if t.pos == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
pos := t.pos - 1
|
|
||||||
for pos > 0 {
|
|
||||||
if t.line[pos] != ' ' {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
pos--
|
|
||||||
}
|
|
||||||
for pos > 0 {
|
|
||||||
if t.line[pos] == ' ' {
|
|
||||||
pos++
|
|
||||||
break
|
|
||||||
}
|
|
||||||
pos--
|
|
||||||
}
|
|
||||||
|
|
||||||
return t.pos - pos
|
|
||||||
}
|
|
||||||
|
|
||||||
// countToRightWord returns then number of characters from the cursor to the
|
|
||||||
// start of the next word.
|
|
||||||
func (t *Terminal) countToRightWord() int {
|
|
||||||
pos := t.pos
|
|
||||||
for pos < len(t.line) {
|
|
||||||
if t.line[pos] == ' ' {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
pos++
|
|
||||||
}
|
|
||||||
for pos < len(t.line) {
|
|
||||||
if t.line[pos] != ' ' {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
pos++
|
|
||||||
}
|
|
||||||
return pos - t.pos
|
|
||||||
}
|
|
||||||
|
|
||||||
// visualLength returns the number of visible glyphs in s.
|
|
||||||
func visualLength(runes []rune) int {
|
|
||||||
inEscapeSeq := false
|
|
||||||
length := 0
|
|
||||||
|
|
||||||
for _, r := range runes {
|
|
||||||
switch {
|
|
||||||
case inEscapeSeq:
|
|
||||||
if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') {
|
|
||||||
inEscapeSeq = false
|
|
||||||
}
|
|
||||||
case r == '\x1b':
|
|
||||||
inEscapeSeq = true
|
|
||||||
default:
|
|
||||||
length++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return length
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleKey processes the given key and, optionally, returns a line of text
|
|
||||||
// that the user has entered.
|
|
||||||
func (t *Terminal) handleKey(key rune) (line string, ok bool) {
|
|
||||||
if t.pasteActive && key != keyEnter {
|
|
||||||
t.addKeyToLine(key)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch key {
|
|
||||||
case keyBackspace:
|
|
||||||
if t.pos == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.eraseNPreviousChars(1)
|
|
||||||
case keyAltLeft:
|
|
||||||
// move left by a word.
|
|
||||||
t.pos -= t.countToLeftWord()
|
|
||||||
t.moveCursorToPos(t.pos)
|
|
||||||
case keyAltRight:
|
|
||||||
// move right by a word.
|
|
||||||
t.pos += t.countToRightWord()
|
|
||||||
t.moveCursorToPos(t.pos)
|
|
||||||
case keyLeft:
|
|
||||||
if t.pos == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.pos--
|
|
||||||
t.moveCursorToPos(t.pos)
|
|
||||||
case keyRight:
|
|
||||||
if t.pos == len(t.line) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.pos++
|
|
||||||
t.moveCursorToPos(t.pos)
|
|
||||||
case keyHome:
|
|
||||||
if t.pos == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.pos = 0
|
|
||||||
t.moveCursorToPos(t.pos)
|
|
||||||
case keyEnd:
|
|
||||||
if t.pos == len(t.line) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.pos = len(t.line)
|
|
||||||
t.moveCursorToPos(t.pos)
|
|
||||||
case keyUp:
|
|
||||||
entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1)
|
|
||||||
if !ok {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
if t.historyIndex == -1 {
|
|
||||||
t.historyPending = string(t.line)
|
|
||||||
}
|
|
||||||
t.historyIndex++
|
|
||||||
runes := []rune(entry)
|
|
||||||
t.setLine(runes, len(runes))
|
|
||||||
case keyDown:
|
|
||||||
switch t.historyIndex {
|
|
||||||
case -1:
|
|
||||||
return
|
|
||||||
case 0:
|
|
||||||
runes := []rune(t.historyPending)
|
|
||||||
t.setLine(runes, len(runes))
|
|
||||||
t.historyIndex--
|
|
||||||
default:
|
|
||||||
entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1)
|
|
||||||
if ok {
|
|
||||||
t.historyIndex--
|
|
||||||
runes := []rune(entry)
|
|
||||||
t.setLine(runes, len(runes))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case keyEnter:
|
|
||||||
t.moveCursorToPos(len(t.line))
|
|
||||||
t.queue([]rune("\r\n"))
|
|
||||||
line = string(t.line)
|
|
||||||
ok = true
|
|
||||||
t.line = t.line[:0]
|
|
||||||
t.pos = 0
|
|
||||||
t.cursorX = 0
|
|
||||||
t.cursorY = 0
|
|
||||||
t.maxLine = 0
|
|
||||||
case keyDeleteWord:
|
|
||||||
// Delete zero or more spaces and then one or more characters.
|
|
||||||
t.eraseNPreviousChars(t.countToLeftWord())
|
|
||||||
case keyDeleteLine:
|
|
||||||
// Delete everything from the current cursor position to the
|
|
||||||
// end of line.
|
|
||||||
for i := t.pos; i < len(t.line); i++ {
|
|
||||||
t.queue(space)
|
|
||||||
t.advanceCursor(1)
|
|
||||||
}
|
|
||||||
t.line = t.line[:t.pos]
|
|
||||||
t.moveCursorToPos(t.pos)
|
|
||||||
case keyCtrlD:
|
|
||||||
// Erase the character under the current position.
|
|
||||||
// The EOF case when the line is empty is handled in
|
|
||||||
// readLine().
|
|
||||||
if t.pos < len(t.line) {
|
|
||||||
t.pos++
|
|
||||||
t.eraseNPreviousChars(1)
|
|
||||||
}
|
|
||||||
case keyCtrlU:
|
|
||||||
t.eraseNPreviousChars(t.pos)
|
|
||||||
case keyClearScreen:
|
|
||||||
// Erases the screen and moves the cursor to the home position.
|
|
||||||
t.queue([]rune("\x1b[2J\x1b[H"))
|
|
||||||
t.queue(t.prompt)
|
|
||||||
t.cursorX, t.cursorY = 0, 0
|
|
||||||
t.advanceCursor(visualLength(t.prompt))
|
|
||||||
t.setLine(t.line, t.pos)
|
|
||||||
default:
|
|
||||||
if t.AutoCompleteCallback != nil {
|
|
||||||
prefix := string(t.line[:t.pos])
|
|
||||||
suffix := string(t.line[t.pos:])
|
|
||||||
|
|
||||||
t.lock.Unlock()
|
|
||||||
newLine, newPos, completeOk := t.AutoCompleteCallback(prefix+suffix, len(prefix), key)
|
|
||||||
t.lock.Lock()
|
|
||||||
|
|
||||||
if completeOk {
|
|
||||||
t.setLine([]rune(newLine), utf8.RuneCount([]byte(newLine)[:newPos]))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !isPrintable(key) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(t.line) == maxLineLength {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.addKeyToLine(key)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// addKeyToLine inserts the given key at the current position in the current
|
|
||||||
// line.
|
|
||||||
func (t *Terminal) addKeyToLine(key rune) {
|
|
||||||
if len(t.line) == cap(t.line) {
|
|
||||||
newLine := make([]rune, len(t.line), 2*(1+len(t.line)))
|
|
||||||
copy(newLine, t.line)
|
|
||||||
t.line = newLine
|
|
||||||
}
|
|
||||||
t.line = t.line[:len(t.line)+1]
|
|
||||||
copy(t.line[t.pos+1:], t.line[t.pos:])
|
|
||||||
t.line[t.pos] = key
|
|
||||||
if t.echo {
|
|
||||||
t.writeLine(t.line[t.pos:])
|
|
||||||
}
|
|
||||||
t.pos++
|
|
||||||
t.moveCursorToPos(t.pos)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Terminal) writeLine(line []rune) {
|
|
||||||
for len(line) != 0 {
|
|
||||||
remainingOnLine := t.termWidth - t.cursorX
|
|
||||||
todo := len(line)
|
|
||||||
if todo > remainingOnLine {
|
|
||||||
todo = remainingOnLine
|
|
||||||
}
|
|
||||||
t.queue(line[:todo])
|
|
||||||
t.advanceCursor(visualLength(line[:todo]))
|
|
||||||
line = line[todo:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Terminal) Write(buf []byte) (n int, err error) {
|
|
||||||
t.lock.Lock()
|
|
||||||
defer t.lock.Unlock()
|
|
||||||
|
|
||||||
if t.cursorX == 0 && t.cursorY == 0 {
|
|
||||||
// This is the easy case: there's nothing on the screen that we
|
|
||||||
// have to move out of the way.
|
|
||||||
return t.c.Write(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have a prompt and possibly user input on the screen. We
|
|
||||||
// have to clear it first.
|
|
||||||
t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */)
|
|
||||||
t.cursorX = 0
|
|
||||||
t.clearLineToRight()
|
|
||||||
|
|
||||||
for t.cursorY > 0 {
|
|
||||||
t.move(1 /* up */, 0, 0, 0)
|
|
||||||
t.cursorY--
|
|
||||||
t.clearLineToRight()
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = t.c.Write(t.outBuf); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.outBuf = t.outBuf[:0]
|
|
||||||
|
|
||||||
if n, err = t.c.Write(buf); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
t.writeLine(t.prompt)
|
|
||||||
if t.echo {
|
|
||||||
t.writeLine(t.line)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.moveCursorToPos(t.pos)
|
|
||||||
|
|
||||||
if _, err = t.c.Write(t.outBuf); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.outBuf = t.outBuf[:0]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadPassword temporarily changes the prompt and reads a password, without
|
|
||||||
// echo, from the terminal.
|
|
||||||
func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
|
|
||||||
t.lock.Lock()
|
|
||||||
defer t.lock.Unlock()
|
|
||||||
|
|
||||||
oldPrompt := t.prompt
|
|
||||||
t.prompt = []rune(prompt)
|
|
||||||
t.echo = false
|
|
||||||
|
|
||||||
line, err = t.readLine()
|
|
||||||
|
|
||||||
t.prompt = oldPrompt
|
|
||||||
t.echo = true
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadLine returns a line of input from the terminal.
|
|
||||||
func (t *Terminal) ReadLine() (line string, err error) {
|
|
||||||
t.lock.Lock()
|
|
||||||
defer t.lock.Unlock()
|
|
||||||
|
|
||||||
return t.readLine()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Terminal) readLine() (line string, err error) {
|
|
||||||
// t.lock must be held at this point
|
|
||||||
|
|
||||||
if t.cursorX == 0 && t.cursorY == 0 {
|
|
||||||
t.writeLine(t.prompt)
|
|
||||||
t.c.Write(t.outBuf)
|
|
||||||
t.outBuf = t.outBuf[:0]
|
|
||||||
}
|
|
||||||
|
|
||||||
lineIsPasted := t.pasteActive
|
|
||||||
|
|
||||||
for {
|
|
||||||
rest := t.remainder
|
|
||||||
lineOk := false
|
|
||||||
for !lineOk {
|
|
||||||
var key rune
|
|
||||||
key, rest = bytesToKey(rest, t.pasteActive)
|
|
||||||
if key == utf8.RuneError {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if !t.pasteActive {
|
|
||||||
if key == keyCtrlD {
|
|
||||||
if len(t.line) == 0 {
|
|
||||||
return "", io.EOF
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if key == keyPasteStart {
|
|
||||||
t.pasteActive = true
|
|
||||||
if len(t.line) == 0 {
|
|
||||||
lineIsPasted = true
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
} else if key == keyPasteEnd {
|
|
||||||
t.pasteActive = false
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !t.pasteActive {
|
|
||||||
lineIsPasted = false
|
|
||||||
}
|
|
||||||
line, lineOk = t.handleKey(key)
|
|
||||||
}
|
|
||||||
if len(rest) > 0 {
|
|
||||||
n := copy(t.inBuf[:], rest)
|
|
||||||
t.remainder = t.inBuf[:n]
|
|
||||||
} else {
|
|
||||||
t.remainder = nil
|
|
||||||
}
|
|
||||||
t.c.Write(t.outBuf)
|
|
||||||
t.outBuf = t.outBuf[:0]
|
|
||||||
if lineOk {
|
|
||||||
if t.echo {
|
|
||||||
t.historyIndex = -1
|
|
||||||
t.history.Add(line)
|
|
||||||
}
|
|
||||||
if lineIsPasted {
|
|
||||||
err = ErrPasteIndicator
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.remainder is a slice at the beginning of t.inBuf
|
|
||||||
// containing a partial key sequence
|
|
||||||
readBuf := t.inBuf[len(t.remainder):]
|
|
||||||
var n int
|
|
||||||
|
|
||||||
t.lock.Unlock()
|
|
||||||
n, err = t.c.Read(readBuf)
|
|
||||||
t.lock.Lock()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
t.remainder = t.inBuf[:n+len(t.remainder)]
|
|
||||||
}
|
|
||||||
|
|
||||||
panic("unreachable") // for Go 1.0.
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPrompt sets the prompt to be used when reading subsequent lines.
|
|
||||||
func (t *Terminal) SetPrompt(prompt string) {
|
|
||||||
t.lock.Lock()
|
|
||||||
defer t.lock.Unlock()
|
|
||||||
|
|
||||||
t.prompt = []rune(prompt)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) {
|
|
||||||
// Move cursor to column zero at the start of the line.
|
|
||||||
t.move(t.cursorY, 0, t.cursorX, 0)
|
|
||||||
t.cursorX, t.cursorY = 0, 0
|
|
||||||
t.clearLineToRight()
|
|
||||||
for t.cursorY < numPrevLines {
|
|
||||||
// Move down a line
|
|
||||||
t.move(0, 1, 0, 0)
|
|
||||||
t.cursorY++
|
|
||||||
t.clearLineToRight()
|
|
||||||
}
|
|
||||||
// Move back to beginning.
|
|
||||||
t.move(t.cursorY, 0, 0, 0)
|
|
||||||
t.cursorX, t.cursorY = 0, 0
|
|
||||||
|
|
||||||
t.queue(t.prompt)
|
|
||||||
t.advanceCursor(visualLength(t.prompt))
|
|
||||||
t.writeLine(t.line)
|
|
||||||
t.moveCursorToPos(t.pos)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Terminal) SetSize(width, height int) error {
|
|
||||||
t.lock.Lock()
|
|
||||||
defer t.lock.Unlock()
|
|
||||||
|
|
||||||
if width == 0 {
|
|
||||||
width = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
oldWidth := t.termWidth
|
|
||||||
t.termWidth, t.termHeight = width, height
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case width == oldWidth:
|
|
||||||
// If the width didn't change then nothing else needs to be
|
|
||||||
// done.
|
|
||||||
return nil
|
|
||||||
case len(t.line) == 0 && t.cursorX == 0 && t.cursorY == 0:
|
|
||||||
// If there is nothing on current line and no prompt printed,
|
|
||||||
// just do nothing
|
|
||||||
return nil
|
|
||||||
case width < oldWidth:
|
|
||||||
// Some terminals (e.g. xterm) will truncate lines that were
|
|
||||||
// too long when shinking. Others, (e.g. gnome-terminal) will
|
|
||||||
// attempt to wrap them. For the former, repainting t.maxLine
|
|
||||||
// works great, but that behaviour goes badly wrong in the case
|
|
||||||
// of the latter because they have doubled every full line.
|
|
||||||
|
|
||||||
// We assume that we are working on a terminal that wraps lines
|
|
||||||
// and adjust the cursor position based on every previous line
|
|
||||||
// wrapping and turning into two. This causes the prompt on
|
|
||||||
// xterms to move upwards, which isn't great, but it avoids a
|
|
||||||
// huge mess with gnome-terminal.
|
|
||||||
if t.cursorX >= t.termWidth {
|
|
||||||
t.cursorX = t.termWidth - 1
|
|
||||||
}
|
|
||||||
t.cursorY *= 2
|
|
||||||
t.clearAndRepaintLinePlusNPrevious(t.maxLine * 2)
|
|
||||||
case width > oldWidth:
|
|
||||||
// If the terminal expands then our position calculations will
|
|
||||||
// be wrong in the future because we think the cursor is
|
|
||||||
// |t.pos| chars into the string, but there will be a gap at
|
|
||||||
// the end of any wrapped line.
|
|
||||||
//
|
|
||||||
// But the position will actually be correct until we move, so
|
|
||||||
// we can move back to the beginning and repaint everything.
|
|
||||||
t.clearAndRepaintLinePlusNPrevious(t.maxLine)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := t.c.Write(t.outBuf)
|
|
||||||
t.outBuf = t.outBuf[:0]
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type pasteIndicatorError struct{}
|
|
||||||
|
|
||||||
func (pasteIndicatorError) Error() string {
|
|
||||||
return "terminal: ErrPasteIndicator not correctly handled"
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrPasteIndicator may be returned from ReadLine as the error, in addition
|
|
||||||
// to valid line data. It indicates that bracketed paste mode is enabled and
|
|
||||||
// that the returned line consists only of pasted data. Programs may wish to
|
|
||||||
// interpret pasted data more literally than typed data.
|
|
||||||
var ErrPasteIndicator = pasteIndicatorError{}
|
|
||||||
|
|
||||||
// SetBracketedPasteMode requests that the terminal bracket paste operations
|
|
||||||
// with markers. Not all terminals support this but, if it is supported, then
|
|
||||||
// enabling this mode will stop any autocomplete callback from running due to
|
|
||||||
// pastes. Additionally, any lines that are completely pasted will be returned
|
|
||||||
// from ReadLine with the error set to ErrPasteIndicator.
|
|
||||||
func (t *Terminal) SetBracketedPasteMode(on bool) {
|
|
||||||
if on {
|
|
||||||
io.WriteString(t.c, "\x1b[?2004h")
|
|
||||||
} else {
|
|
||||||
io.WriteString(t.c, "\x1b[?2004l")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// stRingBuffer is a ring buffer of strings.
|
|
||||||
type stRingBuffer struct {
|
|
||||||
// entries contains max elements.
|
|
||||||
entries []string
|
|
||||||
max int
|
|
||||||
// head contains the index of the element most recently added to the ring.
|
|
||||||
head int
|
|
||||||
// size contains the number of elements in the ring.
|
|
||||||
size int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stRingBuffer) Add(a string) {
|
|
||||||
if s.entries == nil {
|
|
||||||
const defaultNumEntries = 100
|
|
||||||
s.entries = make([]string, defaultNumEntries)
|
|
||||||
s.max = defaultNumEntries
|
|
||||||
}
|
|
||||||
|
|
||||||
s.head = (s.head + 1) % s.max
|
|
||||||
s.entries[s.head] = a
|
|
||||||
if s.size < s.max {
|
|
||||||
s.size++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NthPreviousEntry returns the value passed to the nth previous call to Add.
|
|
||||||
// If n is zero then the immediately prior value is returned, if one, then the
|
|
||||||
// next most recent, and so on. If such an element doesn't exist then ok is
|
|
||||||
// false.
|
|
||||||
func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) {
|
|
||||||
if n >= s.size {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
index := s.head - n
|
|
||||||
if index < 0 {
|
|
||||||
index += s.max
|
|
||||||
}
|
|
||||||
return s.entries[index], true
|
|
||||||
}
|
|
||||||
128
vendor/golang.org/x/crypto/ssh/terminal/util.go
generated
vendored
128
vendor/golang.org/x/crypto/ssh/terminal/util.go
generated
vendored
@ -1,128 +0,0 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd
|
|
||||||
|
|
||||||
// Package terminal provides support functions for dealing with terminals, as
|
|
||||||
// commonly found on UNIX systems.
|
|
||||||
//
|
|
||||||
// Putting a terminal into raw mode is the most common requirement:
|
|
||||||
//
|
|
||||||
// oldState, err := terminal.MakeRaw(0)
|
|
||||||
// if err != nil {
|
|
||||||
// panic(err)
|
|
||||||
// }
|
|
||||||
// defer terminal.Restore(0, oldState)
|
|
||||||
package terminal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// State contains the state of a terminal.
|
|
||||||
type State struct {
|
|
||||||
termios syscall.Termios
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
|
||||||
func IsTerminal(fd int) bool {
|
|
||||||
var termios syscall.Termios
|
|
||||||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
|
|
||||||
return err == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeRaw put the terminal connected to the given file descriptor into raw
|
|
||||||
// mode and returns the previous state of the terminal so that it can be
|
|
||||||
// restored.
|
|
||||||
func MakeRaw(fd int) (*State, error) {
|
|
||||||
var oldState State
|
|
||||||
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
newState := oldState.termios
|
|
||||||
newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXON | syscall.IXOFF
|
|
||||||
newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG
|
|
||||||
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &oldState, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetState returns the current state of a terminal which may be useful to
|
|
||||||
// restore the terminal after a signal.
|
|
||||||
func GetState(fd int) (*State, error) {
|
|
||||||
var oldState State
|
|
||||||
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &oldState, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore restores the terminal connected to the given file descriptor to a
|
|
||||||
// previous state.
|
|
||||||
func Restore(fd int, state *State) error {
|
|
||||||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSize returns the dimensions of the given terminal.
|
|
||||||
func GetSize(fd int) (width, height int, err error) {
|
|
||||||
var dimensions [4]uint16
|
|
||||||
|
|
||||||
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 {
|
|
||||||
return -1, -1, err
|
|
||||||
}
|
|
||||||
return int(dimensions[1]), int(dimensions[0]), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadPassword reads a line of input from a terminal without local echo. This
|
|
||||||
// is commonly used for inputting passwords and other sensitive data. The slice
|
|
||||||
// returned does not include the \n.
|
|
||||||
func ReadPassword(fd int) ([]byte, error) {
|
|
||||||
var oldState syscall.Termios
|
|
||||||
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); err != 0 {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
newState := oldState
|
|
||||||
newState.Lflag &^= syscall.ECHO
|
|
||||||
newState.Lflag |= syscall.ICANON | syscall.ISIG
|
|
||||||
newState.Iflag |= syscall.ICRNL
|
|
||||||
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0)
|
|
||||||
}()
|
|
||||||
|
|
||||||
var buf [16]byte
|
|
||||||
var ret []byte
|
|
||||||
for {
|
|
||||||
n, err := syscall.Read(fd, buf[:])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if n == 0 {
|
|
||||||
if len(ret) == 0 {
|
|
||||||
return nil, io.EOF
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if buf[n-1] == '\n' {
|
|
||||||
n--
|
|
||||||
}
|
|
||||||
ret = append(ret, buf[:n]...)
|
|
||||||
if n < len(buf) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
12
vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go
generated
vendored
12
vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build darwin dragonfly freebsd netbsd openbsd
|
|
||||||
|
|
||||||
package terminal
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
const ioctlReadTermios = syscall.TIOCGETA
|
|
||||||
const ioctlWriteTermios = syscall.TIOCSETA
|
|
||||||
11
vendor/golang.org/x/crypto/ssh/terminal/util_linux.go
generated
vendored
11
vendor/golang.org/x/crypto/ssh/terminal/util_linux.go
generated
vendored
@ -1,11 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package terminal
|
|
||||||
|
|
||||||
// These constants are declared here, rather than importing
|
|
||||||
// them from the syscall package as some syscall packages, even
|
|
||||||
// on linux, for example gccgo, do not declare them.
|
|
||||||
const ioctlReadTermios = 0x5401 // syscall.TCGETS
|
|
||||||
const ioctlWriteTermios = 0x5402 // syscall.TCSETS
|
|
||||||
174
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
generated
vendored
174
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
generated
vendored
@ -1,174 +0,0 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build windows
|
|
||||||
|
|
||||||
// Package terminal provides support functions for dealing with terminals, as
|
|
||||||
// commonly found on UNIX systems.
|
|
||||||
//
|
|
||||||
// Putting a terminal into raw mode is the most common requirement:
|
|
||||||
//
|
|
||||||
// oldState, err := terminal.MakeRaw(0)
|
|
||||||
// if err != nil {
|
|
||||||
// panic(err)
|
|
||||||
// }
|
|
||||||
// defer terminal.Restore(0, oldState)
|
|
||||||
package terminal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
enableLineInput = 2
|
|
||||||
enableEchoInput = 4
|
|
||||||
enableProcessedInput = 1
|
|
||||||
enableWindowInput = 8
|
|
||||||
enableMouseInput = 16
|
|
||||||
enableInsertMode = 32
|
|
||||||
enableQuickEditMode = 64
|
|
||||||
enableExtendedFlags = 128
|
|
||||||
enableAutoPosition = 256
|
|
||||||
enableProcessedOutput = 1
|
|
||||||
enableWrapAtEolOutput = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
||||||
|
|
||||||
var (
|
|
||||||
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
|
||||||
procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
|
|
||||||
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
short int16
|
|
||||||
word uint16
|
|
||||||
|
|
||||||
coord struct {
|
|
||||||
x short
|
|
||||||
y short
|
|
||||||
}
|
|
||||||
smallRect struct {
|
|
||||||
left short
|
|
||||||
top short
|
|
||||||
right short
|
|
||||||
bottom short
|
|
||||||
}
|
|
||||||
consoleScreenBufferInfo struct {
|
|
||||||
size coord
|
|
||||||
cursorPosition coord
|
|
||||||
attributes word
|
|
||||||
window smallRect
|
|
||||||
maximumWindowSize coord
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
type State struct {
|
|
||||||
mode uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
|
||||||
func IsTerminal(fd int) bool {
|
|
||||||
var st uint32
|
|
||||||
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
|
|
||||||
return r != 0 && e == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeRaw put the terminal connected to the given file descriptor into raw
|
|
||||||
// mode and returns the previous state of the terminal so that it can be
|
|
||||||
// restored.
|
|
||||||
func MakeRaw(fd int) (*State, error) {
|
|
||||||
var st uint32
|
|
||||||
_, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
|
|
||||||
if e != 0 {
|
|
||||||
return nil, error(e)
|
|
||||||
}
|
|
||||||
st &^= (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput)
|
|
||||||
_, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(st), 0)
|
|
||||||
if e != 0 {
|
|
||||||
return nil, error(e)
|
|
||||||
}
|
|
||||||
return &State{st}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetState returns the current state of a terminal which may be useful to
|
|
||||||
// restore the terminal after a signal.
|
|
||||||
func GetState(fd int) (*State, error) {
|
|
||||||
var st uint32
|
|
||||||
_, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
|
|
||||||
if e != 0 {
|
|
||||||
return nil, error(e)
|
|
||||||
}
|
|
||||||
return &State{st}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore restores the terminal connected to the given file descriptor to a
|
|
||||||
// previous state.
|
|
||||||
func Restore(fd int, state *State) error {
|
|
||||||
_, _, err := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(state.mode), 0)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSize returns the dimensions of the given terminal.
|
|
||||||
func GetSize(fd int) (width, height int, err error) {
|
|
||||||
var info consoleScreenBufferInfo
|
|
||||||
_, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&info)), 0)
|
|
||||||
if e != 0 {
|
|
||||||
return 0, 0, error(e)
|
|
||||||
}
|
|
||||||
return int(info.size.x), int(info.size.y), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadPassword reads a line of input from a terminal without local echo. This
|
|
||||||
// is commonly used for inputting passwords and other sensitive data. The slice
|
|
||||||
// returned does not include the \n.
|
|
||||||
func ReadPassword(fd int) ([]byte, error) {
|
|
||||||
var st uint32
|
|
||||||
_, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
|
|
||||||
if e != 0 {
|
|
||||||
return nil, error(e)
|
|
||||||
}
|
|
||||||
old := st
|
|
||||||
|
|
||||||
st &^= (enableEchoInput)
|
|
||||||
st |= (enableProcessedInput | enableLineInput | enableProcessedOutput)
|
|
||||||
_, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(st), 0)
|
|
||||||
if e != 0 {
|
|
||||||
return nil, error(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(old), 0)
|
|
||||||
}()
|
|
||||||
|
|
||||||
var buf [16]byte
|
|
||||||
var ret []byte
|
|
||||||
for {
|
|
||||||
n, err := syscall.Read(syscall.Handle(fd), buf[:])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if n == 0 {
|
|
||||||
if len(ret) == 0 {
|
|
||||||
return nil, io.EOF
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if buf[n-1] == '\n' {
|
|
||||||
n--
|
|
||||||
}
|
|
||||||
if n > 0 && buf[n-1] == '\r' {
|
|
||||||
n--
|
|
||||||
}
|
|
||||||
ret = append(ret, buf[:n]...)
|
|
||||||
if n < len(buf) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user