github.com/kopoli/go-terminal-size@v0.0.0-20170219200355-5c97524c8b54/size.go (about) 1 // Package tsize gets the terminal size. Supports Linux and Windows. 2 package tsize 3 4 import ( 5 "errors" 6 "os" 7 8 isatty "github.com/mattn/go-isatty" 9 ) 10 11 // Size represents terminal size in columns and rows as Width and Height, 12 // respectively. 13 type Size struct { 14 Width int 15 Height int 16 } 17 18 var isTerminal = isatty.IsTerminal 19 20 // ErrNotATerminal is the error to return if the given file to FgetSize isn't a 21 // terminal. 22 var ErrNotATerminal = errors.New("Given file is not a terminal") 23 24 // GetSize gets the current terminal size. The terminal is expected to be 25 // os.Stdout. Returns the NotATerminal error, if it is not a terminal. 26 func GetSize() (s Size, err error) { 27 return FgetSize(os.Stdout) 28 } 29 30 // FgetSize gets the terminal size of a given os.File. Returns the NotATerminal error, if it is not a terminal. 31 func FgetSize(fp *os.File) (s Size, err error) { 32 if fp == nil || !isTerminal(fp.Fd()) { 33 err = ErrNotATerminal 34 return 35 } 36 37 s, err = getTerminalSize(fp) 38 return 39 } 40 41 // SizeListener listens to terminal size changes. The new size is returned 42 // through the Change channel when the change occurs. 43 type SizeListener struct { 44 Change <-chan Size 45 46 done chan struct{} 47 } 48 49 // Close implements the io.Closer interface that stops listening to terminal 50 // size changes. 51 func (sc *SizeListener) Close() (err error) { 52 if sc.done != nil { 53 close(sc.done) 54 sc.done = nil 55 sc.Change = nil 56 } 57 58 return 59 } 60 61 // NewSizeListener creates a new size change listener 62 func NewSizeListener() (sc *SizeListener, err error) { 63 sc = &SizeListener{} 64 65 sizechan := make(chan Size, 1) 66 sc.Change = sizechan 67 sc.done = make(chan struct{}) 68 69 err = getTerminalSizeChanges(sizechan, sc.done) 70 if err != nil { 71 close(sizechan) 72 close(sc.done) 73 sc = &SizeListener{} 74 return 75 } 76 77 return 78 }