зеркало из https://github.com/microsoft/docker.git
Merge pull request #16060 from vdemeester/14756-lint-pkg-term-windows
Lint pkg/term/windows package
This commit is contained in:
Коммит
07d2eae6d5
|
@ -88,6 +88,7 @@ packages=(
|
|||
pkg/tailfile
|
||||
pkg/tarsum
|
||||
pkg/term
|
||||
pkg/term/windows
|
||||
pkg/timeoutconn
|
||||
pkg/timeutils
|
||||
pkg/tlsconfig
|
||||
|
|
|
@ -10,8 +10,8 @@ import (
|
|||
"strings"
|
||||
"unsafe"
|
||||
|
||||
. "github.com/Azure/go-ansiterm"
|
||||
. "github.com/Azure/go-ansiterm/winterm"
|
||||
ansiterm "github.com/Azure/go-ansiterm"
|
||||
"github.com/Azure/go-ansiterm/winterm"
|
||||
)
|
||||
|
||||
// ansiReader wraps a standard input file (e.g., os.Stdin) providing ANSI sequence translation.
|
||||
|
@ -26,12 +26,12 @@ type ansiReader struct {
|
|||
}
|
||||
|
||||
func newAnsiReader(nFile int) *ansiReader {
|
||||
file, fd := GetStdFile(nFile)
|
||||
file, fd := winterm.GetStdFile(nFile)
|
||||
return &ansiReader{
|
||||
file: file,
|
||||
fd: fd,
|
||||
command: make([]byte, 0, ANSI_MAX_CMD_LENGTH),
|
||||
escapeSequence: []byte(KEY_ESC_CSI),
|
||||
command: make([]byte, 0, ansiterm.ANSI_MAX_CMD_LENGTH),
|
||||
escapeSequence: []byte(ansiterm.KEY_ESC_CSI),
|
||||
buffer: make([]byte, 0),
|
||||
}
|
||||
}
|
||||
|
@ -101,28 +101,28 @@ func (ar *ansiReader) Read(p []byte) (int, error) {
|
|||
}
|
||||
|
||||
// readInputEvents polls until at least one event is available.
|
||||
func readInputEvents(fd uintptr, maxBytes int) ([]INPUT_RECORD, error) {
|
||||
func readInputEvents(fd uintptr, maxBytes int) ([]winterm.INPUT_RECORD, error) {
|
||||
// Determine the maximum number of records to retrieve
|
||||
// -- Cast around the type system to obtain the size of a single INPUT_RECORD.
|
||||
// unsafe.Sizeof requires an expression vs. a type-reference; the casting
|
||||
// tricks the type system into believing it has such an expression.
|
||||
recordSize := int(unsafe.Sizeof(*((*INPUT_RECORD)(unsafe.Pointer(&maxBytes)))))
|
||||
recordSize := int(unsafe.Sizeof(*((*winterm.INPUT_RECORD)(unsafe.Pointer(&maxBytes)))))
|
||||
countRecords := maxBytes / recordSize
|
||||
if countRecords > MAX_INPUT_EVENTS {
|
||||
countRecords = MAX_INPUT_EVENTS
|
||||
if countRecords > ansiterm.MAX_INPUT_EVENTS {
|
||||
countRecords = ansiterm.MAX_INPUT_EVENTS
|
||||
}
|
||||
logger.Debugf("[windows] readInputEvents: Reading %v records (buffer size %v, record size %v)", countRecords, maxBytes, recordSize)
|
||||
|
||||
// Wait for and read input events
|
||||
events := make([]INPUT_RECORD, countRecords)
|
||||
events := make([]winterm.INPUT_RECORD, countRecords)
|
||||
nEvents := uint32(0)
|
||||
eventsExist, err := WaitForSingleObject(fd, WAIT_INFINITE)
|
||||
eventsExist, err := winterm.WaitForSingleObject(fd, winterm.WAIT_INFINITE)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if eventsExist {
|
||||
err = ReadConsoleInput(fd, events, &nEvents)
|
||||
err = winterm.ReadConsoleInput(fd, events, &nEvents)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -135,43 +135,43 @@ func readInputEvents(fd uintptr, maxBytes int) ([]INPUT_RECORD, error) {
|
|||
|
||||
// KeyEvent Translation Helpers
|
||||
|
||||
var arrowKeyMapPrefix = map[WORD]string{
|
||||
VK_UP: "%s%sA",
|
||||
VK_DOWN: "%s%sB",
|
||||
VK_RIGHT: "%s%sC",
|
||||
VK_LEFT: "%s%sD",
|
||||
var arrowKeyMapPrefix = map[winterm.WORD]string{
|
||||
winterm.VK_UP: "%s%sA",
|
||||
winterm.VK_DOWN: "%s%sB",
|
||||
winterm.VK_RIGHT: "%s%sC",
|
||||
winterm.VK_LEFT: "%s%sD",
|
||||
}
|
||||
|
||||
var keyMapPrefix = map[WORD]string{
|
||||
VK_UP: "\x1B[%sA",
|
||||
VK_DOWN: "\x1B[%sB",
|
||||
VK_RIGHT: "\x1B[%sC",
|
||||
VK_LEFT: "\x1B[%sD",
|
||||
VK_HOME: "\x1B[1%s~", // showkey shows ^[[1
|
||||
VK_END: "\x1B[4%s~", // showkey shows ^[[4
|
||||
VK_INSERT: "\x1B[2%s~",
|
||||
VK_DELETE: "\x1B[3%s~",
|
||||
VK_PRIOR: "\x1B[5%s~",
|
||||
VK_NEXT: "\x1B[6%s~",
|
||||
VK_F1: "",
|
||||
VK_F2: "",
|
||||
VK_F3: "\x1B[13%s~",
|
||||
VK_F4: "\x1B[14%s~",
|
||||
VK_F5: "\x1B[15%s~",
|
||||
VK_F6: "\x1B[17%s~",
|
||||
VK_F7: "\x1B[18%s~",
|
||||
VK_F8: "\x1B[19%s~",
|
||||
VK_F9: "\x1B[20%s~",
|
||||
VK_F10: "\x1B[21%s~",
|
||||
VK_F11: "\x1B[23%s~",
|
||||
VK_F12: "\x1B[24%s~",
|
||||
var keyMapPrefix = map[winterm.WORD]string{
|
||||
winterm.VK_UP: "\x1B[%sA",
|
||||
winterm.VK_DOWN: "\x1B[%sB",
|
||||
winterm.VK_RIGHT: "\x1B[%sC",
|
||||
winterm.VK_LEFT: "\x1B[%sD",
|
||||
winterm.VK_HOME: "\x1B[1%s~", // showkey shows ^[[1
|
||||
winterm.VK_END: "\x1B[4%s~", // showkey shows ^[[4
|
||||
winterm.VK_INSERT: "\x1B[2%s~",
|
||||
winterm.VK_DELETE: "\x1B[3%s~",
|
||||
winterm.VK_PRIOR: "\x1B[5%s~",
|
||||
winterm.VK_NEXT: "\x1B[6%s~",
|
||||
winterm.VK_F1: "",
|
||||
winterm.VK_F2: "",
|
||||
winterm.VK_F3: "\x1B[13%s~",
|
||||
winterm.VK_F4: "\x1B[14%s~",
|
||||
winterm.VK_F5: "\x1B[15%s~",
|
||||
winterm.VK_F6: "\x1B[17%s~",
|
||||
winterm.VK_F7: "\x1B[18%s~",
|
||||
winterm.VK_F8: "\x1B[19%s~",
|
||||
winterm.VK_F9: "\x1B[20%s~",
|
||||
winterm.VK_F10: "\x1B[21%s~",
|
||||
winterm.VK_F11: "\x1B[23%s~",
|
||||
winterm.VK_F12: "\x1B[24%s~",
|
||||
}
|
||||
|
||||
// translateKeyEvents converts the input events into the appropriate ANSI string.
|
||||
func translateKeyEvents(events []INPUT_RECORD, escapeSequence []byte) []byte {
|
||||
func translateKeyEvents(events []winterm.INPUT_RECORD, escapeSequence []byte) []byte {
|
||||
var buffer bytes.Buffer
|
||||
for _, event := range events {
|
||||
if event.EventType == KEY_EVENT && event.KeyEvent.KeyDown != 0 {
|
||||
if event.EventType == winterm.KEY_EVENT && event.KeyEvent.KeyDown != 0 {
|
||||
buffer.WriteString(keyToString(&event.KeyEvent, escapeSequence))
|
||||
}
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ func translateKeyEvents(events []INPUT_RECORD, escapeSequence []byte) []byte {
|
|||
}
|
||||
|
||||
// keyToString maps the given input event record to the corresponding string.
|
||||
func keyToString(keyEvent *KEY_EVENT_RECORD, escapeSequence []byte) string {
|
||||
func keyToString(keyEvent *winterm.KEY_EVENT_RECORD, escapeSequence []byte) string {
|
||||
if keyEvent.UnicodeChar == 0 {
|
||||
return formatVirtualKey(keyEvent.VirtualKeyCode, keyEvent.ControlKeyState, escapeSequence)
|
||||
}
|
||||
|
@ -199,14 +199,14 @@ func keyToString(keyEvent *KEY_EVENT_RECORD, escapeSequence []byte) string {
|
|||
|
||||
// <Alt>+Key generates ESC N Key
|
||||
if !control && alt {
|
||||
return KEY_ESC_N + strings.ToLower(string(keyEvent.UnicodeChar))
|
||||
return ansiterm.KEY_ESC_N + strings.ToLower(string(keyEvent.UnicodeChar))
|
||||
}
|
||||
|
||||
return string(keyEvent.UnicodeChar)
|
||||
}
|
||||
|
||||
// formatVirtualKey converts a virtual key (e.g., up arrow) into the appropriate ANSI string.
|
||||
func formatVirtualKey(key WORD, controlState DWORD, escapeSequence []byte) string {
|
||||
func formatVirtualKey(key winterm.WORD, controlState winterm.DWORD, escapeSequence []byte) string {
|
||||
shift, alt, control := getControlKeys(controlState)
|
||||
modifier := getControlKeysModifier(shift, alt, control, false)
|
||||
|
||||
|
@ -222,35 +222,35 @@ func formatVirtualKey(key WORD, controlState DWORD, escapeSequence []byte) strin
|
|||
}
|
||||
|
||||
// getControlKeys extracts the shift, alt, and ctrl key states.
|
||||
func getControlKeys(controlState DWORD) (shift, alt, control bool) {
|
||||
shift = 0 != (controlState & SHIFT_PRESSED)
|
||||
alt = 0 != (controlState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
|
||||
control = 0 != (controlState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
||||
func getControlKeys(controlState winterm.DWORD) (shift, alt, control bool) {
|
||||
shift = 0 != (controlState & winterm.SHIFT_PRESSED)
|
||||
alt = 0 != (controlState & (winterm.LEFT_ALT_PRESSED | winterm.RIGHT_ALT_PRESSED))
|
||||
control = 0 != (controlState & (winterm.LEFT_CTRL_PRESSED | winterm.RIGHT_CTRL_PRESSED))
|
||||
return shift, alt, control
|
||||
}
|
||||
|
||||
// getControlKeysModifier returns the ANSI modifier for the given combination of control keys.
|
||||
func getControlKeysModifier(shift, alt, control, meta bool) string {
|
||||
if shift && alt && control {
|
||||
return KEY_CONTROL_PARAM_8
|
||||
return ansiterm.KEY_CONTROL_PARAM_8
|
||||
}
|
||||
if alt && control {
|
||||
return KEY_CONTROL_PARAM_7
|
||||
return ansiterm.KEY_CONTROL_PARAM_7
|
||||
}
|
||||
if shift && control {
|
||||
return KEY_CONTROL_PARAM_6
|
||||
return ansiterm.KEY_CONTROL_PARAM_6
|
||||
}
|
||||
if control {
|
||||
return KEY_CONTROL_PARAM_5
|
||||
return ansiterm.KEY_CONTROL_PARAM_5
|
||||
}
|
||||
if shift && alt {
|
||||
return KEY_CONTROL_PARAM_4
|
||||
return ansiterm.KEY_CONTROL_PARAM_4
|
||||
}
|
||||
if alt {
|
||||
return KEY_CONTROL_PARAM_3
|
||||
return ansiterm.KEY_CONTROL_PARAM_3
|
||||
}
|
||||
if shift {
|
||||
return KEY_CONTROL_PARAM_2
|
||||
return ansiterm.KEY_CONTROL_PARAM_2
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
. "github.com/Azure/go-ansiterm"
|
||||
. "github.com/Azure/go-ansiterm/winterm"
|
||||
ansiterm "github.com/Azure/go-ansiterm"
|
||||
"github.com/Azure/go-ansiterm/winterm"
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@ -17,17 +17,17 @@ var logger *logrus.Logger
|
|||
type ansiWriter struct {
|
||||
file *os.File
|
||||
fd uintptr
|
||||
infoReset *CONSOLE_SCREEN_BUFFER_INFO
|
||||
infoReset *winterm.CONSOLE_SCREEN_BUFFER_INFO
|
||||
command []byte
|
||||
escapeSequence []byte
|
||||
inAnsiSequence bool
|
||||
parser *AnsiParser
|
||||
parser *ansiterm.AnsiParser
|
||||
}
|
||||
|
||||
func newAnsiWriter(nFile int) *ansiWriter {
|
||||
logFile := ioutil.Discard
|
||||
|
||||
if isDebugEnv := os.Getenv(LogEnv); isDebugEnv == "1" {
|
||||
if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" {
|
||||
logFile, _ = os.Create("ansiReaderWriter.log")
|
||||
}
|
||||
|
||||
|
@ -37,21 +37,21 @@ func newAnsiWriter(nFile int) *ansiWriter {
|
|||
Level: logrus.DebugLevel,
|
||||
}
|
||||
|
||||
file, fd := GetStdFile(nFile)
|
||||
info, err := GetConsoleScreenBufferInfo(fd)
|
||||
file, fd := winterm.GetStdFile(nFile)
|
||||
info, err := winterm.GetConsoleScreenBufferInfo(fd)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
parser := CreateParser("Ground", CreateWinEventHandler(fd, file))
|
||||
parser := ansiterm.CreateParser("Ground", winterm.CreateWinEventHandler(fd, file))
|
||||
logger.Infof("newAnsiWriter: parser %p", parser)
|
||||
|
||||
aw := &ansiWriter{
|
||||
file: file,
|
||||
fd: fd,
|
||||
infoReset: info,
|
||||
command: make([]byte, 0, ANSI_MAX_CMD_LENGTH),
|
||||
escapeSequence: []byte(KEY_ESC_CSI),
|
||||
command: make([]byte, 0, ansiterm.ANSI_MAX_CMD_LENGTH),
|
||||
escapeSequence: []byte(ansiterm.KEY_ESC_CSI),
|
||||
parser: parser,
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@ import (
|
|||
"os"
|
||||
"syscall"
|
||||
|
||||
. "github.com/Azure/go-ansiterm/winterm"
|
||||
"github.com/Azure/go-ansiterm/winterm"
|
||||
)
|
||||
|
||||
// ConsoleStreams, for each standard stream referencing a console, returns a wrapped version
|
||||
// ConsoleStreams returns a wrapped version for each standard stream referencing a console,
|
||||
// that handles ANSI character sequences.
|
||||
func ConsoleStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
|
||||
if IsConsole(os.Stdin.Fd()) {
|
||||
|
@ -56,6 +56,6 @@ func GetHandleInfo(in interface{}) (uintptr, bool) {
|
|||
// IsConsole returns true if the given file descriptor is a Windows Console.
|
||||
// The code assumes that GetConsoleMode will return an error for file descriptors that are not a console.
|
||||
func IsConsole(fd uintptr) bool {
|
||||
_, e := GetConsoleMode(fd)
|
||||
_, e := winterm.GetConsoleMode(fd)
|
||||
return e == nil
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче