refactoring: GetTermSize
Vladimir Bauer
3 years ago
| 19 | 19 | // Writer is a buffered the writer that updates the terminal. The |
| 20 | 20 | // contents of writer will be flushed when Flush is called. |
| 21 | 21 | type Writer struct { |
| 22 | out io.Writer | |
| 23 | buf bytes.Buffer | |
| 24 | lines int | |
| 25 | fd int | |
| 26 | isTerminal bool | |
| 22 | out io.Writer | |
| 23 | buf bytes.Buffer | |
| 24 | lines int // how much lines to clear before flushing new ones | |
| 25 | termSize func() (int, int, error) | |
| 26 | } | |
| 27 | ||
| 28 | func prepareTermSizeFunc(out io.Writer) func() (int, int, error) { | |
| 29 | fn := func() (int, int, error) { | |
| 30 | return -1, -1, ErrNotTTY | |
| 31 | } | |
| 32 | if f, ok := out.(*os.File); ok { | |
| 33 | fd := int(f.Fd()) | |
| 34 | if IsTerminal(fd) { | |
| 35 | fn = func() (int, int, error) { | |
| 36 | return GetSize(fd) | |
| 37 | } | |
| 38 | } | |
| 39 | } | |
| 40 | return fn | |
| 27 | 41 | } |
| 28 | 42 | |
| 29 | 43 | // New returns a new Writer with defaults. |
| 30 | 44 | func New(out io.Writer) *Writer { |
| 31 | w := &Writer{out: out} | |
| 32 | if f, ok := out.(*os.File); ok { | |
| 33 | w.fd = int(f.Fd()) | |
| 34 | w.isTerminal = IsTerminal(w.fd) | |
| 45 | w := &Writer{ | |
| 46 | out: out, | |
| 47 | termSize: prepareTermSizeFunc(out), | |
| 35 | 48 | } |
| 36 | 49 | return w |
| 37 | 50 | } |
| 66 | 79 | return w.buf.ReadFrom(r) |
| 67 | 80 | } |
| 68 | 81 | |
| 69 | // GetWidth returns width of underlying terminal. | |
| 70 | func (w *Writer) GetWidth() (int, error) { | |
| 71 | if !w.isTerminal { | |
| 72 | return -1, ErrNotTTY | |
| 73 | } | |
| 74 | tw, _, err := GetSize(w.fd) | |
| 75 | return tw, err | |
| 82 | // GetTermSize returns WxH of underlying terminal. | |
| 83 | func (w *Writer) GetTermSize() (width, height int, err error) { | |
| 84 | return w.termSize() | |
| 76 | 85 | } |
| 77 | 86 | |
| 78 | 87 | func (w *Writer) ansiCuuAndEd() error { |