1// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd solaris 2 3package readline 4 5import ( 6 "io" 7 "os" 8 "os/signal" 9 "sync" 10 "syscall" 11) 12 13type winsize struct { 14 Row uint16 15 Col uint16 16 Xpixel uint16 17 Ypixel uint16 18} 19 20// SuspendMe use to send suspend signal to myself, when we in the raw mode. 21// For OSX it need to send to parent's pid 22// For Linux it need to send to myself 23func SuspendMe() { 24 p, _ := os.FindProcess(os.Getppid()) 25 p.Signal(syscall.SIGTSTP) 26 p, _ = os.FindProcess(os.Getpid()) 27 p.Signal(syscall.SIGTSTP) 28} 29 30// get width of the terminal 31func getWidth(stdoutFd int) int { 32 cols, _, err := GetSize(stdoutFd) 33 if err != nil { 34 return -1 35 } 36 return cols 37} 38 39func GetScreenWidth() int { 40 w := getWidth(syscall.Stdout) 41 if w < 0 { 42 w = getWidth(syscall.Stderr) 43 } 44 return w 45} 46 47// ClearScreen clears the console screen 48func ClearScreen(w io.Writer) (int, error) { 49 return w.Write([]byte("\033[H")) 50} 51 52func DefaultIsTerminal() bool { 53 return IsTerminal(syscall.Stdin) && (IsTerminal(syscall.Stdout) || IsTerminal(syscall.Stderr)) 54} 55 56func GetStdin() int { 57 return syscall.Stdin 58} 59 60// ----------------------------------------------------------------------------- 61 62var ( 63 widthChange sync.Once 64 widthChangeCallback func() 65) 66 67func DefaultOnWidthChanged(f func()) { 68 widthChangeCallback = f 69 widthChange.Do(func() { 70 ch := make(chan os.Signal, 1) 71 signal.Notify(ch, syscall.SIGWINCH) 72 73 go func() { 74 for { 75 _, ok := <-ch 76 if !ok { 77 break 78 } 79 widthChangeCallback() 80 } 81 }() 82 }) 83} 84