TTY::Spinner

repository·master·Indexed 19 days ago

https://github.com/piotrmurach/tty-spinner

A terminal spinner component for the TTY toolkit used to provide visual feedback for tasks with non-deterministic durations. It supports various animation formats, dynamic label updates via tokens, and a Multi-spinner (TTY::Spinner::Multi) for managing and synchronizing multiple concurrent tasks in a hierarchical tree structure.

Tokens
6.6K
Snippets
27
Records
30
Agent score
63%

What's inside tty-spinner

  1. How TTY::Spinner::Multi works with auto_spin

    master

    To create a top-level spinner that tracks the activity of all registered sub-spinners, initialize TTY::Spinner::Multi with a message. The top-level spinner will automatically animate whenever at least one registered sub-spinner starts spinning.

    There are two ways to manage the lifecycle of sub-spinners:

    1. Manual Async: Register spinners without tasks, start them manually with #auto_spin, and control their completion (success/error) manually. If a sub-spinner is marked with #error, the top-level multi-spinner will also be marked as a failure.
    2. Auto Async Tasks: Register spinners with a block containing the task logic. The task receives the spinner instance as an argument. When #auto_spin is called on the multi-spinner, it kicks off all tasks. The spinners will automatically animate and finish based on the outcome of the blocks.
    # Example of Auto Async Tasks
    multi_spinner = TTY::Spinner::Multi.new("[:spinner] top")
    
    multi_spinner.register("[:spinner] one") { |sp| sleep(2); sp.success("yes 2") }
    multi_spinner.register("[:spinner] two") { |sp| sleep(3); sp.error("no 2") }
    
    multi_spinner.auto_spin
  2. Configure the visual style of TTY::Spinner::Multi

    master

    You can customize the visual structure of a multi-spinner using the style option during initialization. This allows you to define the characters used for the top-level, middle, and bottom connections in the tree view.

    multi_spinner = TTY::Spinner::Multi.new("[:spinner] parent", style: {
      top: ". "
      middle: "|-> "
      bottom: "|__ "
    })
  3. Configure TTY::Spinner options

    master

    You can customize the spinner's behavior using several configuration options during initialization:

    • :format: Predefined spinner style (e.g., :pulse_2).
    • :frames: Custom array or string of characters for the animation frames.
    • :interval: Integer representing frequency in Hz (e.g., 20 for 20 updates per second).
    • :hide_cursor: Boolean to hide the terminal cursor during animation (defaults to false).
    • :clear: Boolean to clear the spinner output after it finishes (defaults to false).
    • :success_mark: Character used for successful completion (e.g., "+").
    • :error_mark: Character used for error completion (e.g., "x").
    • :output: The IO stream to write to (defaults to $stderr).
    # Example of multiple configuration options
    spinner = TTY::Spinner.new(
      format: :pulse_2,
      interval: 20,
      hide_cursor: true,
      success_mark: "+"
    )
  4. Initialize a TTY::Spinner::Multi multispinner

    master

    Use TTY::Spinner::Multi.new to manage multiple concurrent spinners. You can optionally provide a top-level message and a configuration hash.

    Configuration Options

    • style: A Hash containing :top, :middle, and :bottom keys. These keys can contain Strings used to indent the spinners. These are ignored if the message is blank.
    • output: The object that responds to print (defaults to stderr).
    • hide_cursor: Boolean to display or hide the cursor.
    • clear: Boolean to clear output when finished.
    • interval: A Float representing the interval for auto spinning.
    spinner = TTY::Spinner::Multi.new
  5. Synchronize multiple spinners with TTY::Spinner::Multi

    master

    Use TTY::Spinner::Multi to manage and synchronize multiple spinners simultaneously. You can register individual spinners to a multi-spinner instance. When the spinners complete, they will be displayed in a hierarchical tree structure.

    spinners = TTY::Spinner::Multi.new("[:spinner] top")
    
    sp1 = spinners.register "[:spinner] one"
    sp2 = spinners.register "[:spinner] two"
    
    sp1.auto_spin
    sp2.auto_spin
    
    sleep(2) # Perform work
    
    sp1.success
    sp2.success
  6. Basic usage of TTY::Spinner

    master

    By default, TTY::Spinner uses the :classic format and requires no parameters. You can also provide a message containing the :spinner token and specify a custom format.

    To use it, initialize the spinner, start the animation with auto_spin, perform your task, and then stop the animation with stop.

    spinner = TTY::Spinner.new("[:spinner] Loading ...", format: :pulse_2)
    
    spinner.auto_spin # Automatic animation with default interval
    
    sleep(2) # Perform task
    
    spinner.stop("Done!") # Stop animation
  7. Handle task completion with `success` and `error`

    master

    Instead of a generic stop, you can use success or error to indicate the outcome of a task. These methods stop the animation and replace the spinner symbol with a check mark (for success) or a cross (for error).

    # Indicate success
    spinner = TTY::Spinner.new("[:spinner] Task name")
    spinner.success("(successful)")
    # Output: [✔] Task name (successful)
    
    # Indicate error
    spinner = TTY::Spinner.new("[:spinner] Task name")
    spinner.error("(error)")
    # Output: [✖] Task name (error)
  8. Manage TTY::Spinner::Multi lifecycle with stop, success, and error

    master

    Use these methods to control the state and termination of a TTY::Spinner::Multi instance and its sub-spinners:

    • #stop: Stops the top-level spinner and any sub-spinners that are still spinning.
    • #success: Stops the animation and replaces the symbol with a check mark. This also triggers #success on all currently spinning sub-spinners.
    • #error: Stops the animation and replaces the symbol with a cross character. This also triggers #error on all currently spinning sub-spinners.
    multi_spinner.stop
    multi_spinner.success
    multi_spinner.error
  9. Dynamically update spinner labels with `update`

    master

    You can change the spinner's message dynamically by using tokens in the initial message string and then updating them using the update method.

    spinner = TTY::Spinner.new("[:spinner] :title")
    spinner.update(title: "Downloading file1")
    
    spinner.run { ... }
    # => | Downloading file1
    
    spinner.update(title: "Downloading file2")
    spinner.run { ... }
  10. Register spinners with TTY::Spinner::Multi

    master

    You can add individual spinners to a TTY::Spinner::Multi instance using the #register method. You can register a spinner by providing a message and options, or by passing an existing TTY::Spinner instance.

    If no options are provided, the new spinner inherits the options used to initialize the multi_spinner. If options are provided, they will override the multi-spinner's default options.

    # Register using a message and options
    new_spinner = multi_spinner.register("[:spinner] Task 1 name", options)
    
    # Or register an existing TTY::Spinner instance
    spinner = ::TTY::Spinner.new("[:spinner] one")
    sp1 = multi_spinner.register(spinner)
  11. Animate a task using the `run` method

    master

    The run method is a high-level way to execute a task. It accepts a block that yields the spinner instance. The animation starts automatically when the block begins and terminates when the block finishes. You can optionally pass a message to be displayed upon completion.

    # Basic run
    spinner.run do |spinner|
      # perform task
    end
    
    # Run with a completion message
    spinner.run("Done!") do |spinner|
      # perform task
    end