{"id":13483347,"url":"https://github.com/janlelis/whirly","last_synced_at":"2025-10-10T22:57:26.731Z","repository":{"id":52285885,"uuid":"69032701","full_name":"janlelis/whirly","owner":"janlelis","description":"Colorful Terminal Spinner for Ruby 😀︎","archived":false,"fork":false,"pushed_at":"2021-06-04T21:07:23.000Z","size":143,"stargazers_count":324,"open_issues_count":4,"forks_count":13,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-03-01T02:39:22.763Z","etag":null,"topics":["cli-spinners","hacktoberfest","ruby","spinner","spinner-frames","spinner-icon","terminal","unicode-symbols"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/janlelis.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"MIT-LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-09-23T14:31:38.000Z","updated_at":"2024-06-19T21:17:52.000Z","dependencies_parsed_at":"2022-08-21T02:20:30.233Z","dependency_job_id":null,"html_url":"https://github.com/janlelis/whirly","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janlelis%2Fwhirly","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janlelis%2Fwhirly/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janlelis%2Fwhirly/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janlelis%2Fwhirly/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/janlelis","download_url":"https://codeload.github.com/janlelis/whirly/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245863065,"owners_count":20684782,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli-spinners","hacktoberfest","ruby","spinner","spinner-frames","spinner-icon","terminal","unicode-symbols"],"created_at":"2024-07-31T17:01:10.310Z","updated_at":"2025-10-10T22:57:21.707Z","avatar_url":"https://github.com/janlelis.png","language":"Ruby","funding_links":[],"categories":["CLI Utilities","Ruby"],"sub_categories":[],"readme":"# Whirly 😀 [![[version]](https://badge.fury.io/rb/whirly.svg)](https://badge.fury.io/rb/whirly)  [\u003cimg src=\"https://github.com/janlelis/whirly/workflows/Test/badge.svg\" /\u003e](https://github.com/janlelis/whirly/actions/workflows/test.yml)\n\nA simple, colorful and customizable terminal spinner library for Ruby. It comes with 24 custom spinners and also includes those from the [cli-spinners](https://github.com/sindresorhus/cli-spinners) project.\n\n## Demonstration\n\n![](whirly.gif)\n\n### Bundled Whirly Spinners\n\n[Play on asciinema](https://asciinema.org/a/88198?size=big)\n\n### Bundled Spinners from CLI Spinners\n\n![](https://raw.githubusercontent.com/sindresorhus/cli-spinners/main/screenshot.gif)\n\n[Play on asciinema](https://asciinema.org/a/9mlcoussb137m32swwuqtb2p1?size=big)\n\n## Setup\n\nAdd to your `Gemfile`:\n\n```ruby\ngem 'whirly'\ngem 'paint' # makes whirly colorful (recommended)\n```\n\n## Usage\n\n### Basic Usage\n\nThe spinner is shown while the block executes:\n\n```ruby\nWhirly.start do\n  # do the heavy work here\n  sleep 5\nend\n```\n\nYou can update the spinner text from inside the block:\n\n```ruby\nWhirly.start do\n  Whirly.status = \"Set some text to display alongside the spinner symbol\"\n  sleep 3\n  Whirly.status = \"Update it\"\n  sleep 2\nend\n```\n\nIf you want to avoid the block syntax, you can also stop it manually:\n\n```ruby\nWhirly.start\nsleep 5\nWhirly.stop\n```\n\nThe `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.\n\n```ruby\nWhirly.start spinner: \"pong\", color: false, status: \"The Game of Pong\" do\n  sleep 10\nend\n```\n\nAlso see the [examples directory](https://github.com/janlelis/whirly/tree/main/examples) for example scripts.\n\n### Configuring Whirly\n\nYou can pass the same options you would pass to `.start` to `.configure` instead to create a persistent configuration that will be used by `.start`:\n\n```ruby\nWhirly.configure spinner: \"dots\"\n\nWhirly.start do\n  sleep 3 # will use dots\nend\n\nWhirly.start do\n  sleep 3 # will use dots again\nend\n```\n\nCall `.reset` to restore unconfigured behaviour:\n\n```ruby\nWhirly.configure spinner: \"dots\"\n\nWhirly.reset\n\nWhirly.start do\n  sleep 3 # will use default spinner\nend\n```\n\n## Spinners\n\n### Included Spinners\n\nSee [`data/whirly-static-spinnes.json`](https://github.com/janlelis/whirly/blob/main/data/whirly-static-spinners.json), [`lib/whirly/spinners/whirly.rb`](https://github.com/janlelis/whirly/blob/main/lib/whirly/spinners/whirly.rb) and [cli-spinners](https://github.com/sindresorhus/cli-spinners). You can get a demonstration of all bundled spinners by running the [`examples/all_spinners.rb`](https://github.com/janlelis/whirly/blob/main/examples/all_spinners.rb) script.\n\n## All `Whirly.start` / `Whirly.configure` Configuration Options\n\n### Main Options\n\n#### `spinner:`\n\n*Default:* `\"whirly\"`\n\nYou have multiple ways of telling *Whirly* which spinner should be used. You can pass the following to the `spinner:` option:\n\n- The name of a bundled spinner\n- An array of spinner frames to use\n- A proc which generates the frames dynamically\n- A full spinner hash object ([explained below](https://github.com/janlelis/whirly#full-spinner-hash-format))\n\n#### `status:`\n\n*Default:* None\n\nAllows you to directly set the first status text to display alongside the spinner icon.\n\n#### `interval:`\n\n*Default:* `100`\n\nThe number of milliseconds between changing to the next spinner icon frame.\n\n### Advanced Options\n\n#### `ambiguous_characters_width:`\n\n*Default:* `1`\n\nIf set to `2`, ambiguous Unicode charatcers will be treated as 2 colums wide. See [unicode-display_width](https://github.com/janlelis/unicode-display_width) for more details.\n\n#### `ansi_escape_mode:`\n\n*Default:* `\"restore\"`\n\nCan be set to `\"line\"` to use an different way of producing ANSI escape sequences necessary (experimental).\n\n#### `append_newline:`\n\n*Default:* `true`\n\nWhen the Whirly block is over (or `.stop` was called), a `\"\\n\"` will be outputted. Change to `false` to prevent this.\n\n#### `color:`\n\n*Default:* `!!defined?(Paint)`\n\nThis 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`.\n\n#### `color_change_rate:`\n\n*Default:* `30`\n\nA value which describes how fast the color of the spinner icon changes.\n\n#### `hide_cursor:`\n\n*Default:* `true`\n\nBy 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`.\n\n#### `mode:`\n\n*Default:* `\"linear\"`\n\nInstructs Whirly to play the frames in a different order. Possible values: `\"linear\"`, `\"reverse\"`, `\"swing\"`, and `\"random\"`. See [spinner format section](https://github.com/janlelis/whirly#mode-1) for more details.\n\n#### `non_tty:`\n\n*Default:* `false`\n\nWhirly 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`.\n\n#### `position:`\n\n*Default:* `\"normal\"`\n\nYou can set this to `\"below\"` to let Whirly appear one line below its normal position.\n\n#### `remove_after_stop:`\n\n*Default:* `false`\n\nCauses the last frame to be removed after the spinner stopped.\n\n#### `stop:`\n\n*Default:* None\n\nYou can pass a custom frame to be used to end the animation, for example:\n\n```ruby\nWhirly.start spinner: \"clock\", interval: 1000, stop: \"⏰\" do\n  sleep 12\nend\n```\n\n#### `spinner_packs:`\n\n*Default:* `[:whirly, :cli]`\n\nWhirly 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.\n\n#### `stream:`\n\n*Default:* `$stdout`\n\nYou can pass in an [IO](https://ruby-doc.org/core/IO.html)-like object, if you want to display *Whirly* on an other stream than `$stdout`.\n\n## Full Spinner Hash Format\n\nA 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.\n\n### `\"frames\"`\n\nAn [Array](https://ruby-doc.org/core/Array.html) or [Enumerable](https://ruby-doc.org/core/Enumerable.html) of strings that will be used as the spinner icon.\n\n### `\"proc\"`\n\nInstead of using `\"frames\"`: A proc which will generate the next frame with each call.\n\n### `\"interval\"`\n\nThe number of milliseconds between changing to the next spinner icon frame.\n\n### `\"mode\"`\n\nThe order in which frames should be played. It can be one of the following:\n\n- `\"linear\"`: Cycle through all frames in normal order\n- `\"reverse\"`: Cycle through all frames in reverse order\n- `\"swing\"`: Cycle through all frames in normal order, and then in reverse order, but only play first and last frame once each round\n- `\"random\"`: Play random frames\n\nPlease note: While `\"linear\"` also works with frames that are just an [Enumerable](https://ruby-doc.org/core/Enumerable.html), all other frame modes require the object to be representable as an [Array](https://ruby-doc.org/core/Array.html).\n\n### `\"stop\"`\n\nA frame to be used to end the spinner icon animation.\n\n## Remarks, Troubleshooting, Caveats\n\n- Interval is milliseconds, but don't rely on exact timing\n- Will not do anything if stream is not a real console (or `non_tty: true` is passed)\n- Colors not working? Be sure to include the [paint](https://github.com/janlelis/paint/) gem in your Gemfile\n- Don't set very short intervals (or it might affect performance substantially)\n\n## MIT License\n\n- Copyright (C) 2016 Jan Lelis \u003chttps://janlelis.com\u003e. Released under the MIT license.\n- Contains data from cli-spinners:  MIT License, Copyright (c) Sindre Sorhus \u003csindresorhus@gmail.com\u003e (sindresorhus.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjanlelis%2Fwhirly","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjanlelis%2Fwhirly","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjanlelis%2Fwhirly/lists"}