diff --git a/README.md b/README.md index 0395da4..bce5200 100644 --- a/README.md +++ b/README.md @@ -133,3 +133,7 @@ If you have more advanced needs for TUI including raw mode input or readline, yo [github.com/fortio/terminal](https://github.com/fortio/terminal#terminal) And still use this for a progress bar part. + +It is used for instance in [github.com/fortio/fps's web mode progress update](https://github.com/fortio/fps#web-serving-fire-mode) + +And [grol](https://github.com/grol-io/grol#grol)'s multi file processing progress info (`make grol-tests`) diff --git a/examples/simple/example.go b/examples/simple/example.go index 73f6b15..94476cf 100644 --- a/examples/simple/example.go +++ b/examples/simple/example.go @@ -28,10 +28,13 @@ func main() { everyFlag := flag.Duration("every", 1*time.Second, "Print extra stuff every") noAnsiFlag := flag.Bool("no-ansi", false, "Disable ANSI escape codes (colors and cursor movement)") moveUpFlag := flag.Bool("moveup", false, "Demo in place move instead of writer") + noPercent := flag.Bool("no-percent", false, "Disable percent display") + noSuffix := flag.Bool("no-suffix", false, "Disable suffix display") flag.Parse() cfg := progressbar.DefaultConfig() cfg.UseColors = *colorFlag cfg.NoAnsi = *noAnsiFlag + cfg.NoPercent = *noPercent cfg.ScreenWriter = os.Stdout // For playground, defaults to stderr otherwise. pb := cfg.NewBar() w := pb.Writer() @@ -46,6 +49,9 @@ func main() { // exact number of 'pixels', just to demo every smooth step: n := pb.Width * 8 for i := 0; i <= n; i++ { + if !*noSuffix { + pb.UpdateSuffix(fmt.Sprintf(" %d/%d", i, n)) + } pb.Progress(100. * float64(i) / float64(n)) if moveUpMode && i%63 == 0 { pb.MoveCursorUp(1) diff --git a/progressbar.go b/progressbar.go index 580304e..d8d7333 100644 --- a/progressbar.go +++ b/progressbar.go @@ -60,6 +60,10 @@ type Config struct { Spinner bool // Prefix to show before the progress bar (can be updated while running using UpdatePrefix() or through Extra()). Prefix string + // Suffix to show after the percentage information on the bar (can be updated while running using UpdateSuffix()). + Suffix string + // If NoPercent is true, the percentage is not shown on the bar (if the default %.1f%% format is not adequate). + NoPercent bool // Minimum duration between updates (0 to update every time). UpdateInterval time.Duration // Option to avoid all ANSI sequences (useful for non terminal output/test/go playground), @@ -96,6 +100,14 @@ func (bar *Bar) UpdatePrefix(p string) { bar.out.Unlock() } +// UpdateSuffix changes the suffix while the progress bar is running. +// This is thread safe / acquires a shared lock to avoid issues on the output. +func (bar *Bar) UpdateSuffix(s string) { + bar.out.Lock() + bar.Suffix = s + bar.out.Unlock() +} + // Progress shows a progress bar percentage (0-100%). On the same line as current line, // so when call repeatedly it will overwrite/update itself. // Use MoveCursorUp to move up to update other lines as needed or use Writer() @@ -118,7 +130,7 @@ func (bar *Bar) Progress(progressPercent float64) { } barStr := "" progressPercentStr := "" - if progressPercent >= 0 && progressPercent <= 100 { + if progressPercent >= 0 && progressPercent <= 100 { //nolint:nestif // it's not that bad here width := float64(bar.Width) if width == 0 { width = DefaultWidth @@ -137,7 +149,9 @@ func (bar *Bar) Progress(progressPercent float64) { reset = "▻" // "◣" } barStr = color + strings.Repeat(Full, fullCount) + FractionalBlocks[remainder] + strings.Repeat(Space, spaceCount) + reset - progressPercentStr = fmt.Sprintf(" %.1f%%", progressPercent) + if !bar.NoPercent { + progressPercentStr = fmt.Sprintf(" %.1f%%", progressPercent) + } } spinner := "" if bar.Spinner { @@ -157,6 +171,7 @@ func (bar *Bar) Progress(progressPercent float64) { bar.out.buf = append(bar.out.buf, spinner...) bar.out.buf = append(bar.out.buf, barStr...) bar.out.buf = append(bar.out.buf, progressPercentStr...) + bar.out.buf = append(bar.out.buf, bar.Suffix...) bar.out.buf = append(bar.out.buf, extra...) bar.out.buf = append(bar.out.buf, bar.indexBasedMoveUp()...) // bar.out.buf = append(bar.out.buf, '\n') // Uncomment to debug/see all the incremental updates.