From d748a7ab87cc56873398f08f5703d1b47ef4db4c Mon Sep 17 00:00:00 2001 From: esimov Date: Sun, 23 May 2021 17:45:09 +0300 Subject: [PATCH] cli: fixed spinner glitches on fast execution --- cmd/triangle/main.go | 26 ++++++++++++++++---------- utils/spinner.go | 13 +++++++++---- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/cmd/triangle/main.go b/cmd/triangle/main.go index 929b181..1ad7ea5 100644 --- a/cmd/triangle/main.go +++ b/cmd/triangle/main.go @@ -54,7 +54,10 @@ const ( TriangleMessage ) -var imgurl *os.File +var ( + imgurl *os.File + spinner *utils.Spinner +) // version indicates the current build version. var version string @@ -104,6 +107,12 @@ func main() { BgColor: *bgColor, } + spinnerText := fmt.Sprintf("%s %s", + decorateText("▲ TRIANGLE", TriangleMessage), + decorateText("is generating the triangulated image...", DefaultMessage)) + + spinner = utils.NewSpinner(spinnerText, time.Millisecond*80, true) + // Supported input image file types. srcExts := []string{".jpg", ".jpeg", ".png"} @@ -331,12 +340,7 @@ func processor(in, out string, proc *triangle.Processor, fn func()) ( defer src.(*os.File).Close() defer dst.(*os.File).Close() - spinnerText := fmt.Sprintf("%s %s", - decorateText("▲ TRIANGLE", TriangleMessage), - decorateText("is generating the triangulated image...", DefaultMessage)) - - s := utils.NewSpinner(spinnerText, time.Millisecond*100, true) - s.Start() + spinner.Start() if filepath.Ext(out) == ".svg" { svg := &triangle.SVG{ @@ -354,10 +358,12 @@ func processor(in, out string, proc *triangle.Processor, fn func()) ( } _, triangles, points, err = tri.Draw(src, dst, fn) } - s.Stop() - fmt.Fprintf(os.Stderr, fmt.Sprintf("%s %s", + stopMsg := fmt.Sprintf("%s %s", decorateText("▲ TRIANGLE", TriangleMessage), - decorateText("is generating the triangulated image... ✔", SuccessMessage))) + decorateText("is generating the triangulated image... ✔", SuccessMessage)) + spinner.StopMsg = stopMsg + + spinner.Stop() return triangles, points, err } diff --git a/utils/spinner.go b/utils/spinner.go index 378cd4b..764df55 100644 --- a/utils/spinner.go +++ b/utils/spinner.go @@ -18,6 +18,7 @@ type Spinner struct { writer io.Writer message string lastOutput string + StopMsg string hideCursor bool stopChan chan struct{} } @@ -49,7 +50,6 @@ func (s *Spinner) Start() { return default: s.mu.Lock() - s.erase(s.lastOutput) // clear the last line output := fmt.Sprintf("\r%s%s %c%s", s.message, SuccessColor, r, DefaultColor) fmt.Fprintf(s.writer, output) @@ -71,21 +71,26 @@ func (s *Spinner) Stop() { // makes the cursor visible fmt.Fprint(s.writer, "\033[?25h") } - s.erase(s.lastOutput) + s.erase() + if len(s.StopMsg) > 0 { + fmt.Fprintf(s.writer, s.StopMsg) + } s.stopChan <- struct{}{} } // erase deletes the last terminal line. // Caller must hold the the locker. -func (s *Spinner) erase(lastOutput string) { - n := utf8.RuneCountInString(lastOutput) +func (s *Spinner) erase() { + n := utf8.RuneCountInString(s.lastOutput) if runtime.GOOS == "windows" { clearString := "\r" + strings.Repeat(" ", n) + "\r" fmt.Fprint(s.writer, clearString) + s.lastOutput = "" return } for _, c := range []string{"\b", "\127", "\b", "\033[K"} { // "\033[K" for macOS Terminal fmt.Fprint(s.writer, strings.Repeat(c, n)) } fmt.Fprintf(s.writer, "\r\033[K") // erases to end of line + s.lastOutput = "" }