Awesome
Whirly 😀 <img src="https://github.com/janlelis/whirly/workflows/Test/badge.svg" />
A simple, colorful and customizable terminal spinner library for Ruby. It comes with 24 custom spinners and also includes those from the cli-spinners project.
Demonstration
Bundled Whirly Spinners
Bundled Spinners from CLI Spinners
Setup
Add to your Gemfile
:
gem 'whirly'
gem 'paint' # makes whirly colorful (recommended)
Usage
Basic Usage
The spinner is shown while the block executes:
Whirly.start do
# do the heavy work here
sleep 5
end
You can update the spinner text from inside the block:
Whirly.start do
Whirly.status = "Set some text to display alongside the spinner symbol"
sleep 3
Whirly.status = "Update it"
sleep 2
end
If you want to avoid the block syntax, you can also stop it manually:
Whirly.start
sleep 5
Whirly.stop
The start
method takes a lot of options, like which spinner to use or an initial status. See further below for the full description of available options.
Whirly.start spinner: "pong", color: false, status: "The Game of Pong" do
sleep 10
end
Also see the examples directory for example scripts.
Configuring Whirly
You can pass the same options you would pass to .start
to .configure
instead to create a persistent configuration that will be used by .start
:
Whirly.configure spinner: "dots"
Whirly.start do
sleep 3 # will use dots
end
Whirly.start do
sleep 3 # will use dots again
end
Call .reset
to restore unconfigured behaviour:
Whirly.configure spinner: "dots"
Whirly.reset
Whirly.start do
sleep 3 # will use default spinner
end
Spinners
Included Spinners
See data/whirly-static-spinnes.json
, lib/whirly/spinners/whirly.rb
and cli-spinners. You can get a demonstration of all bundled spinners by running the examples/all_spinners.rb
script.
All Whirly.start
/ Whirly.configure
Configuration Options
Main Options
spinner:
Default: "whirly"
You have multiple ways of telling Whirly which spinner should be used. You can pass the following to the spinner:
option:
- The name of a bundled spinner
- An array of spinner frames to use
- A proc which generates the frames dynamically
- A full spinner hash object (explained below)
status:
Default: None
Allows you to directly set the first status text to display alongside the spinner icon.
interval:
Default: 100
The number of milliseconds between changing to the next spinner icon frame.
Advanced Options
ambiguous_characters_width:
Default: 1
If set to 2
, ambiguous Unicode charatcers will be treated as 2 colums wide. See unicode-display_width for more details.
ansi_escape_mode:
Default: "restore"
Can be set to "line"
to use an different way of producing ANSI escape sequences necessary (experimental).
append_newline:
Default: true
When the Whirly block is over (or .stop
was called), a "\n"
will be outputted. Change to false
to prevent this.
color:
Default: !!defined?(Paint)
This option is responsible for displaying the spinner icon in random colors. Set to false
if you do not want this. Related option :color_change_rate
.
color_change_rate:
Default: 30
A value which describes how fast the color of the spinner icon changes.
hide_cursor:
Default: true
By default, the terminal cursor gets hidden while displaying the spinner. This also registers an at_exit
callback, which always restores the cursor when exitting the program. If you do not want to hide the cursor, change this option to false
.
mode:
Default: "linear"
Instructs Whirly to play the frames in a different order. Possible values: "linear"
, "reverse"
, "swing"
, and "random"
. See spinner format section for more details.
non_tty:
Default: false
Whirly only gets activated if the current process appears to be a real terminal. If you want to activate it for non-terimnals, set this option to true
.
position:
Default: "normal"
You can set this to "below"
to let Whirly appear one line below its normal position.
remove_after_stop:
Default: false
Causes the last frame to be removed after the spinner stopped.
stop:
Default: None
You can pass a custom frame to be used to end the animation, for example:
Whirly.start spinner: "clock", interval: 1000, stop: "⏰" do
sleep 12
end
spinner_packs:
Default: [:whirly, :cli]
Whirly comes with spinners from different sources. This options defines which sources to consider (the value refers to an uppercased child constant of Whirly::Spinners
) and in which order.
stream:
Default: $stdout
You can pass in an IO-like object, if you want to display Whirly on an other stream than $stdout
.
Full Spinner Hash Format
A full spinner is defined by a hash which can have the following key-value pairs. Please note that in order to keep the format more portable, all keys are strings and not Ruby symbols. Except for "frames"
and "proc"
, all options are overwritable when starting/configuring Whirly. See the included spinners for example definitions of spinners.
"frames"
An Array or Enumerable of strings that will be used as the spinner icon.
"proc"
Instead of using "frames"
: A proc which will generate the next frame with each call.
"interval"
The number of milliseconds between changing to the next spinner icon frame.
"mode"
The order in which frames should be played. It can be one of the following:
"linear"
: Cycle through all frames in normal order"reverse"
: Cycle through all frames in reverse order"swing"
: Cycle through all frames in normal order, and then in reverse order, but only play first and last frame once each round"random"
: Play random frames
Please note: While "linear"
also works with frames that are just an Enumerable, all other frame modes require the object to be representable as an Array.
"stop"
A frame to be used to end the spinner icon animation.
Remarks, Troubleshooting, Caveats
- Interval is milliseconds, but don't rely on exact timing
- Will not do anything if stream is not a real console (or
non_tty: true
is passed) - Colors not working? Be sure to include the paint gem in your Gemfile
- Don't set very short intervals (or it might affect performance substantially)
MIT License
- Copyright (C) 2016 Jan Lelis https://janlelis.com. Released under the MIT license.
- Contains data from cli-spinners: MIT License, Copyright (c) Sindre Sorhus sindresorhus@gmail.com (sindresorhus.com)