### DefaultConfig() Config Source: https://context7.com/fortio/progressbar/llms.txt Returns a Config struct with sensible defaults for creating a progress bar. This is a good starting point for customization. ```APIDOC ## DefaultConfig() Config ### Description Returns a `Config` struct pre-filled with sensible defaults: `Width=40`, colors enabled with `GreenBar`, spinner enabled, and a 100ms update interval. Use this as the starting point before customizing individual fields and calling `cfg.NewBar()`. ### Usage ```go cfg := progressbar.DefaultConfig() cfg.UseColors = false // disable color (e.g., for CI output) cfg.NoAnsi = false // keep cursor movement cfg.Prefix = "Downloading " // static label before the bar cfg.Suffix = " please wait" // static label after percentage pb := cfg.NewBar() n := 200 for i := 0; i <= n; i++ { pb.Progress(100.0 * float64(i) / float64(n)) time.Sleep(10 * time.Millisecond) } b.End() fmt.Println("done") ``` ``` -------------------------------- ### Create and Use Basic Progress Bar Source: https://context7.com/fortio/progressbar/llms.txt Shows the quickest way to initialize a single progress bar with default settings attached to the global screen writer. Ideal for simple progress tracking without complex configuration. ```go package main import ( "time" "fortio.org/progressbar" ) func main() { pb := progressbar.NewBar() steps := 50 for i := 0; i <= steps; i++ { pb.Progress(100.0 * float64(i) / float64(steps)) time.Sleep(40 * time.Millisecond) } pb.End() // Terminal output (color mode): // ⣾ [green bar fills to 100%] 100.0% // ✓ [final newline printed by End()] } ``` -------------------------------- ### Create and Use Default Progress Bar with Custom Config Source: https://context7.com/fortio/progressbar/llms.txt Demonstrates creating a progress bar using default configuration and then customizing fields like disabling colors, setting prefix/suffix labels. Useful for applications needing a progress bar with specific visual or textual elements. ```go package main import ( "fmt" "time" "fortio.org/progressbar" ) func main() { cfg := progressbar.DefaultConfig() cfg.UseColors = false // disable color (e.g., for CI output) cfg.NoAnsi = false // keep cursor movement cfg.Prefix = "Downloading " // static label before the bar cfg.Suffix = " please wait" // static label after percentage pb := cfg.NewBar() n := 200 for i := 0; i <= n; i++ { pb.Progress(100.0 * float64(i) / float64(n)) time.Sleep(10 * time.Millisecond) } pb.End() fmt.Println("done") // Output on terminal (no color): // Downloading ◅████████████████████████████████████████▻ 100.0% please wait } ``` -------------------------------- ### Progress Bar with Custom Screen Writer and Spinner Source: https://context7.com/fortio/progressbar/llms.txt Illustrates how to redirect progress bar output to `os.Stdout` instead of the default `os.Stderr` and enable a spinner. Useful for integrating progress bars into pipelines or when specific output streams are required. ```go package main import ( "os" "time" "fortio.org/progressbar" ) func main() { cfg := progressbar.DefaultConfig() cfg.ScreenWriter = os.Stdout // write to stdout instead of stderr cfg.Spinner = true pb := cfg.NewBar() total := 1000 for i := 0; i <= total; i++ { pb.Progress(float64(i) / float64(total) * 100) time.Sleep(2 * time.Millisecond) } pb.End() } ``` -------------------------------- ### Create and Manage Multiple Progress Bars Source: https://context7.com/fortio/progressbar/llms.txt Creates a MultiBar with one Bar per prefix string, sharing Config settings and laid out vertically. Requires ANSI cursor movement; NoAnsi must not be set. Prefix widths are automatically aligned. ```go package main import ( "fmt" "math/rand/v2" "os" "sync" "time" "fortio.org/progressbar" ) func main() { fmt.Println("Parallel downloads" + progressbar.ClearAfter) cfg := progressbar.DefaultConfig() cfg.ExtraLines = 1 cfg.ScreenWriter = os.Stdout mbar := cfg.NewMultiBarPrefixes("file-A", "file-B", "file-C") wg := sync.WaitGroup{} colors := []string{progressbar.GreenBar, progressbar.BlueBar, progressbar.YellowBar} for i, bar := range mbar.Bars { bar.Color = colors[i] wg.Add(1) delay := time.Duration(10+rand.IntN(30)) * time.Millisecond go func(b *progressbar.Bar, d time.Duration) { defer wg.Done() for j := 0; j <= 100; j++ { b.Progress(float64(j)) time.Sleep(d) } }(bar, delay) } wg.Wait() mbar.End() } ``` -------------------------------- ### Multiple Bars Updating Concurrently Source: https://github.com/fortio/progressbar/blob/main/README.md Demonstrates setting up and managing multiple progress bars that update concurrently. Useful for tracking multiple independent tasks simultaneously. ```go cfg := progressbar.DefaultConfig() cfg.ExtraLines = 1 cfg.ScreenWriter = os.Stdout mbar := cfg.NewMultiBarPrefixes( "b1", "longest prefix", "short", "b4", ) wg := sync.WaitGroup{} for i, bar := range mbar { wg.Add(1) // Update at random speed so bars move differently for a demo: delay := time.Duration(5+rand.IntN(40)) * time.Millisecond bar.WriteAbove(fmt.Sprintf("\t\t\tBar %d delay is %v", i+1, delay)) go func(b *progressbar.State) { UpdateBar(b, delay) wg.Done() }(bar) } wg.Wait() progressbar.MultiBarEnd(mbar) ``` -------------------------------- ### Assemble MultiBar from Existing Bars Source: https://context7.com/fortio/progressbar/llms.txt Assembles a MultiBar from pre-configured Bar instances. Use this when bars require individual configuration before being grouped. The MultiBar lays out all provided bars vertically. ```go package main import ( "fmt" "io" "net/http" "os" "fortio.org/progressbar" ) func main() { urls := []string{"https://go.dev/", "https://pkg.go.dev/"} cfg := progressbar.DefaultConfig() cfg.ScreenWriter = os.Stderr bars := make([]*progressbar.Bar, len(urls)) for i, u := range urls { cfg.Prefix = fmt.Sprintf("URL%d ", i+1) bars[i] = cfg.NewBar() _ = u // start fetch goroutines in real use } cfg.NewMultiBar(bars...) // lays out all bars vertically // Simulate progress updates. for _, b := range bars { b.Progress(50) } for _, b := range bars { b.Progress(100) b.End() } _ = io.Discard // suppress unused import _ = http.MethodGet } ``` -------------------------------- ### Manually Update Progress Bar and Output Source: https://github.com/fortio/progressbar/blob/main/README.md Demonstrates manual control of a progress bar and updating additional output lines. Use when precise control over progress and interspersed messages is needed. ```go pb := progressbar.NewBar() fmt.Print("Progress bar example\n\n") // 1 empty line before the progress bar, for the demo n := 1000 for i := 0; i <= n; i++ { pb.ProgressBar(100. * float64(i) / float64(n)) if i%63 == 0 { progressbar.MoveCursorUp(1) fmt.Printf("Just an extra demo print for %d\n", i) } time.Sleep(20 * time.Millisecond) } ``` -------------------------------- ### NewBar() *Bar Source: https://context7.com/fortio/progressbar/llms.txt Creates a new progress bar with default settings, writing to os.Stderr. This is a quick way to initialize a progress bar without explicit configuration. ```APIDOC ## NewBar() *Bar ### Description Creates a `*Bar` with default settings attached to the global shared `screenWriter` (writes to `os.Stderr`). This is the quickest way to get a single progress bar running without any configuration ceremony. ### Usage ```go pb := progressbar.NewBar() steps := 50 for i := 0; i <= steps; i++ { pb.Progress(100.0 * float64(i) / float64(steps)) time.Sleep(40 * time.Millisecond) } pb.End() ``` ``` -------------------------------- ### Dynamically Update Progress Bar Prefix and Suffix Source: https://context7.com/fortio/progressbar/llms.txt Use `UpdatePrefix()` and `UpdateSuffix()` for thread-safe changes to the text displayed before and after the progress bar. The changes are reflected on the next `Progress()` call. ```Go package main import ( "fmt" "time" "fortio.org/progressbar" ) func main() { pb := progressbar.NewBar() files := []string{"main.go", "util.go", "handler.go", "model.go"} for i, f := range files { pb.UpdatePrefix(fmt.Sprintf("[%s] ", f)) pb.UpdateSuffix(fmt.Sprintf(" %d/%d files", i+1, len(files))) // Simulate per-file work. steps := 20 for j := 0; j <= steps; j++ { pb.Progress(float64(j) / float64(steps) * 100) time.Sleep(20 * time.Millisecond) } } pb.End() } ``` -------------------------------- ### Standalone Spinner for Unknown Progress Source: https://context7.com/fortio/progressbar/llms.txt Utilize the `Spinner()` function to display an animated spinner on `os.Stderr` when the total progress is unknown. This provides an activity indicator without a percentage completion. ```Go package main import ( "fmt" "time" "fortio.org/progressbar" ) func main() { done := make(chan struct{}) go func() { for { select { case <-done: fmt.Print("\r\033[K") // erase spinner return default: progressbar.Spinner() time.Sleep(100 * time.Millisecond) } } }() time.Sleep(2 * time.Second) // simulate unknown-length work close(done) time.Sleep(50 * time.Millisecond) fmt.Println("done") } ``` -------------------------------- ### Custom I/O Progress Tracking with AutoProgress Source: https://context7.com/fortio/progressbar/llms.txt Uses AutoProgress as a lower-level building block for custom I/O wrappers. Call Update(n) from any goroutine to increment the byte counter and redraw the bar. This is the foundation for AutoProgressReader and AutoProgressWriter. ```go package main import ( "fmt" "sync" "time" "fortio.org/progressbar" ) func main() { const total = 100 bar := progressbar.NewBar() ap := progressbar.NewAutoProgress(bar, total) var wg sync.WaitGroup // Simulate 4 parallel workers each contributing 25 units. for w := 0; w < 4; w++ { wg.Add(1) go func() { defer wg.Done() for i := 0; i < 25; i++ { time.Sleep(20 * time.Millisecond) ap.Update(1) } }() } wg.Wait() bar.End() fmt.Println("all workers done") } ``` -------------------------------- ### Concurrent Safe Screen Writer with Progress Bar Source: https://github.com/fortio/progressbar/blob/main/README.md Shows how to use a progress bar's writer for concurrent output while the progress bar updates. Useful for displaying dynamic information alongside progress. ```go pb := progressbar.NewBar() w := pb.Writer() fmt.Fprintln(w, "Progress bar example") // demonstrate concurrency safety: go PrintStuff(w, *everyFlag) // exact number of 'pixels', just to demo every smooth step: n := pb.Width * 8 for i := 0; i <= n; i++ { pb.ProgressBar(100. * float64(i) / float64(n)) time.Sleep(*delayFlag) } ``` -------------------------------- ### Add Source: https://context7.com/fortio/progressbar/llms.txt Dynamically adds one or more bars to an existing MultiBar while it is running, adjusting terminal space and cursor position. ```APIDOC ## (*MultiBar).Add(mbars ...*Bar) *MultiBar ### Description Dynamically adds one or more bars to an existing `*MultiBar` while it is already running. Reserves terminal space for the new bars and repositions the cursor correctly. Call `PrefixesAlign()` afterward if the new bars' prefixes are longer than existing ones. ### Parameters * `mbars` (...*Bar) - A variable number of `Bar` instances to add to the `MultiBar`. ### Returns * `*MultiBar` - The modified `MultiBar` instance with the added bars. ``` -------------------------------- ### NewMultiBarPrefixes Source: https://context7.com/fortio/progressbar/llms.txt Creates a MultiBar containing one Bar per prefix string, useful for managing multiple progress bars simultaneously with shared configuration. ```APIDOC ## (Config).NewMultiBarPrefixes(prefixes ...string) *MultiBar ### Description Creates a `*MultiBar` containing one `*Bar` per prefix string. All bars share the same `Config` settings and are laid out vertically on the terminal with `ExtraLines` blank lines between each. Prefix widths are automatically aligned. ANSI cursor movement is required; `NoAnsi` must not be set for multi-bar mode. ### Parameters * `prefixes` (...string) - A variable number of prefix strings for each bar. ### Returns * `*MultiBar` - A new `MultiBar` instance containing the created bars. ``` -------------------------------- ### UpdatePrefix(p string) / UpdateSuffix(s string) Source: https://context7.com/fortio/progressbar/llms.txt Thread-safe setters to change the bar's prefix or suffix dynamically while it is running. The changes are reflected on the next `Progress()` call. ```APIDOC ## (*Bar).UpdatePrefix(p string) / (*Bar).UpdateSuffix(s string) ### Description Thread-safe setters that change the bar's prefix (text before the bar) or suffix (text after the percentage) at any time while the bar is running. The new value is reflected on the next `Progress()` call. ### Usage Example ```go pb := progressbar.NewBar() files := []string{"main.go", "util.go", "handler.go", "model.go"} for i, f := range files { pb.UpdatePrefix(fmt.Sprintf("[%s] ", f)) pb.UpdateSuffix(fmt.Sprintf(" %d/%d files", i+1, len(files))) // Simulate per-file work. steps := 20 for j := 0; j <= steps; j++ { pb.Progress(float64(j) / float64(steps) * 100) time.Sleep(20 * time.Millisecond) } } pb.End() ``` ``` -------------------------------- ### Spinner() Source: https://context7.com/fortio/progressbar/llms.txt A package-level function that displays a standalone animated spinner on `os.Stderr` using a global shared writer. Ideal for situations where progress is unknown. ```APIDOC ## Spinner() ### Description Package-level function that draws a standalone animated spinner on `os.Stderr` using the global shared writer. Use this when progress toward 100 % is unknown and only an activity indicator is needed. ### Usage Example ```go done := make(chan struct{}) go func() { for { select { case <-done: fmt.Print("\r\033[K") // erase spinner return default: progressbar.Spinner() time.Sleep(100 * time.Millisecond) } } }() time.Sleep(2 * time.Second) // simulate unknown-length work close(done) time.Sleep(50 * time.Millisecond) fmt.Println("done") ``` ``` -------------------------------- ### Auto-Progress Reader for I/O Operations Source: https://context7.com/fortio/progressbar/llms.txt Wrap an `io.Reader` with `NewAutoReader()` to automatically update a progress bar during read operations. Handles unknown totals by displaying a spinner and speed metrics. The returned reader implements `io.Reader` and `io.Closer`. ```Go package main import ( "fmt" "io" "net/http" "os" "fortio.org/progressbar" ) func downloadFile(url string) error { resp, err := http.Get(url) //nolint:gosec if err != nil { return err } // ContentLength is -1 when unknown; NewAutoReader handles that gracefully. bar := progressbar.NewBar() reader := progressbar.NewAutoReader(bar, resp.Body, resp.ContentLength) defer reader.Close() // also calls bar.End() _, err = io.Copy(os.Stdout, reader) if err != nil { return fmt.Errorf("copy: %w", err) } return nil } func main() { if err := downloadFile("https://go.dev/"); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } // Terminal (stderr) shows while downloading: // ⣾ ██████████████████▌ 46.2% 1.234 Mb out of 2.671 Mb, 120ms elapsed, 10.283 Mb/s, 140ms remaining } ``` -------------------------------- ### Wrap io.Writer for Upload Progress Tracking Source: https://context7.com/fortio/progressbar/llms.txt Wraps an io.Writer to advance a progress bar with every Write call. Useful for tracking upload progress or other write-side I/O. Ensure the writer is closed to finalize the progress bar. ```go package main import ( "bufio" "fmt" "os" "strings" "fortio.org/progressbar" ) func main() { data := strings.Repeat("hello world\n", 10_000) total := int64(len(data)) bar := progressbar.NewBar() dest := bufio.NewWriter(os.Stdout) writer := progressbar.NewAutoWriter(bar, dest, total) defer writer.Close() _, err := writer.Write([]byte(data)) if err != nil { fmt.Fprintln(os.Stderr, err) } // Progress bar on stderr reflects bytes written in real time. } ``` -------------------------------- ### Align Prefixes in Multi-Bar Layout Source: https://context7.com/fortio/progressbar/llms.txt Call `PrefixesAlign()` after adding new bars or updating existing prefixes to ensure all bar prefixes are visually aligned. This is automatically handled by `NewMultiBarPrefixes`. ```go package main import ( "os" "time" "fortio.org/progressbar" ) func main() { cfg := progressbar.DefaultConfig() cfg.ScreenWriter = os.Stdout mbar := cfg.NewMultiBarPrefixes("short", "medium len", "x") // Dynamically rename a prefix mid-run. time.Sleep(500 * time.Millisecond) mbar.Bars[2].UpdatePrefix("very long new prefix") mbar.PrefixesAlign() // re-align all bars for _, b := range mbar.Bars { b.Progress(100) } mbar.End() } ``` -------------------------------- ### Dynamically Add Bars to a Running MultiBar Source: https://context7.com/fortio/progressbar/llms.txt Dynamically adds one or more bars to an existing MultiBar while it is running. Reserves terminal space and repositions the cursor. Call PrefixesAlign() after adding bars if new prefixes are longer than existing ones. ```go package main import ( "fmt" "os" "sync" "time" "fortio.org/progressbar" ) func main() { fmt.Println("Dynamic multi-bar demo" + progressbar.ClearAfter) cfg := progressbar.DefaultConfig() cfg.ScreenWriter = os.Stdout cfg.ExtraLines = 0 mbar := cfg.NewMultiBarPrefixes("initial") wg := sync.WaitGroup{} wg.Add(1) go func() { defer wg.Done() for i := 0; i <= 100; i++ { mbar.Bars[0].Progress(float64(i)) time.Sleep(30 * time.Millisecond) } }() // After 1 second, add a second bar. time.Sleep(1 * time.Second) cfg.Prefix = "added later" newBar := cfg.NewBar() mbar.Add(newBar) mbar.PrefixesAlign() wg.Add(1) go func() { defer wg.Done() for i := 0; i <= 100; i++ { newBar.Progress(float64(i)) time.Sleep(15 * time.Millisecond) } }() wg.Wait() mbar.End() } ``` -------------------------------- ### NewAutoWriter Source: https://context7.com/fortio/progressbar/llms.txt Wraps an io.Writer so that every Write call advances the progress bar. This is useful for tracking upload progress or any write-side I/O operations. ```APIDOC ## NewAutoWriter(bar *Bar, w io.Writer, total int64) *AutoProgressWriter ### Description Wraps an `io.Writer` so that every `Write` call advances the bar. Mirrors `NewAutoReader` in API and behaviour. Useful for upload progress or any write-side I/O tracking. ### Parameters * `bar` (*Bar) - The progress bar instance to update. * `w` (io.Writer) - The underlying writer to wrap. * `total` (int64) - The total number of bytes expected to be written. ### Returns * `*AutoProgressWriter` - A new `AutoProgressWriter` instance. ``` -------------------------------- ### Finalize Progress Bar and Print Subsequent Output Source: https://context7.com/fortio/progressbar/llms.txt Demonstrates the use of the `End()` method to finalize a progress bar, ensuring any pending updates are flushed and a newline is printed. This is crucial for maintaining clean terminal output after the progress bar completes, allowing subsequent messages to appear on a new line. ```go package main import ( "fmt" "time" "fortio.org/progressbar" ) func processItems(items []string) { pb := progressbar.NewBar() for i, item := range items { _ = item // do real work here pb.Progress(float64(i+1) / float64(len(items)) * 100) time.Sleep(50 * time.Millisecond) } pb.End() // cursor moves to next line fmt.Println("done") // prints on a clean line } func main() { processItems([]string{"a", "b", "c", "d", "e"}) } ``` -------------------------------- ### NewAutoReader(bar *Bar, r io.Reader, total int64) *AutoProgressReader Source: https://context7.com/fortio/progressbar/llms.txt Wraps an `io.Reader` to automatically advance a progress bar with each `Read` call. Handles unknown totals by displaying a spinner. ```APIDOC ## NewAutoReader(bar *Bar, r io.Reader, total int64) *AutoProgressReader ### Description Wraps an `io.Reader` so that every `Read` call automatically advances the associated bar. `total` is the expected byte count (use a negative value for an unknown total, which shows a spinner and elapsed/speed only). The returned `*AutoProgressReader` implements both `io.Reader` and `io.Closer`; calling `Close()` finalises the bar and closes the underlying reader. ### Usage Example ```go func downloadFile(url string) error { resp, err := http.Get(url) //nolint:gosec if err != nil { return err } // ContentLength is -1 when unknown; NewAutoReader handles that gracefully. bar := progressbar.NewBar() reader := progressbar.NewAutoReader(bar, resp.Body, resp.ContentLength) defer reader.Close() // also calls bar.End() _, err = io.Copy(os.Stdout, reader) if err != nil { return fmt.Errorf("copy: %w", err) } return nil } func main() { if err := downloadFile("https://go.dev/"); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } // Terminal (stderr) shows while downloading: // ⣾ ██████████████████▌ 46.2% 1.234 Mb out of 2.671 Mb, 120ms elapsed, 10.283 Mb/s, 140ms remaining } ``` ``` -------------------------------- ### NewMultiBar Source: https://context7.com/fortio/progressbar/llms.txt Assembles a MultiBar from already constructed Bar instances, allowing for individual bar configuration before grouping. ```APIDOC ## (Config).NewMultiBar(mbars ...*Bar) *MultiBar ### Description Assembles a `*MultiBar` from already-constructed `*Bar` instances (e.g., `AutoProgressReader`/`AutoProgressWriter` bars). Use this when bars need individual configuration before being grouped. ### Parameters * `mbars` (...*Bar) - A variable number of `Bar` instances to group into a `MultiBar`. ### Returns * `*MultiBar` - A new `MultiBar` instance containing the provided bars. ``` -------------------------------- ### Format Byte Counts into Human-Readable Strings Source: https://context7.com/fortio/progressbar/llms.txt The `HumanBytes` utility function converts byte counts into human-readable strings with appropriate units (b, Kb, Mb, Gb). It accepts both `int64` and `float64` and can be used for transfer rates by appending '/s'. ```go package main import ( "fmt" "fortio.org/progressbar" ) func main() { fmt.Println(progressbar.HumanBytes(512)) // "512 b" fmt.Println(progressbar.HumanBytes(1536)) // "1.5 Kb" fmt.Println(progressbar.HumanBytes(int64(5_242_880))) // "5.000 Mb" fmt.Println(progressbar.HumanBytes(float64(1.5e9))) // "1.397 Gb" speed := float64(10_485_760) // 10 MiB/s fmt.Println(progressbar.HumanBytes(speed) + "/s") // "10.000 Mb/s" } ``` -------------------------------- ### HumanBytes[T int64 | float64](inp T) string Source: https://context7.com/fortio/progressbar/llms.txt Generic utility that formats a byte count as a human-readable string with auto-selected unit (b, Kb, Mb, Gb). It is also suitable for transfer-rate strings by appending `/s` to the result. ```APIDOC ## HumanBytes[T int64 | float64](inp T) string ### Description Generic utility that formats a byte count as a human-readable string with auto-selected unit (`b`, `Kb`, `Mb`, `Gb`). Also suitable for transfer-rate strings by appending `/s` to the result. ### Usage Example ```go package main import ( "fmt" "fortio.org/progressbar" ) func main() { fmt.Println(progressbar.HumanBytes(512)) // "512 b" fmt.Println(progressbar.HumanBytes(1536)) // "1.5 Kb" fmt.Println(progressbar.HumanBytes(int64(5_242_880))) // "5.000 Mb" fmt.Println(progressbar.HumanBytes(float64(1.5e9))) // "1.397 Gb" speed := float64(10_485_760) // 10 MiB/s fmt.Println(progressbar.HumanBytes(speed) + "/s") // "10.000 Mb/s" } ``` ``` -------------------------------- ### NewAutoProgress Source: https://context7.com/fortio/progressbar/llms.txt A lower-level building block for custom I/O wrappers. Allows updating the progress bar from any goroutine by calling the `Update` method. ```APIDOC ## NewAutoProgress(bar *Bar, total int64) *AutoProgress ### Description Lower-level building block for custom I/O wrappers. Call `(*AutoProgress).Update(n int)` from any goroutine to increment the byte counter by `n` and redraw the bar. `AutoProgressReader` and `AutoProgressWriter` are built on top of this type. ### Parameters * `bar` (*Bar) - The progress bar instance to update. * `total` (int64) - The total amount of progress to be made. ### Returns * `*AutoProgress` - A new `AutoProgress` instance. ``` -------------------------------- ### Automatic Reader Progress Bar Source: https://github.com/fortio/progressbar/blob/main/README.md Wraps an io.Reader to automatically display progress based on content length. Ideal for downloads or file processing where progress tracking is desired without manual updates. ```go reader := progressbar.NewAutoReader(progressbar.NewBar(), resp.Body, resp.ContentLength) _, err = io.Copy(os.Stdout, reader) reader.Close() ``` -------------------------------- ### (*MultiBar).PrefixesAlign() Source: https://context7.com/fortio/progressbar/llms.txt Left-aligns all bar prefixes to the length of the longest one (plus one space), then redraws every bar. This is called automatically by NewMultiBarPrefixes, but can be called manually after Add() if a new prefix is longer than existing ones. ```APIDOC ## (*MultiBar).PrefixesAlign() ### Description Left-aligns all bar prefixes to the length of the longest one (plus one space), then redraws every bar. Called automatically by `NewMultiBarPrefixes`; call it manually after `Add()` if the new prefix is longer than existing ones. ### Usage Example ```go package main import ( "os" "time" "fortio.org/progressbar" ) func main() { cfg := progressbar.DefaultConfig() cfg.ScreenWriter = os.Stdout mbar := cfg.NewMultiBarPrefixes("short", "medium len", "x") // Dynamically rename a prefix mid-run. time.Sleep(500 * time.Millisecond) mbar.Bars[2].UpdatePrefix("very long new prefix") mbar.PrefixesAlign() // re-align all bars for _, b := range mbar.Bars { b.Progress(100) } mbar.End() } ``` ``` -------------------------------- ### Concurrent Logging with Progress Bar Writer Source: https://context7.com/fortio/progressbar/llms.txt Use the `Writer()` to safely log messages from goroutines while a progress bar is active. Writes clear the current line, print the message, and allow the bar to redraw. ```Go package main import ( "fmt" "os" "time" "fortio.org/progressbar" ) func main() { cfg := progressbar.DefaultConfig() cfg.ScreenWriter = os.Stdout pb := cfg.NewBar() w := pb.Writer() fmt.Fprintln(w, "Starting long job…") // Safe concurrent logging while the bar advances: go func() { for i := 0; i < 5; i++ { time.Sleep(200 * time.Millisecond) fmt.Fprintf(w, "log entry #%d\n", i+1) } }() n := pb.Width * 8 // iterate over every fractional pixel for i := 0; i <= n; i++ { pb.Progress(100.0 * float64(i) / float64(n)) time.Sleep(5 * time.Millisecond) } pb.End() } ``` -------------------------------- ### (*Bar).WriteAbove(msg string) Source: https://context7.com/fortio/progressbar/llms.txt In a multi-bar layout, writes a single-line message in the ExtraLines space immediately above the bar. This is used for per-bar status lines (e.g., speed, filename) without disturbing other bars. ```APIDOC ## (*Bar).WriteAbove(msg string) ### Description In a multi-bar layout, writes a single-line message in the `ExtraLines` space immediately above the bar. Used for per-bar status lines (e.g., speed, filename) without disturbing other bars. ### Usage Example ```go package main import ( "fmt" "os" "sync" "time" "fortio.org/progressbar" ) func main() { cfg := progressbar.DefaultConfig() cfg.ExtraLines = 1 cfg.ScreenWriter = os.Stdout mbar := cfg.NewMultiBarPrefixes("task-1", "task-2") wg := sync.WaitGroup{} for i, bar := range mbar.Bars { wg.Add(1) go func(b *progressbar.Bar, idx int) { defer wg.Done() for j := 0; j <= 100; j++ { b.Progress(float64(j)) b.WriteAbove(fmt.Sprintf("task-%d: processing item %d/100", idx+1, j)) time.Sleep(20 * time.Millisecond) } }(bar, i) } wg.Wait() mbar.End() _ = os.Stdout } ``` ``` -------------------------------- ### Force Immediate Redraw of a Progress Bar Source: https://context7.com/fortio/progressbar/llms.txt Call `Redraw()` to force an immediate visual update of the bar, bypassing rate limiting. This is useful after changing a bar's prefix or suffix using `UpdatePrefix` or `UpdateSuffix` when you need the change to be visible instantly. ```go package main import ( "time" "fortio.org/progressbar" ) func main() { pb := progressbar.NewBar() pb.Progress(42.0) time.Sleep(10 * time.Millisecond) pb.UpdatePrefix("Uploading ") pb.Redraw() // immediately show new prefix at 42 % time.Sleep(500 * time.Millisecond) pb.Progress(100) pb.End() } ``` -------------------------------- ### (*Bar).End() Source: https://context7.com/fortio/progressbar/llms.txt Finalizes the progress bar, ensuring any pending updates are flushed and a newline is printed for subsequent output. ```APIDOC ## (*Bar).End() ### Description Finalises the progress bar by flushing any pending (rate-limited) update and printing a newline so the next terminal output starts on a fresh line. Always call `End()` when a manually-driven bar is complete. ### Usage ```go func processItems(items []string) { pb := progressbar.NewBar() for i, item := range items { _ = item // do real work here pb.Progress(float64(i+1) / float64(len(items)) * 100) time.Sleep(50 * time.Millisecond) } pb.End() // cursor moves to next line fmt.Println("done") // prints on a clean line } func main() { processItems([]string{"a", "b", "c", "d", "e"}) } ``` ``` -------------------------------- ### Move Cursor Up to Overwrite Text Above Progress Bar Source: https://context7.com/fortio/progressbar/llms.txt Employ `MoveCursorUp(n)` to reposition the cursor and clear lines above the progress bar, enabling direct overwriting of previous output without using the `Writer()`. ```Go package main import ( "fmt" "time" "fortio.org/progressbar" ) func main() { pb := progressbar.NewBar() fmt.Print("Status: initialising\n\n") // blank line above the bar n := 100 for i := 0; i <= n; i++ { pb.Progress(float64(i)) if i%25 == 0 { // Overwrite the "Status:" line two rows above. pb.MoveCursorUp(2) fmt.Printf("Status: step %d of %d\n", i, n) } time.Sleep(30 * time.Millisecond) } pb.End() } ``` -------------------------------- ### Writer() io.Writer Source: https://context7.com/fortio/progressbar/llms.txt Returns a concurrency-safe io.Writer associated with the progress bar. Writes to this writer clear the current line, print content, and then allow the bar to redraw. ```APIDOC ## (*Bar).Writer() io.Writer ### Description Returns a concurrency-safe `io.Writer` associated with the bar. Any write to this writer clears the current progress-bar line first, prints the supplied content, and then lets the next `Progress()` call redraw the bar on a fresh line. Use this writer for all `fmt.Fprint*` / `log` output while a bar is active. ### Usage Example ```go cfg := progressbar.DefaultConfig() cfg.ScreenWriter = os.Stdout pb := cfg.NewBar() w := pb.Writer() fmt.Fprintln(w, "Starting long job…") // Safe concurrent logging while the bar advances: go func() { for i := 0; i < 5; i++ { time.Sleep(200 * time.Millisecond) fmt.Fprintf(w, "log entry #%d\n", i+1) } }() n := pb.Width * 8 // iterate over every fractional pixel for i := 0; i <= n; i++ { pb.Progress(100.0 * float64(i) / float64(n)) time.Sleep(5 * time.Millisecond) } pc.End() ``` ``` -------------------------------- ### (*Bar).Progress(progressPercent float64) Source: https://context7.com/fortio/progressbar/llms.txt Updates the progress bar to the specified percentage. This method is concurrency-safe and rate-limited to prevent excessive terminal updates. ```APIDOC ## (*Bar).Progress(progressPercent float64) ### Description Updates the progress bar to the given percentage (0–100). Repeated calls overwrite the same terminal line. The method is concurrency-safe; it acquires the shared writer lock internally. Calls are silently rate-limited to `Config.UpdateInterval` (default 100 ms) unless the value reaches 100 %. ### Parameters #### Path Parameters - **progressPercent** (float64) - Required - The current progress as a percentage (0.0 to 100.0). ### Usage ```go cfg := progressbar.DefaultConfig() cfg.ScreenWriter = os.Stdout // write to stdout instead of stderr cfg.Spinner = true pb := cfg.NewBar() total := 1000 for i := 0; i <= total; i++ { pb.Progress(float64(i) / float64(total) * 100) time.Sleep(2 * time.Millisecond) } pb.End() ``` ``` -------------------------------- ### Write Status Messages Above Individual Bars Source: https://context7.com/fortio/progressbar/llms.txt Use `WriteAbove()` within a multi-bar layout to display single-line status messages immediately above a specific bar. This is useful for showing per-task details without affecting other bars. Ensure `cfg.ExtraLines` is set to accommodate these messages. ```go package main import ( "fmt" "os" "sync" "time" "fortio.org/progressbar" ) func main() { cfg := progressbar.DefaultConfig() cfg.ExtraLines = 1 cfg.ScreenWriter = os.Stdout mbar := cfg.NewMultiBarPrefixes("task-1", "task-2") wg := sync.WaitGroup{} for i, bar := range mbar.Bars { wg.Add(1) go func(b *progressbar.Bar, idx int) { defer wg.Done() for j := 0; j <= 100; j++ { b.Progress(float64(j)) b.WriteAbove(fmt.Sprintf("task-%d: processing item %d/100", idx+1, j)) time.Sleep(20 * time.Millisecond) } }(bar, i) } wg.Wait() mbar.End() _ = os.Stdout } ``` -------------------------------- ### (*Bar).Redraw() Source: https://context7.com/fortio/progressbar/llms.txt Forces a redraw of the bar at its last known percentage, bypassing rate limiting. This is useful after an UpdatePrefix or UpdateSuffix call when an immediate visual refresh is required. ```APIDOC ## (*Bar).Redraw() ### Description Forces a redraw of the bar at its last known percentage, bypassing rate limiting. Useful after an `UpdatePrefix` or `UpdateSuffix` call when an immediate visual refresh is required. ### Usage Example ```go package main import ( "time" "fortio.org/progressbar" ) func main() { pb := progressbar.NewBar() pb.Progress(42.0) time.Sleep(10 * time.Millisecond) pb.UpdatePrefix("Uploading ") pb.Redraw() // immediately show new prefix at 42 % time.Sleep(500 * time.Millisecond) pb.Progress(100) pb.End() } ``` ``` -------------------------------- ### Format Time Durations into Human-Readable Strings Source: https://context7.com/fortio/progressbar/llms.txt The `HumanDuration` function formats `time.Duration` values into human-readable strings with adaptive precision (milliseconds, 100ms, or minutes). This is useful for displaying elapsed or remaining time in a user-friendly format. ```go package main import ( "fmt" "time" "fortio.org/progressbar" ) func main() { fmt.Println(progressbar.HumanDuration(750 * time.Millisecond)) // "750ms" fmt.Println(progressbar.HumanDuration(3*time.Second + 400*time.Millisecond)) // "3.4s" fmt.Println(progressbar.HumanDuration(2*time.Minute + 15*time.Second)) // "2m15s" (100ms precision) fmt.Println(progressbar.HumanDuration(1*time.Hour + 23*time.Minute)) // "1h23m0s" (minute precision) } ``` -------------------------------- ### MoveCursorUp(n int) Source: https://context7.com/fortio/progressbar/llms.txt Moves the terminal cursor up `n` lines and clears the target line, allowing for content overwrites above the progress bar without using the `Writer()`. ```APIDOC ## (*Bar).MoveCursorUp(n int) ### Description Moves the terminal cursor up `n` lines and clears the target line, allowing the caller to overwrite content above the current progress bar line without using `Writer()`. When `NoAnsi` is set, emits a plain newline instead. ### Usage Example ```go pb := progressbar.NewBar() fmt.Print("Status: initialising\n\n") // blank line above the bar n := 100 for i := 0; i <= n; i++ { pb.Progress(float64(i)) if i%25 == 0 { // Overwrite the "Status:" line two rows above. pb.MoveCursorUp(2) fmt.Printf("Status: step %d of %d\n", i, n) } time.Sleep(30 * time.Millisecond) } pb.End() ``` ``` -------------------------------- ### HumanDuration(d time.Duration) string Source: https://context7.com/fortio/progressbar/llms.txt Formats a time.Duration with magnitude-appropriate rounding: millisecond precision for <= 1 second, 100 ms precision for < 1 hour, and minute precision for >= 1 hour. This is used internally by AutoProgress.Extra to display elapsed and remaining time. ```APIDOC ## HumanDuration(d time.Duration) string ### Description Formats a `time.Duration` with magnitude-appropriate rounding: millisecond precision for ≤1 s, 100 ms precision for <1 h, and minute precision for ≥1 h. Used internally by `AutoProgress.Extra` to display elapsed and remaining time. ### Usage Example ```go package main import ( "fmt" "time" "fortio.org/progressbar" ) func main() { fmt.Println(progressbar.HumanDuration(750 * time.Millisecond)) // "750ms" fmt.Println(progressbar.HumanDuration(3*time.Second + 400*time.Millisecond)) // "3.4s" fmt.Println(progressbar.HumanDuration(2*time.Minute + 15*time.Second)) // "2m15s" (100ms precision) fmt.Println(progressbar.HumanDuration(1*time.Hour + 23*time.Minute)) // "1h23m0s" (minute precision) } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.