Oleg Sydorov
Oleg Sydorov

Reputation: 709

golang erase symbols from console

I want to create animation in console, when program waits. There are a lot of simple ways to do this, usually, we just draw symbols in iterations of some cycle. Let our code be:

func Spinner(delay time.Duration) {
    for !StopSpinner{
        for _, r := range `-\|/` {
            fmt.Printf("\r%c", r)
            time.Sleep(delay)
        }
    }
}

The problem is - how to remove animation, when there is no need in it from the console screen. I tried escape sequences like fmt.Print("\b") or fmt.Printf("\r%s", "") but no result. I can not remove last symbol from screen and it concatenates with next text. How do you erase characters already printed to the console?

Upvotes: 5

Views: 4917

Answers (3)

David Budworth
David Budworth

Reputation: 11626

All you need to do is print a space (0x20) when you are done and that will overwrite the spinner.

ie: fmt.Fprint(os.Stdout, "\r \r") to put the cursor back to beginning of line after the space.

Upvotes: 9

Oleg Sydorov
Oleg Sydorov

Reputation: 709

All you need to do is print a space (0x20) when you are done and that will overwrite the spinner.

ie: fmt.Fprint("\r \r") to put the cursor back to beginning of line after the space.

This answer is helpful, thank you! But, there is an important detail! Because the spinner function has a delay, it cannot stop exactly when StopSpinner boolean flag is set to true. So, I have added a channel for synchronization.

func Spinner(delay time.Duration) {
    for !StopSpinner {
        for _, r := range `-\|/` {
            fmt.Printf("\r%c", r)
            time.Sleep(delay)
        }
    }
    fmt.Fprint("\r \r")
    c <- struct{}{}
}

Now, calling function waits, while my spinner stop.

var c chan struct{} = make(chan struct{}) // event marker

func callingFunc(){
  StopSpinner = false
  go Spinner(100 * time.Millisecond)

  // do something...
   StopSpinner = true

   <-c // wait spinner stop

   //do something else
}

In my opinion, this is the complete solution!

Upvotes: 4

Iain Duncan
Iain Duncan

Reputation: 3394

fmt.Print("\033[H\033[2J")

This will put the cursor in the top left then clear the console as per this document of useful terminal commands:

https://www.student.cs.uwaterloo.ca/~cs452/terminal.html

Upvotes: 2

Related Questions