1// +build windows 2 3package flags 4 5import ( 6 "syscall" 7 "unsafe" 8) 9 10type ( 11 SHORT int16 12 WORD uint16 13 14 SMALL_RECT struct { 15 Left SHORT 16 Top SHORT 17 Right SHORT 18 Bottom SHORT 19 } 20 21 COORD struct { 22 X SHORT 23 Y SHORT 24 } 25 26 CONSOLE_SCREEN_BUFFER_INFO struct { 27 Size COORD 28 CursorPosition COORD 29 Attributes WORD 30 Window SMALL_RECT 31 MaximumWindowSize COORD 32 } 33) 34 35var kernel32DLL = syscall.NewLazyDLL("kernel32.dll") 36var getConsoleScreenBufferInfoProc = kernel32DLL.NewProc("GetConsoleScreenBufferInfo") 37 38func getError(r1, r2 uintptr, lastErr error) error { 39 // If the function fails, the return value is zero. 40 if r1 == 0 { 41 if lastErr != nil { 42 return lastErr 43 } 44 return syscall.EINVAL 45 } 46 return nil 47} 48 49func getStdHandle(stdhandle int) (uintptr, error) { 50 handle, err := syscall.GetStdHandle(stdhandle) 51 if err != nil { 52 return 0, err 53 } 54 return uintptr(handle), nil 55} 56 57// GetConsoleScreenBufferInfo retrieves information about the specified console screen buffer. 58// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx 59func GetConsoleScreenBufferInfo(handle uintptr) (*CONSOLE_SCREEN_BUFFER_INFO, error) { 60 var info CONSOLE_SCREEN_BUFFER_INFO 61 if err := getError(getConsoleScreenBufferInfoProc.Call(handle, uintptr(unsafe.Pointer(&info)), 0)); err != nil { 62 return nil, err 63 } 64 return &info, nil 65} 66 67func getTerminalColumns() int { 68 defaultWidth := 80 69 70 stdoutHandle, err := getStdHandle(syscall.STD_OUTPUT_HANDLE) 71 if err != nil { 72 return defaultWidth 73 } 74 75 info, err := GetConsoleScreenBufferInfo(stdoutHandle) 76 if err != nil { 77 return defaultWidth 78 } 79 80 if info.MaximumWindowSize.X > 0 { 81 return int(info.MaximumWindowSize.X) 82 } 83 84 return defaultWidth 85} 86