Commit a33c5957 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder Committed by Robert Griesemer

text/tabwriter: don't mimic previous lines on flush

\f triggers a flush.

This is used (by gofmt, among others) to indicate that
the current aligned segment has ended.

When flushed, it is unlikely that the previous line is
in fact a good predictor of the upcoming line,
so stop treating it as such.

No performance impact on the existing benchmarks,
which do not perform any flushes.

Change-Id: Ifdf3e6d4600713c90db7b51a10e429d9260dc08c
Reviewed-on: https://go-review.googlesource.com/111644Reviewed-by: default avatarRobert Griesemer <gri@golang.org>
parent 3fbfc83d
...@@ -106,7 +106,10 @@ type Writer struct { ...@@ -106,7 +106,10 @@ type Writer struct {
widths []int // list of column widths in runes - re-used during formatting widths []int // list of column widths in runes - re-used during formatting
} }
func (b *Writer) addLine() { // addLine adds a new line.
// flushed is a hint indicating whether the underlying writer was just flushed.
// If so, the previous line is not likely to be a good indicator of the new line's cells.
func (b *Writer) addLine(flushed bool) {
// Grow slice instead of appending, // Grow slice instead of appending,
// as that gives us an opportunity // as that gives us an opportunity
// to re-use an existing []cell. // to re-use an existing []cell.
...@@ -117,6 +120,7 @@ func (b *Writer) addLine() { ...@@ -117,6 +120,7 @@ func (b *Writer) addLine() {
b.lines = append(b.lines, nil) b.lines = append(b.lines, nil)
} }
if !flushed {
// The previous line is probably a good indicator // The previous line is probably a good indicator
// of how many cells the current line will have. // of how many cells the current line will have.
// If the current line's capacity is smaller than that, // If the current line's capacity is smaller than that,
...@@ -126,6 +130,7 @@ func (b *Writer) addLine() { ...@@ -126,6 +130,7 @@ func (b *Writer) addLine() {
b.lines[n-1] = make([]cell, 0, prev) b.lines[n-1] = make([]cell, 0, prev)
} }
} }
}
} }
// Reset the current state. // Reset the current state.
...@@ -136,7 +141,7 @@ func (b *Writer) reset() { ...@@ -136,7 +141,7 @@ func (b *Writer) reset() {
b.endChar = 0 b.endChar = 0
b.lines = b.lines[0:0] b.lines = b.lines[0:0]
b.widths = b.widths[0:0] b.widths = b.widths[0:0]
b.addLine() b.addLine(true)
} }
// Internal representation (current state): // Internal representation (current state):
...@@ -527,7 +532,7 @@ func (b *Writer) Write(buf []byte) (n int, err error) { ...@@ -527,7 +532,7 @@ func (b *Writer) Write(buf []byte) (n int, err error) {
ncells := b.terminateCell(ch == '\t') ncells := b.terminateCell(ch == '\t')
if ch == '\n' || ch == '\f' { if ch == '\n' || ch == '\f' {
// terminate line // terminate line
b.addLine() b.addLine(ch == '\f')
if ch == '\f' || ncells == 1 { if ch == '\f' || ncells == 1 {
// A '\f' always forces a flush. Otherwise, if the previous // A '\f' always forces a flush. Otherwise, if the previous
// line has only one cell which does not have an impact on // line has only one cell which does not have an impact on
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment