]> Cypherpunks repositories - gostls13.git/commitdiff
text/tabwriter: don't mimic previous lines on flush
authorJosh Bleecher Snyder <josharian@gmail.com>
Sun, 6 May 2018 04:26:23 +0000 (21:26 -0700)
committerRobert Griesemer <gri@golang.org>
Mon, 7 May 2018 17:53:13 +0000 (17:53 +0000)
\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/111644
Reviewed-by: Robert Griesemer <gri@golang.org>
src/text/tabwriter/tabwriter.go

index d2f38be26de719ef62a6ed61185b255a11a2f697..36d999b411ee0bea1d6f5287f90abcefe83763c3 100644 (file)
@@ -106,7 +106,10 @@ type Writer struct {
        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,
        // as that gives us an opportunity
        // to re-use an existing []cell.
@@ -117,13 +120,15 @@ func (b *Writer) addLine() {
                b.lines = append(b.lines, nil)
        }
 
-       // The previous line is probably a good indicator
-       // of how many cells the current line will have.
-       // If the current line's capacity is smaller than that,
-       // abandon it and make a new one.
-       if n := len(b.lines); n >= 2 {
-               if prev := len(b.lines[n-2]); prev > cap(b.lines[n-1]) {
-                       b.lines[n-1] = make([]cell, 0, prev)
+       if !flushed {
+               // The previous line is probably a good indicator
+               // of how many cells the current line will have.
+               // If the current line's capacity is smaller than that,
+               // abandon it and make a new one.
+               if n := len(b.lines); n >= 2 {
+                       if prev := len(b.lines[n-2]); prev > cap(b.lines[n-1]) {
+                               b.lines[n-1] = make([]cell, 0, prev)
+                       }
                }
        }
 }
@@ -136,7 +141,7 @@ func (b *Writer) reset() {
        b.endChar = 0
        b.lines = b.lines[0:0]
        b.widths = b.widths[0:0]
-       b.addLine()
+       b.addLine(true)
 }
 
 // Internal representation (current state):
@@ -527,7 +532,7 @@ func (b *Writer) Write(buf []byte) (n int, err error) {
                                ncells := b.terminateCell(ch == '\t')
                                if ch == '\n' || ch == '\f' {
                                        // terminate line
-                                       b.addLine()
+                                       b.addLine(ch == '\f')
                                        if ch == '\f' || ncells == 1 {
                                                // A '\f' always forces a flush. Otherwise, if the previous
                                                // line has only one cell which does not have an impact on