gotest.tools/gotestsum@v1.11.0/internal/dotwriter/writer_posix.go (about) 1 //go:build !windows 2 // +build !windows 3 4 package dotwriter 5 6 import ( 7 "bytes" 8 "fmt" 9 ) 10 11 // hide cursor 12 var hide = fmt.Sprintf("%c[?25l", ESC) 13 14 // show cursor 15 var show = fmt.Sprintf("%c[?25h", ESC) 16 17 // Flush the buffer, writing all buffered lines to out 18 func (w *Writer) Flush() error { 19 if w.buf.Len() == 0 { 20 return nil 21 } 22 // Hide cursor during write to avoid it moving around the screen 23 defer w.hideCursor()() 24 25 // Move up to the top of our last output. 26 w.up(w.lineCount) 27 lines := bytes.Split(w.buf.Bytes(), []byte{'\n'}) 28 w.lineCount = len(lines) - 1 // Record how many lines we will write for the next Flush() 29 for i, line := range lines { 30 // For each line, write the contents and clear everything else on the line 31 _, err := w.out.Write(line) 32 if err != nil { 33 return err 34 } 35 w.clearRest() 36 // Add a newline if this isn't the last line 37 if i != len(lines)-1 { 38 _, err := w.out.Write([]byte{'\n'}) 39 if err != nil { 40 return err 41 } 42 } 43 } 44 w.buf.Reset() 45 return nil 46 } 47 48 func (w *Writer) up(count int) { 49 if count == 0 { 50 return 51 } 52 _, _ = fmt.Fprintf(w.out, "%c[%dA", ESC, count) 53 } 54 55 func (w *Writer) clearRest() { 56 _, _ = fmt.Fprintf(w.out, "%c[0K", ESC) 57 } 58 59 // hideCursor hides the cursor and returns a function to restore the cursor back. 60 func (w *Writer) hideCursor() func() { 61 _, _ = fmt.Fprint(w.out, hide) 62 return func() { 63 _, _ = fmt.Fprint(w.out, show) 64 } 65 }