You are developing or refactoring a Go project that uses the pin
library for displaying interactive CLI spinners. The following is a comprehensive description of the library, its public API, and usage examples designed for new projects or refactored code.
The pin
library is a lightweight and customizable terminal spinner for Go applications. It provides an elegant progress indicator with support for:
- Custom colors
- Dynamic message updates
- Flexible positioning (spinner before or after the message)
- Custom symbols for success or failure states
- Automatic adjustment in non-interactive environments (animations are disabled when output is piped)
To install the library, run:
go get github.com/yarlson/pin
-
Creating a New Spinner:
- Constructor:
Description: Initializes a new spinner with a base message and an optional list of functional options for customization.
func New(message string, opts ...Option) *Pin
- Constructor:
-
Controlling the Spinner:
-
Start:
func (p *Pin) Start(ctx context.Context) context.CancelFunc
Description: Begins the spinner animation using the provided context. Returns a cancellation function that can be called to stop the spinner.
-
Stop:
func (p *Pin) Stop(message ...string)
Description: Stops the spinner and outputs an optional final message indicating success or normal termination.
-
Fail:
func (p *Pin) Fail(message ...string)
Description: Stops the spinner and displays a failure message with a failure-specific symbol and color.
-
UpdateMessage:
func (p *Pin) UpdateMessage(message string)
Description: Dynamically updates the spinner's displayed message while it is still active.
-
-
Functional Options for Customization: These functions return an
Option
that customizes various aspects of the spinner.-
Description: Sets the color of the spinner's animation.
func WithSpinnerColor(color Color) Option
-
Description: Sets the color of the message text.
func WithTextColor(color Color) Option
-
Description: Sets the symbol displayed when the spinner stops successfully.
func WithDoneSymbol(symbol rune) Option
-
Description: Sets the color of the done symbol.
func WithDoneSymbolColor(color Color) Option
-
Description: Adds a prefix before the spinner and message.
func WithPrefix(prefix string) Option
-
Description: Sets the color of the prefix text.
func WithPrefixColor(color Color) Option
-
Description: Defines the separator between the prefix and the main message text.
func WithSeparator(separator string) Option
-
Description: Sets the color for the separator.
func WithSeparatorColor(color Color) Option
-
Description: Determines the spinner's placement relative to the message text. Use
func WithPosition(pos Position) Option
PositionLeft
(default) orPositionRight
. -
Description: Sets the spinner's frames for custom animations.
func WithSpinnerFrames(frames []rune) Option
-
Description: Sets the symbol shown when the spinner indicates a failure.
func WithFailSymbol(symbol rune) Option
-
Description: Sets the color for the failure symbol.
func WithFailSymbolColor(color Color) Option
-
Description: Sets the color of the failure message text.
func WithFailColor(color Color) Option
-
Description: Redirects spinner output to a custom writer such as
func WithWriter(w io.Writer) Option
os.Stderr
.
-
-
Public Constants:
Colors:
const ( ColorDefault Color = iota ColorBlack ColorRed ColorGreen ColorYellow ColorBlue ColorMagenta ColorCyan ColorGray ColorWhite )
Description: These constants represent ANSI colors for styling elements of the spinner (text, symbols, animation).
Positions:
const ( PositionLeft Position = iota // Spinner appears before the message (default) PositionRight // Spinner appears after the message )
Description: These constants allow you to specify the spinner's placement relative to the message text.
-
Basic Spinner Usage:
package main import ( "context" "time" "github.com/yarlson/pin" ) func main() { // Create a spinner with default settings. p := pin.New("Loading...", pin.WithSpinnerColor(pin.ColorCyan), pin.WithTextColor(pin.ColorYellow), ) // Start the spinner. cancel := p.Start(context.Background()) defer cancel() // Simulate work. time.Sleep(3 * time.Second) // Stop the spinner with a final message. p.Stop("Done!") }
-
Advanced Customization with Dynamic Updates:
package main import ( "context" "time" "github.com/yarlson/pin" ) func main() { // Initialize spinner with custom options. p := pin.New("Processing", pin.WithSpinnerColor(pin.ColorBlue), pin.WithTextColor(pin.ColorCyan), pin.WithPrefix("Task"), pin.WithPrefixColor(pin.ColorYellow), pin.WithSeparator("->"), pin.WithPosition(pin.PositionRight), pin.WithDoneSymbol('✔'), pin.WithDoneSymbolColor(pin.ColorGreen), ) // Start the spinner. ctx, cancel := context.WithCancel(context.Background()) defer cancel() p.Start(ctx) // Update the spinner message while processing. time.Sleep(2 * time.Second) p.UpdateMessage("Still processing...") time.Sleep(2 * time.Second) // Stop the spinner with a success message. p.Stop("Success!") }
-
Handling Failure States:
package main import ( "context" "time" "github.com/yarlson/pin" ) func main() { // Configure spinner with failure indicators. p := pin.New("Deploying", pin.WithFailSymbol('✖'), pin.WithFailSymbolColor(pin.ColorRed), pin.WithFailColor(pin.ColorYellow), ) // Start the spinner. ctx, cancel := context.WithCancel(context.Background()) defer cancel() p.Start(ctx) // Simulate a failure scenario. time.Sleep(2 * time.Second) p.Fail("Deployment failed") }
-
Specifying a Custom Output Destination:
package main import ( "context" "os" "time" "github.com/yarlson/pin" ) func main() { // Direct spinner output to os.Stderr. p := pin.New("Saving Data", pin.WithSpinnerColor(pin.ColorMagenta), pin.WithWriter(os.Stderr), ) // Start the spinner. ctx, cancel := context.WithCancel(context.Background()) defer cancel() p.Start(ctx) // Simulate work. time.Sleep(3 * time.Second) p.Stop("Saved!") }
Usage Context:
This description is intended for integrating or refactoring the pin spinner in your Go project. It details every aspect of the API (public functions and constants) and provides real-world usage examples to simplify the implementation. Use this comprehensive guide to ensure a consistent and interactive CLI experience in your application.