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  }