diff --git a/cwriter/writer.go b/cwriter/writer.go index cbbc7d9..61be02b 100644 --- a/cwriter/writer.go +++ b/cwriter/writer.go @@ -26,19 +26,12 @@ // Flush flushes the underlying buffer func (w *Writer) Flush() error { - // do nothing if buffer is empty - if len(w.buf.Bytes()) == 0 { + // Do nothing if buffer is empty + if w.buf.Len() == 0 { return nil } w.clearLines() - - lines := 0 - for _, b := range w.buf.Bytes() { - if b == '\n' { - lines++ - } - } - w.lineCount = lines + w.lineCount = bytes.Count(w.buf.Bytes(), []byte("\n")) _, err := w.out.Write(w.buf.Bytes()) w.buf.Reset() return err diff --git a/cwriter/writer_posix.go b/cwriter/writer_posix.go index fd8aea0..a39bb7b 100644 --- a/cwriter/writer_posix.go +++ b/cwriter/writer_posix.go @@ -8,10 +8,15 @@ "unsafe" ) +var ( + cursorUp = fmt.Sprintf("%c[%dA", ESC, 1) + clearLine = fmt.Sprintf("%c[2K\r", ESC) + clearCursorAndLine = cursorUp + clearLine +) + func (w *Writer) clearLines() { for i := 0; i < w.lineCount; i++ { - fmt.Fprintf(w.out, "%c[%dA", ESC, 1) // move the cursor up - fmt.Fprintf(w.out, "%c[2K\r", ESC) // clear the line + fmt.Fprint(w.out, clearCursorAndLine) } } diff --git a/cwriter/writer_posix_test.go b/cwriter/writer_posix_test.go new file mode 100644 index 0000000..30e6c25 --- /dev/null +++ b/cwriter/writer_posix_test.go @@ -0,0 +1,36 @@ +// +build !windows + +package cwriter_test + +import ( + "bytes" + "fmt" + "testing" + + "github.com/vbauerster/mpb/cwriter" +) + +var clearSequence = fmt.Sprintf("%c[%dA%c[2K\r", 27, 1, 27) + +// TestWriterPosix by writing and flushing many times. The output buffer +// must contain the clearCursor and clearLine sequences. +func TestWriterPosix(t *testing.T) { + out := new(bytes.Buffer) + w := cwriter.New(out) + + testCases := []struct { + input, expectedOutput string + }{ + {input: "foo\n", expectedOutput: "foo\n"}, + {input: "bar\n", expectedOutput: "foo\n" + clearSequence + "bar\n"}, + {input: "fizz\n", expectedOutput: "foo\n" + clearSequence + "bar\n" + clearSequence + "fizz\n"}, + } + for _, testCase := range testCases { + w.Write([]byte(testCase.input)) + w.Flush() + output := out.String() + if output != testCase.expectedOutput { + t.Fatalf("want %q, got %q", testCase.expectedOutput, output) + } + } +}