write esc cuuAndEd to buf rather than to out drectly
Vladimir Bauer
3 years ago
| 21 | 21 |
type Writer struct {
|
| 22 | 22 |
out io.Writer
|
| 23 | 23 |
buf bytes.Buffer
|
| 24 | |
lines int // how much lines to clear before flushing new ones
|
| 25 | 24 |
fd int
|
| 26 | 25 |
terminal bool
|
| 27 | 26 |
termSize func(int) (int, int, error)
|
|
| 48 | 47 |
}
|
| 49 | 48 |
|
| 50 | 49 |
// Flush flushes the underlying buffer.
|
| 51 | |
func (w *Writer) Flush(lines int) (err error) {
|
|
50 |
func (w *Writer) Flush(lines int) error {
|
|
51 |
_, err := w.buf.WriteTo(w.out)
|
| 52 | 52 |
// some terminals interpret 'cursor up 0' as 'cursor up 1'
|
| 53 | |
if w.lines > 0 {
|
| 54 | |
err = w.clearLines()
|
| 55 | |
if err != nil {
|
| 56 | |
return
|
| 57 | |
}
|
|
53 |
if err == nil && lines > 0 {
|
|
54 |
err = w.clearLines(lines)
|
| 58 | 55 |
}
|
| 59 | |
w.lines = lines
|
| 60 | |
_, err = w.buf.WriteTo(w.out)
|
| 61 | |
return
|
|
56 |
return err
|
| 62 | 57 |
}
|
| 63 | 58 |
|
| 64 | 59 |
// Write appends the contents of p to the underlying buffer.
|
|
| 82 | 77 |
return w.termSize(w.fd)
|
| 83 | 78 |
}
|
| 84 | 79 |
|
| 85 | |
func (w *Writer) ansiCuuAndEd() error {
|
|
80 |
func (w *Writer) ansiCuuAndEd(n int) error {
|
| 86 | 81 |
buf := make([]byte, 8)
|
| 87 | |
buf = strconv.AppendInt(buf[:copy(buf, escOpen)], int64(w.lines), 10)
|
| 88 | |
_, err := w.out.Write(append(buf, cuuAndEd...))
|
|
82 |
buf = strconv.AppendInt(buf[:copy(buf, escOpen)], int64(n), 10)
|
|
83 |
_, err := w.buf.Write(append(buf, cuuAndEd...))
|
| 89 | 84 |
return err
|
| 90 | 85 |
}
|
| 5 | 5 |
"golang.org/x/sys/unix"
|
| 6 | 6 |
)
|
| 7 | 7 |
|
| 8 | |
func (w *Writer) clearLines() error {
|
| 9 | |
return w.ansiCuuAndEd()
|
|
8 |
func (w *Writer) clearLines(n int) error {
|
|
9 |
return w.ansiCuuAndEd(n)
|
| 10 | 10 |
}
|
| 11 | 11 |
|
| 12 | 12 |
// GetSize returns the dimensions of the given terminal.
|
| 14 | 14 |
procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
|
| 15 | 15 |
)
|
| 16 | 16 |
|
| 17 | |
func (w *Writer) clearLines() error {
|
|
17 |
func (w *Writer) clearLines(n int) error {
|
| 18 | 18 |
if !w.terminal {
|
| 19 | 19 |
// hope it's cygwin or similar
|
| 20 | 20 |
return w.ansiCuuAndEd()
|
|
| 25 | 25 |
return err
|
| 26 | 26 |
}
|
| 27 | 27 |
|
| 28 | |
info.CursorPosition.Y -= int16(w.lines)
|
|
28 |
info.CursorPosition.Y -= int16(n)
|
| 29 | 29 |
if info.CursorPosition.Y < 0 {
|
| 30 | 30 |
info.CursorPosition.Y = 0
|
| 31 | 31 |
}
|
|
| 39 | 39 |
X: info.Window.Left,
|
| 40 | 40 |
Y: info.CursorPosition.Y,
|
| 41 | 41 |
}
|
| 42 | |
count := uint32(info.Size.X) * uint32(w.lines)
|
|
42 |
count := uint32(info.Size.X) * uint32(n)
|
| 43 | 43 |
_, _, _ = procFillConsoleOutputCharacter.Call(
|
| 44 | 44 |
uintptr(w.fd),
|
| 45 | 45 |
uintptr(' '),
|