forked from pachyderm/pachyderm
/
tabwriter.go
59 lines (53 loc) · 1.43 KB
/
tabwriter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package tabwriter
import (
"bytes"
"io"
"text/tabwriter"
)
const (
// termHeight is the default height of a terminal.
termHeight = 50
)
// Writer is like tabwriter.Writer in the stdlibexcept that it's suitable for
// large numbers of items because it periodically flushes its contents and
// reprints a header when it does.
type Writer struct {
w *tabwriter.Writer
lines int
header []byte
}
// NewWriter returns a new Writer, it will flush when
// it gets termHeight many lines, including the header line.
// The header line will be reprinted termHeight many lines have been written.
// NewStreamingWriter will panic if it's given a header that doesn't end in \n.
func NewWriter(w io.Writer, header string) *Writer {
if header[len(header)-1] != '\n' {
panic("header must end in a new line")
}
tabwriter := tabwriter.NewWriter(w, 0, 1, 1, ' ', 0)
tabwriter.Write([]byte(header))
return &Writer{
w: tabwriter,
lines: 1, // 1 because we just printed the header
header: []byte(header),
}
}
// Write writes a line to the tabwriter.
func (w *Writer) Write(buf []byte) (int, error) {
if w.lines >= termHeight {
if err := w.Flush(); err != nil {
return 0, err
}
if _, err := w.w.Write(w.header); err != nil {
return 0, err
}
w.lines++
}
w.lines += bytes.Count(buf, []byte{'\n'})
return w.w.Write(buf)
}
// Flush flushes the underlying tab writer.
func (w *Writer) Flush() error {
w.lines = 0
return w.w.Flush()
}