mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 10:03:42 +08:00 
			
		
		
		
	vendor: initial vendor
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
		
							
								
								
									
										182
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/ansi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/ansi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,182 @@
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package winterm
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"syscall"
 | 
			
		||||
 | 
			
		||||
	"github.com/Azure/go-ansiterm"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Windows keyboard constants
 | 
			
		||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx.
 | 
			
		||||
const (
 | 
			
		||||
	VK_PRIOR    = 0x21 // PAGE UP key
 | 
			
		||||
	VK_NEXT     = 0x22 // PAGE DOWN key
 | 
			
		||||
	VK_END      = 0x23 // END key
 | 
			
		||||
	VK_HOME     = 0x24 // HOME key
 | 
			
		||||
	VK_LEFT     = 0x25 // LEFT ARROW key
 | 
			
		||||
	VK_UP       = 0x26 // UP ARROW key
 | 
			
		||||
	VK_RIGHT    = 0x27 // RIGHT ARROW key
 | 
			
		||||
	VK_DOWN     = 0x28 // DOWN ARROW key
 | 
			
		||||
	VK_SELECT   = 0x29 // SELECT key
 | 
			
		||||
	VK_PRINT    = 0x2A // PRINT key
 | 
			
		||||
	VK_EXECUTE  = 0x2B // EXECUTE key
 | 
			
		||||
	VK_SNAPSHOT = 0x2C // PRINT SCREEN key
 | 
			
		||||
	VK_INSERT   = 0x2D // INS key
 | 
			
		||||
	VK_DELETE   = 0x2E // DEL key
 | 
			
		||||
	VK_HELP     = 0x2F // HELP key
 | 
			
		||||
	VK_F1       = 0x70 // F1 key
 | 
			
		||||
	VK_F2       = 0x71 // F2 key
 | 
			
		||||
	VK_F3       = 0x72 // F3 key
 | 
			
		||||
	VK_F4       = 0x73 // F4 key
 | 
			
		||||
	VK_F5       = 0x74 // F5 key
 | 
			
		||||
	VK_F6       = 0x75 // F6 key
 | 
			
		||||
	VK_F7       = 0x76 // F7 key
 | 
			
		||||
	VK_F8       = 0x77 // F8 key
 | 
			
		||||
	VK_F9       = 0x78 // F9 key
 | 
			
		||||
	VK_F10      = 0x79 // F10 key
 | 
			
		||||
	VK_F11      = 0x7A // F11 key
 | 
			
		||||
	VK_F12      = 0x7B // F12 key
 | 
			
		||||
 | 
			
		||||
	RIGHT_ALT_PRESSED  = 0x0001
 | 
			
		||||
	LEFT_ALT_PRESSED   = 0x0002
 | 
			
		||||
	RIGHT_CTRL_PRESSED = 0x0004
 | 
			
		||||
	LEFT_CTRL_PRESSED  = 0x0008
 | 
			
		||||
	SHIFT_PRESSED      = 0x0010
 | 
			
		||||
	NUMLOCK_ON         = 0x0020
 | 
			
		||||
	SCROLLLOCK_ON      = 0x0040
 | 
			
		||||
	CAPSLOCK_ON        = 0x0080
 | 
			
		||||
	ENHANCED_KEY       = 0x0100
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type ansiCommand struct {
 | 
			
		||||
	CommandBytes []byte
 | 
			
		||||
	Command      string
 | 
			
		||||
	Parameters   []string
 | 
			
		||||
	IsSpecial    bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newAnsiCommand(command []byte) *ansiCommand {
 | 
			
		||||
 | 
			
		||||
	if isCharacterSelectionCmdChar(command[1]) {
 | 
			
		||||
		// Is Character Set Selection commands
 | 
			
		||||
		return &ansiCommand{
 | 
			
		||||
			CommandBytes: command,
 | 
			
		||||
			Command:      string(command),
 | 
			
		||||
			IsSpecial:    true,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// last char is command character
 | 
			
		||||
	lastCharIndex := len(command) - 1
 | 
			
		||||
 | 
			
		||||
	ac := &ansiCommand{
 | 
			
		||||
		CommandBytes: command,
 | 
			
		||||
		Command:      string(command[lastCharIndex]),
 | 
			
		||||
		IsSpecial:    false,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// more than a single escape
 | 
			
		||||
	if lastCharIndex != 0 {
 | 
			
		||||
		start := 1
 | 
			
		||||
		// skip if double char escape sequence
 | 
			
		||||
		if command[0] == ansiterm.ANSI_ESCAPE_PRIMARY && command[1] == ansiterm.ANSI_ESCAPE_SECONDARY {
 | 
			
		||||
			start++
 | 
			
		||||
		}
 | 
			
		||||
		// convert this to GetNextParam method
 | 
			
		||||
		ac.Parameters = strings.Split(string(command[start:lastCharIndex]), ansiterm.ANSI_PARAMETER_SEP)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ac
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ac *ansiCommand) paramAsSHORT(index int, defaultValue int16) int16 {
 | 
			
		||||
	if index < 0 || index >= len(ac.Parameters) {
 | 
			
		||||
		return defaultValue
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	param, err := strconv.ParseInt(ac.Parameters[index], 10, 16)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return defaultValue
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return int16(param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ac *ansiCommand) String() string {
 | 
			
		||||
	return fmt.Sprintf("0x%v \"%v\" (\"%v\")",
 | 
			
		||||
		bytesToHex(ac.CommandBytes),
 | 
			
		||||
		ac.Command,
 | 
			
		||||
		strings.Join(ac.Parameters, "\",\""))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// isAnsiCommandChar returns true if the passed byte falls within the range of ANSI commands.
 | 
			
		||||
// See http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html.
 | 
			
		||||
func isAnsiCommandChar(b byte) bool {
 | 
			
		||||
	switch {
 | 
			
		||||
	case ansiterm.ANSI_COMMAND_FIRST <= b && b <= ansiterm.ANSI_COMMAND_LAST && b != ansiterm.ANSI_ESCAPE_SECONDARY:
 | 
			
		||||
		return true
 | 
			
		||||
	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
 | 
			
		||||
		return true
 | 
			
		||||
	case b == ansiterm.ANSI_CMD_STR_TERM || b == ansiterm.ANSI_BEL:
 | 
			
		||||
		// String escape sequence terminator
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isXtermOscSequence(command []byte, current byte) bool {
 | 
			
		||||
	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 {
 | 
			
		||||
	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.
 | 
			
		||||
func bytesToHex(b []byte) string {
 | 
			
		||||
	hex := make([]string, len(b))
 | 
			
		||||
	for i, ch := range b {
 | 
			
		||||
		hex[i] = fmt.Sprintf("%X", ch)
 | 
			
		||||
	}
 | 
			
		||||
	return strings.Join(hex, "")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ensureInRange adjusts the passed value, if necessary, to ensure it is within
 | 
			
		||||
// the passed min / max range.
 | 
			
		||||
func ensureInRange(n int16, min int16, max int16) int16 {
 | 
			
		||||
	if n < min {
 | 
			
		||||
		return min
 | 
			
		||||
	} else if n > max {
 | 
			
		||||
		return max
 | 
			
		||||
	} else {
 | 
			
		||||
		return n
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetStdFile(nFile int) (*os.File, uintptr) {
 | 
			
		||||
	var file *os.File
 | 
			
		||||
	switch nFile {
 | 
			
		||||
	case syscall.STD_INPUT_HANDLE:
 | 
			
		||||
		file = os.Stdin
 | 
			
		||||
	case syscall.STD_OUTPUT_HANDLE:
 | 
			
		||||
		file = os.Stdout
 | 
			
		||||
	case syscall.STD_ERROR_HANDLE:
 | 
			
		||||
		file = os.Stderr
 | 
			
		||||
	default:
 | 
			
		||||
		panic(fmt.Errorf("Invalid standard handle identifier: %v", nFile))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fd, err := syscall.GetStdHandle(nFile)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(fmt.Errorf("Invalid standard handle identifier: %v -- %v", nFile, err))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return file, uintptr(fd)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										327
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/api.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										327
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/api.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,327 @@
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package winterm
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//===========================================================================================================
 | 
			
		||||
// IMPORTANT NOTE:
 | 
			
		||||
//
 | 
			
		||||
//	The methods below make extensive use of the "unsafe" package to obtain the required pointers.
 | 
			
		||||
//	Beginning in Go 1.3, the garbage collector may release local variables (e.g., incoming arguments, stack
 | 
			
		||||
//	variables) the pointers reference *before* the API completes.
 | 
			
		||||
//
 | 
			
		||||
//  As a result, in those cases, the code must hint that the variables remain in active by invoking the
 | 
			
		||||
//	dummy method "use" (see below). Newer versions of Go are planned to change the mechanism to no longer
 | 
			
		||||
//	require unsafe pointers.
 | 
			
		||||
//
 | 
			
		||||
//	If you add or modify methods, ENSURE protection of local variables through the "use" builtin to inform
 | 
			
		||||
//	the garbage collector the variables remain in use if:
 | 
			
		||||
//
 | 
			
		||||
//	-- The value is not a pointer (e.g., int32, struct)
 | 
			
		||||
//	-- The value is not referenced by the method after passing the pointer to Windows
 | 
			
		||||
//
 | 
			
		||||
//	See http://golang.org/doc/go1.3.
 | 
			
		||||
//===========================================================================================================
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	kernel32DLL = syscall.NewLazyDLL("kernel32.dll")
 | 
			
		||||
 | 
			
		||||
	getConsoleCursorInfoProc       = kernel32DLL.NewProc("GetConsoleCursorInfo")
 | 
			
		||||
	setConsoleCursorInfoProc       = kernel32DLL.NewProc("SetConsoleCursorInfo")
 | 
			
		||||
	setConsoleCursorPositionProc   = kernel32DLL.NewProc("SetConsoleCursorPosition")
 | 
			
		||||
	setConsoleModeProc             = kernel32DLL.NewProc("SetConsoleMode")
 | 
			
		||||
	getConsoleScreenBufferInfoProc = kernel32DLL.NewProc("GetConsoleScreenBufferInfo")
 | 
			
		||||
	setConsoleScreenBufferSizeProc = kernel32DLL.NewProc("SetConsoleScreenBufferSize")
 | 
			
		||||
	scrollConsoleScreenBufferProc  = kernel32DLL.NewProc("ScrollConsoleScreenBufferA")
 | 
			
		||||
	setConsoleTextAttributeProc    = kernel32DLL.NewProc("SetConsoleTextAttribute")
 | 
			
		||||
	setConsoleWindowInfoProc       = kernel32DLL.NewProc("SetConsoleWindowInfo")
 | 
			
		||||
	writeConsoleOutputProc         = kernel32DLL.NewProc("WriteConsoleOutputW")
 | 
			
		||||
	readConsoleInputProc           = kernel32DLL.NewProc("ReadConsoleInputW")
 | 
			
		||||
	waitForSingleObjectProc        = kernel32DLL.NewProc("WaitForSingleObject")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Windows Console constants
 | 
			
		||||
const (
 | 
			
		||||
	// Console modes
 | 
			
		||||
	// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx.
 | 
			
		||||
	ENABLE_PROCESSED_INPUT        = 0x0001
 | 
			
		||||
	ENABLE_LINE_INPUT             = 0x0002
 | 
			
		||||
	ENABLE_ECHO_INPUT             = 0x0004
 | 
			
		||||
	ENABLE_WINDOW_INPUT           = 0x0008
 | 
			
		||||
	ENABLE_MOUSE_INPUT            = 0x0010
 | 
			
		||||
	ENABLE_INSERT_MODE            = 0x0020
 | 
			
		||||
	ENABLE_QUICK_EDIT_MODE        = 0x0040
 | 
			
		||||
	ENABLE_EXTENDED_FLAGS         = 0x0080
 | 
			
		||||
	ENABLE_AUTO_POSITION          = 0x0100
 | 
			
		||||
	ENABLE_VIRTUAL_TERMINAL_INPUT = 0x0200
 | 
			
		||||
 | 
			
		||||
	ENABLE_PROCESSED_OUTPUT            = 0x0001
 | 
			
		||||
	ENABLE_WRAP_AT_EOL_OUTPUT          = 0x0002
 | 
			
		||||
	ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004
 | 
			
		||||
	DISABLE_NEWLINE_AUTO_RETURN        = 0x0008
 | 
			
		||||
	ENABLE_LVB_GRID_WORLDWIDE          = 0x0010
 | 
			
		||||
 | 
			
		||||
	// Character attributes
 | 
			
		||||
	// Note:
 | 
			
		||||
	// -- 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.
 | 
			
		||||
	// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682088(v=vs.85).aspx#_win32_character_attributes.
 | 
			
		||||
	FOREGROUND_BLUE      uint16 = 0x0001
 | 
			
		||||
	FOREGROUND_GREEN     uint16 = 0x0002
 | 
			
		||||
	FOREGROUND_RED       uint16 = 0x0004
 | 
			
		||||
	FOREGROUND_INTENSITY uint16 = 0x0008
 | 
			
		||||
	FOREGROUND_MASK      uint16 = 0x000F
 | 
			
		||||
 | 
			
		||||
	BACKGROUND_BLUE      uint16 = 0x0010
 | 
			
		||||
	BACKGROUND_GREEN     uint16 = 0x0020
 | 
			
		||||
	BACKGROUND_RED       uint16 = 0x0040
 | 
			
		||||
	BACKGROUND_INTENSITY uint16 = 0x0080
 | 
			
		||||
	BACKGROUND_MASK      uint16 = 0x00F0
 | 
			
		||||
 | 
			
		||||
	COMMON_LVB_MASK          uint16 = 0xFF00
 | 
			
		||||
	COMMON_LVB_REVERSE_VIDEO uint16 = 0x4000
 | 
			
		||||
	COMMON_LVB_UNDERSCORE    uint16 = 0x8000
 | 
			
		||||
 | 
			
		||||
	// Input event types
 | 
			
		||||
	// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx.
 | 
			
		||||
	KEY_EVENT                = 0x0001
 | 
			
		||||
	MOUSE_EVENT              = 0x0002
 | 
			
		||||
	WINDOW_BUFFER_SIZE_EVENT = 0x0004
 | 
			
		||||
	MENU_EVENT               = 0x0008
 | 
			
		||||
	FOCUS_EVENT              = 0x0010
 | 
			
		||||
 | 
			
		||||
	// WaitForSingleObject return codes
 | 
			
		||||
	WAIT_ABANDONED = 0x00000080
 | 
			
		||||
	WAIT_FAILED    = 0xFFFFFFFF
 | 
			
		||||
	WAIT_SIGNALED  = 0x0000000
 | 
			
		||||
	WAIT_TIMEOUT   = 0x00000102
 | 
			
		||||
 | 
			
		||||
	// WaitForSingleObject wait duration
 | 
			
		||||
	WAIT_INFINITE       = 0xFFFFFFFF
 | 
			
		||||
	WAIT_ONE_SECOND     = 1000
 | 
			
		||||
	WAIT_HALF_SECOND    = 500
 | 
			
		||||
	WAIT_QUARTER_SECOND = 250
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Windows API Console types
 | 
			
		||||
// -- 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
 | 
			
		||||
type (
 | 
			
		||||
	CHAR_INFO struct {
 | 
			
		||||
		UnicodeChar uint16
 | 
			
		||||
		Attributes  uint16
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	CONSOLE_CURSOR_INFO struct {
 | 
			
		||||
		Size    uint32
 | 
			
		||||
		Visible int32
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	CONSOLE_SCREEN_BUFFER_INFO struct {
 | 
			
		||||
		Size              COORD
 | 
			
		||||
		CursorPosition    COORD
 | 
			
		||||
		Attributes        uint16
 | 
			
		||||
		Window            SMALL_RECT
 | 
			
		||||
		MaximumWindowSize COORD
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	COORD struct {
 | 
			
		||||
		X int16
 | 
			
		||||
		Y int16
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	SMALL_RECT struct {
 | 
			
		||||
		Left   int16
 | 
			
		||||
		Top    int16
 | 
			
		||||
		Right  int16
 | 
			
		||||
		Bottom int16
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 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.
 | 
			
		||||
	INPUT_RECORD struct {
 | 
			
		||||
		EventType uint16
 | 
			
		||||
		KeyEvent  KEY_EVENT_RECORD
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	KEY_EVENT_RECORD struct {
 | 
			
		||||
		KeyDown         int32
 | 
			
		||||
		RepeatCount     uint16
 | 
			
		||||
		VirtualKeyCode  uint16
 | 
			
		||||
		VirtualScanCode uint16
 | 
			
		||||
		UnicodeChar     uint16
 | 
			
		||||
		ControlKeyState uint32
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	WINDOW_BUFFER_SIZE struct {
 | 
			
		||||
		Size COORD
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// boolToBOOL converts a Go bool into a Windows int32.
 | 
			
		||||
func boolToBOOL(f bool) int32 {
 | 
			
		||||
	if f {
 | 
			
		||||
		return int32(1)
 | 
			
		||||
	} else {
 | 
			
		||||
		return int32(0)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetConsoleCursorInfo retrieves information about the size and visiblity of the console cursor.
 | 
			
		||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683163(v=vs.85).aspx.
 | 
			
		||||
func GetConsoleCursorInfo(handle uintptr, cursorInfo *CONSOLE_CURSOR_INFO) error {
 | 
			
		||||
	r1, r2, err := getConsoleCursorInfoProc.Call(handle, uintptr(unsafe.Pointer(cursorInfo)), 0)
 | 
			
		||||
	return checkError(r1, r2, err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetConsoleCursorInfo sets the size and visiblity of the console cursor.
 | 
			
		||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686019(v=vs.85).aspx.
 | 
			
		||||
func SetConsoleCursorInfo(handle uintptr, cursorInfo *CONSOLE_CURSOR_INFO) error {
 | 
			
		||||
	r1, r2, err := setConsoleCursorInfoProc.Call(handle, uintptr(unsafe.Pointer(cursorInfo)), 0)
 | 
			
		||||
	return checkError(r1, r2, err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetConsoleCursorPosition location of the console cursor.
 | 
			
		||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx.
 | 
			
		||||
func SetConsoleCursorPosition(handle uintptr, coord COORD) error {
 | 
			
		||||
	r1, r2, err := setConsoleCursorPositionProc.Call(handle, coordToPointer(coord))
 | 
			
		||||
	use(coord)
 | 
			
		||||
	return checkError(r1, r2, err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetConsoleMode gets the console mode for given file descriptor
 | 
			
		||||
// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx.
 | 
			
		||||
func GetConsoleMode(handle uintptr) (mode uint32, err error) {
 | 
			
		||||
	err = syscall.GetConsoleMode(syscall.Handle(handle), &mode)
 | 
			
		||||
	return mode, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetConsoleMode sets the console mode for given file descriptor
 | 
			
		||||
// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx.
 | 
			
		||||
func SetConsoleMode(handle uintptr, mode uint32) error {
 | 
			
		||||
	r1, r2, err := setConsoleModeProc.Call(handle, uintptr(mode), 0)
 | 
			
		||||
	use(mode)
 | 
			
		||||
	return checkError(r1, r2, err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetConsoleScreenBufferInfo retrieves information about the specified console screen buffer.
 | 
			
		||||
// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx.
 | 
			
		||||
func GetConsoleScreenBufferInfo(handle uintptr) (*CONSOLE_SCREEN_BUFFER_INFO, error) {
 | 
			
		||||
	info := CONSOLE_SCREEN_BUFFER_INFO{}
 | 
			
		||||
	err := checkError(getConsoleScreenBufferInfoProc.Call(handle, uintptr(unsafe.Pointer(&info)), 0))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return &info, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ScrollConsoleScreenBuffer(handle uintptr, scrollRect SMALL_RECT, clipRect SMALL_RECT, destOrigin COORD, char CHAR_INFO) error {
 | 
			
		||||
	r1, r2, err := scrollConsoleScreenBufferProc.Call(handle, uintptr(unsafe.Pointer(&scrollRect)), uintptr(unsafe.Pointer(&clipRect)), coordToPointer(destOrigin), uintptr(unsafe.Pointer(&char)))
 | 
			
		||||
	use(scrollRect)
 | 
			
		||||
	use(clipRect)
 | 
			
		||||
	use(destOrigin)
 | 
			
		||||
	use(char)
 | 
			
		||||
	return checkError(r1, r2, err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetConsoleScreenBufferSize sets the size of the console screen buffer.
 | 
			
		||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686044(v=vs.85).aspx.
 | 
			
		||||
func SetConsoleScreenBufferSize(handle uintptr, coord COORD) error {
 | 
			
		||||
	r1, r2, err := setConsoleScreenBufferSizeProc.Call(handle, coordToPointer(coord))
 | 
			
		||||
	use(coord)
 | 
			
		||||
	return checkError(r1, r2, err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetConsoleTextAttribute sets the attributes of characters written to the
 | 
			
		||||
// console screen buffer by the WriteFile or WriteConsole function.
 | 
			
		||||
// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047(v=vs.85).aspx.
 | 
			
		||||
func SetConsoleTextAttribute(handle uintptr, attribute uint16) error {
 | 
			
		||||
	r1, r2, err := setConsoleTextAttributeProc.Call(handle, uintptr(attribute), 0)
 | 
			
		||||
	use(attribute)
 | 
			
		||||
	return checkError(r1, r2, err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetConsoleWindowInfo sets the size and position of the console screen buffer's window.
 | 
			
		||||
// Note that the size and location must be within and no larger than the backing console screen buffer.
 | 
			
		||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686125(v=vs.85).aspx.
 | 
			
		||||
func SetConsoleWindowInfo(handle uintptr, isAbsolute bool, rect SMALL_RECT) error {
 | 
			
		||||
	r1, r2, err := setConsoleWindowInfoProc.Call(handle, uintptr(boolToBOOL(isAbsolute)), uintptr(unsafe.Pointer(&rect)))
 | 
			
		||||
	use(isAbsolute)
 | 
			
		||||
	use(rect)
 | 
			
		||||
	return checkError(r1, r2, err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WriteConsoleOutput writes the CHAR_INFOs from the provided buffer to the active console buffer.
 | 
			
		||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms687404(v=vs.85).aspx.
 | 
			
		||||
func WriteConsoleOutput(handle uintptr, buffer []CHAR_INFO, bufferSize COORD, bufferCoord COORD, writeRegion *SMALL_RECT) error {
 | 
			
		||||
	r1, r2, err := writeConsoleOutputProc.Call(handle, uintptr(unsafe.Pointer(&buffer[0])), coordToPointer(bufferSize), coordToPointer(bufferCoord), uintptr(unsafe.Pointer(writeRegion)))
 | 
			
		||||
	use(buffer)
 | 
			
		||||
	use(bufferSize)
 | 
			
		||||
	use(bufferCoord)
 | 
			
		||||
	return checkError(r1, r2, err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ReadConsoleInput reads (and removes) data from the console input buffer.
 | 
			
		||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684961(v=vs.85).aspx.
 | 
			
		||||
func ReadConsoleInput(handle uintptr, buffer []INPUT_RECORD, count *uint32) error {
 | 
			
		||||
	r1, r2, err := readConsoleInputProc.Call(handle, uintptr(unsafe.Pointer(&buffer[0])), uintptr(len(buffer)), uintptr(unsafe.Pointer(count)))
 | 
			
		||||
	use(buffer)
 | 
			
		||||
	return checkError(r1, r2, err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WaitForSingleObject waits for the passed handle to be signaled.
 | 
			
		||||
// 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.
 | 
			
		||||
func WaitForSingleObject(handle uintptr, msWait uint32) (bool, error) {
 | 
			
		||||
	r1, _, err := waitForSingleObjectProc.Call(handle, uintptr(uint32(msWait)))
 | 
			
		||||
	switch r1 {
 | 
			
		||||
	case WAIT_ABANDONED, WAIT_TIMEOUT:
 | 
			
		||||
		return false, nil
 | 
			
		||||
	case WAIT_SIGNALED:
 | 
			
		||||
		return true, nil
 | 
			
		||||
	}
 | 
			
		||||
	use(msWait)
 | 
			
		||||
	return false, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String helpers
 | 
			
		||||
func (info CONSOLE_SCREEN_BUFFER_INFO) String() string {
 | 
			
		||||
	return fmt.Sprintf("Size(%v) Cursor(%v) Window(%v) Max(%v)", info.Size, info.CursorPosition, info.Window, info.MaximumWindowSize)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (coord COORD) String() string {
 | 
			
		||||
	return fmt.Sprintf("%v,%v", coord.X, coord.Y)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (rect SMALL_RECT) String() string {
 | 
			
		||||
	return fmt.Sprintf("(%v,%v),(%v,%v)", rect.Left, rect.Top, rect.Right, rect.Bottom)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// checkError evaluates the results of a Windows API call and returns the error if it failed.
 | 
			
		||||
func checkError(r1, r2 uintptr, err error) error {
 | 
			
		||||
	// Windows APIs return non-zero to indicate success
 | 
			
		||||
	if r1 != 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Return the error if provided, otherwise default to EINVAL
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return syscall.EINVAL
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// coordToPointer converts a COORD into a uintptr (by fooling the type system).
 | 
			
		||||
func coordToPointer(c COORD) uintptr {
 | 
			
		||||
	// 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(*((*uint32)(unsafe.Pointer(&c))))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// use is a no-op, but the compiler cannot see that it is.
 | 
			
		||||
// Calling use(p) ensures that p is kept live until that point.
 | 
			
		||||
func use(p interface{}) {}
 | 
			
		||||
							
								
								
									
										100
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package winterm
 | 
			
		||||
 | 
			
		||||
import "github.com/Azure/go-ansiterm"
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	FOREGROUND_COLOR_MASK = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
 | 
			
		||||
	BACKGROUND_COLOR_MASK = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// collectAnsiIntoWindowsAttributes modifies the passed Windows text mode flags to reflect the
 | 
			
		||||
// request represented by the passed ANSI mode.
 | 
			
		||||
func collectAnsiIntoWindowsAttributes(windowsMode uint16, inverted bool, baseMode uint16, ansiMode int16) (uint16, bool) {
 | 
			
		||||
	switch ansiMode {
 | 
			
		||||
 | 
			
		||||
	// Mode styles
 | 
			
		||||
	case ansiterm.ANSI_SGR_BOLD:
 | 
			
		||||
		windowsMode = windowsMode | FOREGROUND_INTENSITY
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_DIM, ansiterm.ANSI_SGR_BOLD_DIM_OFF:
 | 
			
		||||
		windowsMode &^= FOREGROUND_INTENSITY
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_UNDERLINE:
 | 
			
		||||
		windowsMode = windowsMode | COMMON_LVB_UNDERSCORE
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_REVERSE:
 | 
			
		||||
		inverted = true
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_REVERSE_OFF:
 | 
			
		||||
		inverted = false
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_UNDERLINE_OFF:
 | 
			
		||||
		windowsMode &^= COMMON_LVB_UNDERSCORE
 | 
			
		||||
 | 
			
		||||
		// Foreground colors
 | 
			
		||||
	case ansiterm.ANSI_SGR_FOREGROUND_DEFAULT:
 | 
			
		||||
		windowsMode = (windowsMode &^ FOREGROUND_MASK) | (baseMode & FOREGROUND_MASK)
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_FOREGROUND_BLACK:
 | 
			
		||||
		windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK)
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_FOREGROUND_RED:
 | 
			
		||||
		windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_FOREGROUND_GREEN:
 | 
			
		||||
		windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_FOREGROUND_YELLOW:
 | 
			
		||||
		windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_FOREGROUND_BLUE:
 | 
			
		||||
		windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_BLUE
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_FOREGROUND_MAGENTA:
 | 
			
		||||
		windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_BLUE
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_FOREGROUND_CYAN:
 | 
			
		||||
		windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN | FOREGROUND_BLUE
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_FOREGROUND_WHITE:
 | 
			
		||||
		windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
 | 
			
		||||
 | 
			
		||||
		// Background colors
 | 
			
		||||
	case ansiterm.ANSI_SGR_BACKGROUND_DEFAULT:
 | 
			
		||||
		// Black with no intensity
 | 
			
		||||
		windowsMode = (windowsMode &^ BACKGROUND_MASK) | (baseMode & BACKGROUND_MASK)
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_BACKGROUND_BLACK:
 | 
			
		||||
		windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK)
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_BACKGROUND_RED:
 | 
			
		||||
		windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_BACKGROUND_GREEN:
 | 
			
		||||
		windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_BACKGROUND_YELLOW:
 | 
			
		||||
		windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_BACKGROUND_BLUE:
 | 
			
		||||
		windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_BLUE
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_BACKGROUND_MAGENTA:
 | 
			
		||||
		windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_BLUE
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_BACKGROUND_CYAN:
 | 
			
		||||
		windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN | BACKGROUND_BLUE
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_SGR_BACKGROUND_WHITE:
 | 
			
		||||
		windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return windowsMode, inverted
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// invertAttributes inverts the foreground and background colors of a Windows attributes value
 | 
			
		||||
func invertAttributes(windowsMode uint16) uint16 {
 | 
			
		||||
	return (COMMON_LVB_MASK & windowsMode) | ((FOREGROUND_MASK & windowsMode) << 4) | ((BACKGROUND_MASK & windowsMode) >> 4)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										101
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,101 @@
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package winterm
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	horizontal = iota
 | 
			
		||||
	vertical
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) getCursorWindow(info *CONSOLE_SCREEN_BUFFER_INFO) SMALL_RECT {
 | 
			
		||||
	if h.originMode {
 | 
			
		||||
		sr := h.effectiveSr(info.Window)
 | 
			
		||||
		return SMALL_RECT{
 | 
			
		||||
			Top:    sr.top,
 | 
			
		||||
			Bottom: sr.bottom,
 | 
			
		||||
			Left:   0,
 | 
			
		||||
			Right:  info.Size.X - 1,
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		return SMALL_RECT{
 | 
			
		||||
			Top:    info.Window.Top,
 | 
			
		||||
			Bottom: info.Window.Bottom,
 | 
			
		||||
			Left:   0,
 | 
			
		||||
			Right:  info.Size.X - 1,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setCursorPosition sets the cursor to the specified position, bounded to the screen size
 | 
			
		||||
func (h *windowsAnsiEventHandler) setCursorPosition(position COORD, window SMALL_RECT) error {
 | 
			
		||||
	position.X = ensureInRange(position.X, window.Left, window.Right)
 | 
			
		||||
	position.Y = ensureInRange(position.Y, window.Top, window.Bottom)
 | 
			
		||||
	err := SetConsoleCursorPosition(h.fd, position)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("Cursor position set: (%d, %d)", position.X, position.Y)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) moveCursorVertical(param int) error {
 | 
			
		||||
	return h.moveCursor(vertical, param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) moveCursorHorizontal(param int) error {
 | 
			
		||||
	return h.moveCursor(horizontal, param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) moveCursor(moveMode int, param int) error {
 | 
			
		||||
	info, err := GetConsoleScreenBufferInfo(h.fd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	position := info.CursorPosition
 | 
			
		||||
	switch moveMode {
 | 
			
		||||
	case horizontal:
 | 
			
		||||
		position.X += int16(param)
 | 
			
		||||
	case vertical:
 | 
			
		||||
		position.Y += int16(param)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) moveCursorLine(param int) error {
 | 
			
		||||
	info, err := GetConsoleScreenBufferInfo(h.fd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	position := info.CursorPosition
 | 
			
		||||
	position.X = 0
 | 
			
		||||
	position.Y += int16(param)
 | 
			
		||||
 | 
			
		||||
	if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) moveCursorColumn(param int) error {
 | 
			
		||||
	info, err := GetConsoleScreenBufferInfo(h.fd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	position := info.CursorPosition
 | 
			
		||||
	position.X = int16(param) - 1
 | 
			
		||||
 | 
			
		||||
	if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										84
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package winterm
 | 
			
		||||
 | 
			
		||||
import "github.com/Azure/go-ansiterm"
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) clearRange(attributes uint16, fromCoord COORD, toCoord COORD) error {
 | 
			
		||||
	// Ignore an invalid (negative area) request
 | 
			
		||||
	if toCoord.Y < fromCoord.Y {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var err error
 | 
			
		||||
 | 
			
		||||
	var coordStart = COORD{}
 | 
			
		||||
	var coordEnd = COORD{}
 | 
			
		||||
 | 
			
		||||
	xCurrent, yCurrent := fromCoord.X, fromCoord.Y
 | 
			
		||||
	xEnd, yEnd := toCoord.X, toCoord.Y
 | 
			
		||||
 | 
			
		||||
	// Clear any partial initial line
 | 
			
		||||
	if xCurrent > 0 {
 | 
			
		||||
		coordStart.X, coordStart.Y = xCurrent, yCurrent
 | 
			
		||||
		coordEnd.X, coordEnd.Y = xEnd, yCurrent
 | 
			
		||||
 | 
			
		||||
		err = h.clearRect(attributes, coordStart, coordEnd)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		xCurrent = 0
 | 
			
		||||
		yCurrent += 1
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Clear intervening rectangular section
 | 
			
		||||
	if yCurrent < yEnd {
 | 
			
		||||
		coordStart.X, coordStart.Y = xCurrent, yCurrent
 | 
			
		||||
		coordEnd.X, coordEnd.Y = xEnd, yEnd-1
 | 
			
		||||
 | 
			
		||||
		err = h.clearRect(attributes, coordStart, coordEnd)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		xCurrent = 0
 | 
			
		||||
		yCurrent = yEnd
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Clear remaining partial ending line
 | 
			
		||||
	coordStart.X, coordStart.Y = xCurrent, yCurrent
 | 
			
		||||
	coordEnd.X, coordEnd.Y = xEnd, yEnd
 | 
			
		||||
 | 
			
		||||
	err = h.clearRect(attributes, coordStart, coordEnd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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}
 | 
			
		||||
	width := toCoord.X - fromCoord.X + 1
 | 
			
		||||
	height := toCoord.Y - fromCoord.Y + 1
 | 
			
		||||
	size := uint32(width) * uint32(height)
 | 
			
		||||
 | 
			
		||||
	if size <= 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	buffer := make([]CHAR_INFO, size)
 | 
			
		||||
 | 
			
		||||
	char := CHAR_INFO{ansiterm.FILL_CHARACTER, attributes}
 | 
			
		||||
	for i := 0; i < int(size); i++ {
 | 
			
		||||
		buffer[i] = char
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err := WriteConsoleOutput(h.fd, buffer, COORD{X: width, Y: height}, COORD{X: 0, Y: 0}, ®ion)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										118
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,118 @@
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package winterm
 | 
			
		||||
 | 
			
		||||
// effectiveSr gets the current effective scroll region in buffer coordinates
 | 
			
		||||
func (h *windowsAnsiEventHandler) effectiveSr(window SMALL_RECT) scrollRegion {
 | 
			
		||||
	top := addInRange(window.Top, h.sr.top, window.Top, window.Bottom)
 | 
			
		||||
	bottom := addInRange(window.Top, h.sr.bottom, window.Top, window.Bottom)
 | 
			
		||||
	if top >= bottom {
 | 
			
		||||
		top = window.Top
 | 
			
		||||
		bottom = window.Bottom
 | 
			
		||||
	}
 | 
			
		||||
	return scrollRegion{top: top, bottom: bottom}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) scrollUp(param int) error {
 | 
			
		||||
	info, err := GetConsoleScreenBufferInfo(h.fd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sr := h.effectiveSr(info.Window)
 | 
			
		||||
	return h.scroll(param, sr, info)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) scrollDown(param int) error {
 | 
			
		||||
	return h.scrollUp(-param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) deleteLines(param int) error {
 | 
			
		||||
	info, err := GetConsoleScreenBufferInfo(h.fd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	start := info.CursorPosition.Y
 | 
			
		||||
	sr := h.effectiveSr(info.Window)
 | 
			
		||||
	// Lines cannot be inserted or deleted outside the scrolling region.
 | 
			
		||||
	if start >= sr.top && start <= sr.bottom {
 | 
			
		||||
		sr.top = start
 | 
			
		||||
		return h.scroll(param, sr, info)
 | 
			
		||||
	} else {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) insertLines(param int) error {
 | 
			
		||||
	return h.deleteLines(-param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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 {
 | 
			
		||||
	h.logf("scroll: scrollTop: %d, scrollBottom: %d", sr.top, sr.bottom)
 | 
			
		||||
	h.logf("scroll: windowTop: %d, windowBottom: %d", info.Window.Top, info.Window.Bottom)
 | 
			
		||||
 | 
			
		||||
	// Copy from and clip to the scroll region (full buffer width)
 | 
			
		||||
	scrollRect := SMALL_RECT{
 | 
			
		||||
		Top:    sr.top,
 | 
			
		||||
		Bottom: sr.bottom,
 | 
			
		||||
		Left:   0,
 | 
			
		||||
		Right:  info.Size.X - 1,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Origin to which area should be copied
 | 
			
		||||
	destOrigin := COORD{
 | 
			
		||||
		X: 0,
 | 
			
		||||
		Y: sr.top - int16(param),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	char := CHAR_INFO{
 | 
			
		||||
		UnicodeChar: ' ',
 | 
			
		||||
		Attributes:  h.attributes,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := ScrollConsoleScreenBuffer(h.fd, scrollRect, scrollRect, destOrigin, char); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) deleteCharacters(param int) error {
 | 
			
		||||
	info, err := GetConsoleScreenBufferInfo(h.fd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return h.scrollLine(param, info.CursorPosition, info)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) insertCharacters(param int) error {
 | 
			
		||||
	return h.deleteCharacters(-param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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 {
 | 
			
		||||
	// Copy from and clip to the scroll region (full buffer width)
 | 
			
		||||
	scrollRect := SMALL_RECT{
 | 
			
		||||
		Top:    position.Y,
 | 
			
		||||
		Bottom: position.Y,
 | 
			
		||||
		Left:   position.X,
 | 
			
		||||
		Right:  info.Size.X - 1,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Origin to which area should be copied
 | 
			
		||||
	destOrigin := COORD{
 | 
			
		||||
		X: position.X - int16(columns),
 | 
			
		||||
		Y: position.Y,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	char := CHAR_INFO{
 | 
			
		||||
		UnicodeChar: ' ',
 | 
			
		||||
		Attributes:  h.attributes,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := ScrollConsoleScreenBuffer(h.fd, scrollRect, scrollRect, destOrigin, char); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/utilities.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/utilities.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package winterm
 | 
			
		||||
 | 
			
		||||
// AddInRange increments a value by the passed quantity while ensuring the values
 | 
			
		||||
// always remain within the supplied min / max range.
 | 
			
		||||
func addInRange(n int16, increment int16, min int16, max int16) int16 {
 | 
			
		||||
	return ensureInRange(n+increment, min, max)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										743
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										743
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,743 @@
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package winterm
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	"github.com/Azure/go-ansiterm"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type windowsAnsiEventHandler struct {
 | 
			
		||||
	fd             uintptr
 | 
			
		||||
	file           *os.File
 | 
			
		||||
	infoReset      *CONSOLE_SCREEN_BUFFER_INFO
 | 
			
		||||
	sr             scrollRegion
 | 
			
		||||
	buffer         bytes.Buffer
 | 
			
		||||
	attributes     uint16
 | 
			
		||||
	inverted       bool
 | 
			
		||||
	wrapNext       bool
 | 
			
		||||
	drewMarginByte bool
 | 
			
		||||
	originMode     bool
 | 
			
		||||
	marginByte     byte
 | 
			
		||||
	curInfo        *CONSOLE_SCREEN_BUFFER_INFO
 | 
			
		||||
	curPos         COORD
 | 
			
		||||
	logf           func(string, ...interface{})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Option func(*windowsAnsiEventHandler)
 | 
			
		||||
 | 
			
		||||
func WithLogf(f func(string, ...interface{})) Option {
 | 
			
		||||
	return func(w *windowsAnsiEventHandler) {
 | 
			
		||||
		w.logf = f
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func CreateWinEventHandler(fd uintptr, file *os.File, opts ...Option) ansiterm.AnsiEventHandler {
 | 
			
		||||
	infoReset, err := GetConsoleScreenBufferInfo(fd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	h := &windowsAnsiEventHandler{
 | 
			
		||||
		fd:         fd,
 | 
			
		||||
		file:       file,
 | 
			
		||||
		infoReset:  infoReset,
 | 
			
		||||
		attributes: infoReset.Attributes,
 | 
			
		||||
	}
 | 
			
		||||
	for _, o := range opts {
 | 
			
		||||
		o(h)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" {
 | 
			
		||||
		logFile, _ := os.Create("winEventHandler.log")
 | 
			
		||||
		logger := log.New(logFile, "", log.LstdFlags)
 | 
			
		||||
		if h.logf != nil {
 | 
			
		||||
			l := h.logf
 | 
			
		||||
			h.logf = func(s string, v ...interface{}) {
 | 
			
		||||
				l(s, v...)
 | 
			
		||||
				logger.Printf(s, v...)
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			h.logf = logger.Printf
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if h.logf == nil {
 | 
			
		||||
		h.logf = func(string, ...interface{}) {}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return h
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type scrollRegion struct {
 | 
			
		||||
	top    int16
 | 
			
		||||
	bottom int16
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// simulateLF simulates a LF or CR+LF by scrolling if necessary to handle the
 | 
			
		||||
// current cursor position and scroll region settings, in which case it returns
 | 
			
		||||
// true. If no special handling is necessary, then it does nothing and returns
 | 
			
		||||
// false.
 | 
			
		||||
//
 | 
			
		||||
// In the false case, the caller should ensure that a carriage return
 | 
			
		||||
// and line feed are inserted or that the text is otherwise wrapped.
 | 
			
		||||
func (h *windowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) {
 | 
			
		||||
	if h.wrapNext {
 | 
			
		||||
		if err := h.Flush(); err != nil {
 | 
			
		||||
			return false, err
 | 
			
		||||
		}
 | 
			
		||||
		h.clearWrap()
 | 
			
		||||
	}
 | 
			
		||||
	pos, info, err := h.getCurrentInfo()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false, err
 | 
			
		||||
	}
 | 
			
		||||
	sr := h.effectiveSr(info.Window)
 | 
			
		||||
	if pos.Y == sr.bottom {
 | 
			
		||||
		// Scrolling is necessary. Let Windows automatically scroll if the scrolling region
 | 
			
		||||
		// is the full window.
 | 
			
		||||
		if sr.top == info.Window.Top && sr.bottom == info.Window.Bottom {
 | 
			
		||||
			if includeCR {
 | 
			
		||||
				pos.X = 0
 | 
			
		||||
				h.updatePos(pos)
 | 
			
		||||
			}
 | 
			
		||||
			return false, nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// A custom scroll region is active. Scroll the window manually to simulate
 | 
			
		||||
		// the LF.
 | 
			
		||||
		if err := h.Flush(); err != nil {
 | 
			
		||||
			return false, err
 | 
			
		||||
		}
 | 
			
		||||
		h.logf("Simulating LF inside scroll region")
 | 
			
		||||
		if err := h.scrollUp(1); err != nil {
 | 
			
		||||
			return false, err
 | 
			
		||||
		}
 | 
			
		||||
		if includeCR {
 | 
			
		||||
			pos.X = 0
 | 
			
		||||
			if err := SetConsoleCursorPosition(h.fd, pos); err != nil {
 | 
			
		||||
				return false, err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return true, nil
 | 
			
		||||
 | 
			
		||||
	} else if pos.Y < info.Window.Bottom {
 | 
			
		||||
		// Let Windows handle the LF.
 | 
			
		||||
		pos.Y++
 | 
			
		||||
		if includeCR {
 | 
			
		||||
			pos.X = 0
 | 
			
		||||
		}
 | 
			
		||||
		h.updatePos(pos)
 | 
			
		||||
		return false, nil
 | 
			
		||||
	} else {
 | 
			
		||||
		// The cursor is at the bottom of the screen but outside the scroll
 | 
			
		||||
		// region. Skip the LF.
 | 
			
		||||
		h.logf("Simulating LF outside scroll region")
 | 
			
		||||
		if includeCR {
 | 
			
		||||
			if err := h.Flush(); err != nil {
 | 
			
		||||
				return false, err
 | 
			
		||||
			}
 | 
			
		||||
			pos.X = 0
 | 
			
		||||
			if err := SetConsoleCursorPosition(h.fd, pos); err != nil {
 | 
			
		||||
				return false, err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return true, nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// executeLF executes a LF without a CR.
 | 
			
		||||
func (h *windowsAnsiEventHandler) executeLF() error {
 | 
			
		||||
	handled, err := h.simulateLF(false)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if !handled {
 | 
			
		||||
		// Windows LF will reset the cursor column position. Write the LF
 | 
			
		||||
		// and restore the cursor position.
 | 
			
		||||
		pos, _, err := h.getCurrentInfo()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		h.buffer.WriteByte(ansiterm.ANSI_LINE_FEED)
 | 
			
		||||
		if pos.X != 0 {
 | 
			
		||||
			if err := h.Flush(); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			h.logf("Resetting cursor position for LF without CR")
 | 
			
		||||
			if err := SetConsoleCursorPosition(h.fd, pos); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) Print(b byte) error {
 | 
			
		||||
	if h.wrapNext {
 | 
			
		||||
		h.buffer.WriteByte(h.marginByte)
 | 
			
		||||
		h.clearWrap()
 | 
			
		||||
		if _, err := h.simulateLF(true); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	pos, info, err := h.getCurrentInfo()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if pos.X == info.Size.X-1 {
 | 
			
		||||
		h.wrapNext = true
 | 
			
		||||
		h.marginByte = b
 | 
			
		||||
	} else {
 | 
			
		||||
		pos.X++
 | 
			
		||||
		h.updatePos(pos)
 | 
			
		||||
		h.buffer.WriteByte(b)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) Execute(b byte) error {
 | 
			
		||||
	switch b {
 | 
			
		||||
	case ansiterm.ANSI_TAB:
 | 
			
		||||
		h.logf("Execute(TAB)")
 | 
			
		||||
		// Move to the next tab stop, but preserve auto-wrap if already set.
 | 
			
		||||
		if !h.wrapNext {
 | 
			
		||||
			pos, info, err := h.getCurrentInfo()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			pos.X = (pos.X + 8) - pos.X%8
 | 
			
		||||
			if pos.X >= info.Size.X {
 | 
			
		||||
				pos.X = info.Size.X - 1
 | 
			
		||||
			}
 | 
			
		||||
			if err := h.Flush(); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			if err := SetConsoleCursorPosition(h.fd, pos); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_BEL:
 | 
			
		||||
		h.buffer.WriteByte(ansiterm.ANSI_BEL)
 | 
			
		||||
		return nil
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_BACKSPACE:
 | 
			
		||||
		if h.wrapNext {
 | 
			
		||||
			if err := h.Flush(); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			h.clearWrap()
 | 
			
		||||
		}
 | 
			
		||||
		pos, _, err := h.getCurrentInfo()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		if pos.X > 0 {
 | 
			
		||||
			pos.X--
 | 
			
		||||
			h.updatePos(pos)
 | 
			
		||||
			h.buffer.WriteByte(ansiterm.ANSI_BACKSPACE)
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_VERTICAL_TAB, ansiterm.ANSI_FORM_FEED:
 | 
			
		||||
		// Treat as true LF.
 | 
			
		||||
		return h.executeLF()
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_LINE_FEED:
 | 
			
		||||
		// 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
 | 
			
		||||
		// missing than when it's incorrectly added).
 | 
			
		||||
		handled, err := h.simulateLF(true)
 | 
			
		||||
		if handled || err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		return h.buffer.WriteByte(ansiterm.ANSI_LINE_FEED)
 | 
			
		||||
 | 
			
		||||
	case ansiterm.ANSI_CARRIAGE_RETURN:
 | 
			
		||||
		if h.wrapNext {
 | 
			
		||||
			if err := h.Flush(); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			h.clearWrap()
 | 
			
		||||
		}
 | 
			
		||||
		pos, _, err := h.getCurrentInfo()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		if pos.X != 0 {
 | 
			
		||||
			pos.X = 0
 | 
			
		||||
			h.updatePos(pos)
 | 
			
		||||
			h.buffer.WriteByte(ansiterm.ANSI_CARRIAGE_RETURN)
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) CUU(param int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("CUU: [%v]", []string{strconv.Itoa(param)})
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	return h.moveCursorVertical(-param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) CUD(param int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("CUD: [%v]", []string{strconv.Itoa(param)})
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	return h.moveCursorVertical(param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) CUF(param int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("CUF: [%v]", []string{strconv.Itoa(param)})
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	return h.moveCursorHorizontal(param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) CUB(param int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("CUB: [%v]", []string{strconv.Itoa(param)})
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	return h.moveCursorHorizontal(-param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) CNL(param int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("CNL: [%v]", []string{strconv.Itoa(param)})
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	return h.moveCursorLine(param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) CPL(param int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("CPL: [%v]", []string{strconv.Itoa(param)})
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	return h.moveCursorLine(-param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) CHA(param int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("CHA: [%v]", []string{strconv.Itoa(param)})
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	return h.moveCursorColumn(param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) VPA(param int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("VPA: [[%d]]", param)
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	info, err := GetConsoleScreenBufferInfo(h.fd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	window := h.getCursorWindow(info)
 | 
			
		||||
	position := info.CursorPosition
 | 
			
		||||
	position.Y = window.Top + int16(param) - 1
 | 
			
		||||
	return h.setCursorPosition(position, window)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) CUP(row int, col int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("CUP: [[%d %d]]", row, col)
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	info, err := GetConsoleScreenBufferInfo(h.fd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	window := h.getCursorWindow(info)
 | 
			
		||||
	position := COORD{window.Left + int16(col) - 1, window.Top + int16(row) - 1}
 | 
			
		||||
	return h.setCursorPosition(position, window)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) HVP(row int, col int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("HVP: [[%d %d]]", row, col)
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	return h.CUP(row, col)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) DECTCEM(visible bool) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("DECTCEM: [%v]", []string{strconv.FormatBool(visible)})
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) DECOM(enable bool) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("DECOM: [%v]", []string{strconv.FormatBool(enable)})
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	h.originMode = enable
 | 
			
		||||
	return h.CUP(1, 1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) DECCOLM(use132 bool) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("DECCOLM: [%v]", []string{strconv.FormatBool(use132)})
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	if err := h.ED(2); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	info, err := GetConsoleScreenBufferInfo(h.fd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	targetWidth := int16(80)
 | 
			
		||||
	if use132 {
 | 
			
		||||
		targetWidth = 132
 | 
			
		||||
	}
 | 
			
		||||
	if info.Size.X < targetWidth {
 | 
			
		||||
		if err := SetConsoleScreenBufferSize(h.fd, COORD{targetWidth, info.Size.Y}); err != nil {
 | 
			
		||||
			h.logf("set buffer failed: %v", err)
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	window := info.Window
 | 
			
		||||
	window.Left = 0
 | 
			
		||||
	window.Right = targetWidth - 1
 | 
			
		||||
	if err := SetConsoleWindowInfo(h.fd, true, window); err != nil {
 | 
			
		||||
		h.logf("set window failed: %v", err)
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if info.Size.X > targetWidth {
 | 
			
		||||
		if err := SetConsoleScreenBufferSize(h.fd, COORD{targetWidth, info.Size.Y}); err != nil {
 | 
			
		||||
			h.logf("set buffer failed: %v", err)
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return SetConsoleCursorPosition(h.fd, COORD{0, 0})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) ED(param int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("ED: [%v]", []string{strconv.Itoa(param)})
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
 | 
			
		||||
	// [J  -- Erases from the cursor to the end of the screen, including the cursor position.
 | 
			
		||||
	// [1J -- Erases from the beginning of the screen to the cursor, including the cursor position.
 | 
			
		||||
	// [2J -- Erases the complete display. The cursor does not move.
 | 
			
		||||
	// Notes:
 | 
			
		||||
	// -- Clearing the entire buffer, versus just the Window, works best for Windows Consoles
 | 
			
		||||
 | 
			
		||||
	info, err := GetConsoleScreenBufferInfo(h.fd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var start COORD
 | 
			
		||||
	var end COORD
 | 
			
		||||
 | 
			
		||||
	switch param {
 | 
			
		||||
	case 0:
 | 
			
		||||
		start = info.CursorPosition
 | 
			
		||||
		end = COORD{info.Size.X - 1, info.Size.Y - 1}
 | 
			
		||||
 | 
			
		||||
	case 1:
 | 
			
		||||
		start = COORD{0, 0}
 | 
			
		||||
		end = info.CursorPosition
 | 
			
		||||
 | 
			
		||||
	case 2:
 | 
			
		||||
		start = COORD{0, 0}
 | 
			
		||||
		end = COORD{info.Size.X - 1, info.Size.Y - 1}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = h.clearRange(h.attributes, start, end)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If the whole buffer was cleared, move the window to the top while preserving
 | 
			
		||||
	// the window-relative cursor position.
 | 
			
		||||
	if param == 2 {
 | 
			
		||||
		pos := info.CursorPosition
 | 
			
		||||
		window := info.Window
 | 
			
		||||
		pos.Y -= window.Top
 | 
			
		||||
		window.Bottom -= window.Top
 | 
			
		||||
		window.Top = 0
 | 
			
		||||
		if err := SetConsoleCursorPosition(h.fd, pos); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		if err := SetConsoleWindowInfo(h.fd, true, window); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) EL(param int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("EL: [%v]", strconv.Itoa(param))
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
 | 
			
		||||
	// [K  -- Erases from the cursor to the end of the line, including the cursor position.
 | 
			
		||||
	// [1K -- Erases from the beginning of the line to the cursor, including the cursor position.
 | 
			
		||||
	// [2K -- Erases the complete line.
 | 
			
		||||
 | 
			
		||||
	info, err := GetConsoleScreenBufferInfo(h.fd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var start COORD
 | 
			
		||||
	var end COORD
 | 
			
		||||
 | 
			
		||||
	switch param {
 | 
			
		||||
	case 0:
 | 
			
		||||
		start = info.CursorPosition
 | 
			
		||||
		end = COORD{info.Size.X, info.CursorPosition.Y}
 | 
			
		||||
 | 
			
		||||
	case 1:
 | 
			
		||||
		start = COORD{0, info.CursorPosition.Y}
 | 
			
		||||
		end = info.CursorPosition
 | 
			
		||||
 | 
			
		||||
	case 2:
 | 
			
		||||
		start = COORD{0, info.CursorPosition.Y}
 | 
			
		||||
		end = COORD{info.Size.X, info.CursorPosition.Y}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = h.clearRange(h.attributes, start, end)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) IL(param int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("IL: [%v]", strconv.Itoa(param))
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	return h.insertLines(param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) DL(param int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("DL: [%v]", strconv.Itoa(param))
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	return h.deleteLines(param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) ICH(param int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("ICH: [%v]", strconv.Itoa(param))
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	return h.insertCharacters(param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) DCH(param int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("DCH: [%v]", strconv.Itoa(param))
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	return h.deleteCharacters(param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) SGR(params []int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	strings := []string{}
 | 
			
		||||
	for _, v := range params {
 | 
			
		||||
		strings = append(strings, strconv.Itoa(v))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	h.logf("SGR: [%v]", strings)
 | 
			
		||||
 | 
			
		||||
	if len(params) <= 0 {
 | 
			
		||||
		h.attributes = h.infoReset.Attributes
 | 
			
		||||
		h.inverted = false
 | 
			
		||||
	} else {
 | 
			
		||||
		for _, attr := range params {
 | 
			
		||||
 | 
			
		||||
			if attr == ansiterm.ANSI_SGR_RESET {
 | 
			
		||||
				h.attributes = h.infoReset.Attributes
 | 
			
		||||
				h.inverted = false
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			h.attributes, h.inverted = collectAnsiIntoWindowsAttributes(h.attributes, h.inverted, h.infoReset.Attributes, int16(attr))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	attributes := h.attributes
 | 
			
		||||
	if h.inverted {
 | 
			
		||||
		attributes = invertAttributes(attributes)
 | 
			
		||||
	}
 | 
			
		||||
	err := SetConsoleTextAttribute(h.fd, attributes)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) SU(param int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("SU: [%v]", []string{strconv.Itoa(param)})
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	return h.scrollUp(param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) SD(param int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("SD: [%v]", []string{strconv.Itoa(param)})
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	return h.scrollDown(param)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) DA(params []string) error {
 | 
			
		||||
	h.logf("DA: [%v]", params)
 | 
			
		||||
	// DA cannot be implemented because it must send data on the VT100 input stream,
 | 
			
		||||
	// which is not available to go-ansiterm.
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) DECSTBM(top int, bottom int) error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("DECSTBM: [%d, %d]", top, bottom)
 | 
			
		||||
 | 
			
		||||
	// Windows is 0 indexed, Linux is 1 indexed
 | 
			
		||||
	h.sr.top = int16(top - 1)
 | 
			
		||||
	h.sr.bottom = int16(bottom - 1)
 | 
			
		||||
 | 
			
		||||
	// This command also moves the cursor to the origin.
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
	return h.CUP(1, 1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) RI() error {
 | 
			
		||||
	if err := h.Flush(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	h.logf("RI: []")
 | 
			
		||||
	h.clearWrap()
 | 
			
		||||
 | 
			
		||||
	info, err := GetConsoleScreenBufferInfo(h.fd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sr := h.effectiveSr(info.Window)
 | 
			
		||||
	if info.CursorPosition.Y == sr.top {
 | 
			
		||||
		return h.scrollDown(1)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return h.moveCursorVertical(-1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) IND() error {
 | 
			
		||||
	h.logf("IND: []")
 | 
			
		||||
	return h.executeLF()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) Flush() error {
 | 
			
		||||
	h.curInfo = nil
 | 
			
		||||
	if h.buffer.Len() > 0 {
 | 
			
		||||
		h.logf("Flush: [%s]", h.buffer.Bytes())
 | 
			
		||||
		if _, err := h.buffer.WriteTo(h.file); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if h.wrapNext && !h.drewMarginByte {
 | 
			
		||||
		h.logf("Flush: drawing margin byte '%c'", h.marginByte)
 | 
			
		||||
 | 
			
		||||
		info, err := GetConsoleScreenBufferInfo(h.fd)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		charInfo := []CHAR_INFO{{UnicodeChar: uint16(h.marginByte), Attributes: info.Attributes}}
 | 
			
		||||
		size := COORD{1, 1}
 | 
			
		||||
		position := COORD{0, 0}
 | 
			
		||||
		region := SMALL_RECT{Left: info.CursorPosition.X, Top: info.CursorPosition.Y, Right: info.CursorPosition.X, Bottom: info.CursorPosition.Y}
 | 
			
		||||
		if err := WriteConsoleOutput(h.fd, charInfo, size, position, ®ion); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		h.drewMarginByte = true
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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.
 | 
			
		||||
func (h *windowsAnsiEventHandler) getCurrentInfo() (COORD, *CONSOLE_SCREEN_BUFFER_INFO, error) {
 | 
			
		||||
	if h.curInfo == nil {
 | 
			
		||||
		info, err := GetConsoleScreenBufferInfo(h.fd)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return COORD{}, nil, err
 | 
			
		||||
		}
 | 
			
		||||
		h.curInfo = info
 | 
			
		||||
		h.curPos = info.CursorPosition
 | 
			
		||||
	}
 | 
			
		||||
	return h.curPos, h.curInfo, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *windowsAnsiEventHandler) updatePos(pos COORD) {
 | 
			
		||||
	if h.curInfo == nil {
 | 
			
		||||
		panic("failed to call getCurrentInfo before calling updatePos")
 | 
			
		||||
	}
 | 
			
		||||
	h.curPos = pos
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// clearWrap clears the state where the cursor is in the margin
 | 
			
		||||
// waiting for the next character before wrapping the line. This must
 | 
			
		||||
// be done before most operations that act on the cursor.
 | 
			
		||||
func (h *windowsAnsiEventHandler) clearWrap() {
 | 
			
		||||
	h.wrapNext = false
 | 
			
		||||
	h.drewMarginByte = false
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user