schollz / progressbar

A really basic thread-safe progress bar for Golang applications

Home Page:https://pkg.go.dev/github.com/schollz/progressbar/v3?tab=doc

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add a way to reduce flickering for ANSI code compatible environments

kirides opened this issue · comments

Since there is no way to determine if a terminal (emulator) supports certain ansi escape codes, it would be nice to offer a "option" that would allow to use ANSI escape codes to reduce terminal writes to the required minimum

This would allow for a more flicker-free experience (atleast for windows users)
currently the progressbar flickers when used in the "Windows Terminal", or a conhost environment.
This is due to the call to "clearProgressBar" which happens on every single render call.

func (p *ProgressBar) render() error {
    // ...
    
    // first, clear the existing progress bar
    err := clearProgressBar(p.config, p.state)
    if err != nil {
        return err
    }
    // either returns because finished, or renders current progress

by only calling the clear function if "finished" and otherwise appending the ANSI escape sequence of \033[0K to the rendered string, we can write a full clean line in just one write call, without a prior clear.

This however is only supported on terminal(emulators) that support ANSI escape sequences, like virtually every unix terminal and Windows 10 conhost (opt-in 1) and "Windows Terminal"

Before using the ANSI escape code option:
before

After:
after

I do not want the progressBar to implement windows specific code, but for it to offer a way to make use of ANSI escape sequences if a specific option is provided. e.g.

func OptionUseANSICodes(val bool) Option {
	return func(p *ProgressBar) {
		p.config.useANSICodes = val
	}
}

 
 
 
 
 
1 atleast ENABLE_VIRTUAL_TERMINAL_PROCESSING (0x04) must be enabled on the terminal output console handle (e.g. os.Stderr.Fd()) to support escape codes. This is easily achieved using syscall.LazyDll and calling the GetConsoleMode + SetConsoleMode Kernel32-APIs to enable the flags on demand.
This is code that shows how easy it can be to implement.
image

commented

Interesting! Would welcome a PR for this!

commented

Added in v3.7.0!