| 5 | 5 |
"io"
|
| 6 | 6 |
"os"
|
| 7 | 7 |
"strconv"
|
| 8 | |
"sync"
|
| 9 | 8 |
)
|
| 10 | 9 |
|
| 11 | 10 |
// https://github.com/dylanaraps/pure-sh-bible#cursor-movement
|
|
| 14 | 13 |
cuuAndEd = "A\x1b[J"
|
| 15 | 14 |
)
|
| 16 | 15 |
|
| 17 | |
// used by ansiCuuAndEd func
|
| 18 | |
var escBuf = sync.Pool{
|
| 19 | |
New: func() interface{} {
|
| 20 | |
b := make([]byte, 8)
|
| 21 | |
return &b
|
| 22 | |
},
|
| 23 | |
}
|
| 24 | |
|
| 25 | 16 |
// ErrNotTTY not a TeleTYpewriter error.
|
| 26 | 17 |
var ErrNotTTY = errors.New("not a terminal")
|
| 27 | 18 |
|
|
| 29 | 20 |
// contents of writer will be flushed when Flush is called.
|
| 30 | 21 |
type Writer struct {
|
| 31 | 22 |
*bytes.Buffer
|
|
23 |
ew escWriter
|
| 32 | 24 |
out io.Writer
|
| 33 | 25 |
lines int // used by writer_windows only
|
| 34 | 26 |
fd int
|
|
| 40 | 32 |
func New(out io.Writer) *Writer {
|
| 41 | 33 |
w := &Writer{
|
| 42 | 34 |
Buffer: new(bytes.Buffer),
|
|
35 |
ew: escWriter(make([]byte, 8, 16)),
|
| 43 | 36 |
out: out,
|
| 44 | 37 |
termSize: func(_ int) (int, int, error) {
|
| 45 | 38 |
return -1, -1, ErrNotTTY
|
|
| 62 | 55 |
return w.termSize(w.fd)
|
| 63 | 56 |
}
|
| 64 | 57 |
|
| 65 | |
// if n > 99 it will allocate because escBuf.Get returns slice of length 8
|
| 66 | |
func ansiCuuAndEd(out io.Writer, n int) error {
|
| 67 | |
bufp := escBuf.Get()
|
| 68 | |
buf := *bufp.(*[]byte)
|
| 69 | |
buf = strconv.AppendInt(buf[:copy(buf, escOpen)], int64(n), 10)
|
| 70 | |
_, err := out.Write(append(buf, cuuAndEd...))
|
| 71 | |
escBuf.Put(bufp)
|
|
58 |
type escWriter []byte
|
|
59 |
|
|
60 |
func (b escWriter) ansiCuuAndEd(out io.Writer, n int) error {
|
|
61 |
b = strconv.AppendInt(b[:copy(b, escOpen)], int64(n), 10)
|
|
62 |
_, err := out.Write(append(b, cuuAndEd...))
|
| 72 | 63 |
return err
|
| 73 | 64 |
}
|