Keyboard shortcuts

Press ← or β†’ to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Group

Group runs multiple animations concurrently in a multi-line block, redrawn each tick.

Group demo

g := clog.NewGroup(ctx)
g.Add(clog.Spinner("Processing data").Int("workers", 4)).
  Run(func(ctx context.Context) error {
    return processData(ctx)
  })
g.Add(clog.Bar("Downloading", 100)).
  Progress(func(ctx context.Context, p *clog.ProgressUpdate) error {
    for i := range 101 {
      p.SetProgress(i).Send()
      time.Sleep(20 * time.Millisecond)
    }
    return nil
  })
g.Wait().Prefix("βœ…").Msg("All tasks complete")

While the tasks run, the terminal shows all animations updating simultaneously:

INF πŸŒ’ Processing data workers=4
INF ⏳ Downloading [━━━━━━━╸╺───────────] 42%

When all tasks finish, the block is cleared and a single summary line is logged. Alternatively, use per-task results for individual completion messages:

g := clog.NewGroup(ctx)
proc := g.Add(clog.Spinner("Processing")).Run(processData)
dl := g.Add(clog.Bar("Downloading", 100)).Progress(download)
g.Wait()
proc.Prefix("βœ…").Msg("Processing done")
dl.Prefix("βœ…").Msg("Download complete")

Any mix of animation types works: spinners, bars, pulses, and shimmers can all run in the same group.

API

Function / MethodDescription
clog.NewGroup(ctx)Create a group using the Default logger
logger.Group(ctx)Create a group using a specific logger
g.Add(builder)Register an animation builder, returns *GroupEntry
entry.Run(task)Start a TaskFunc, returns *TaskResult
entry.Progress(task)Start a ProgressTaskFunc, returns *TaskResult
g.Wait()Block until all tasks complete, returns *GroupResult

GroupResult and TaskResult support the same chaining as WaitResult: .Msg(), .Parts(), .Prefix(), .Send(), .Err(), .Silent(), .OnErrorLevel(), .OnErrorMessage(), .OnSuccessLevel(), .OnSuccessMessage(), and all field methods (.Str(), .Int(), etc.).

Per-Event Parts Override

Override the part order for individual animations and their completion messages:

g := clog.NewGroup(ctx)

// Animation + completion both use overridden parts.
proc := g.Add(clog.Spinner("Processing").Parts(clog.PartMessage)).
  Run(processData)

dl := g.Add(clog.Bar("Downloading", 100)).
  Progress(download)

// Override parts only on the summary line.
g.Wait().Parts(clog.PartPrefix, clog.PartMessage).Msg("All done")

.Parts() on the AnimationBuilder propagates to the TaskResult. Call .Parts() on TaskResult or GroupResult to override independently for the completion message.

GroupResult.Err() / .Silent() returns the errors.Join of all task errors (nil when all succeeded).