https://github.com/dominicegginton/spinner
Powerful Swift CLI Spinners
https://github.com/dominicegginton/spinner
cli-spinner cli-spinners loading spinner spinner-animations swift terminal
Last synced: 3 months ago
JSON representation
Powerful Swift CLI Spinners
- Host: GitHub
- URL: https://github.com/dominicegginton/spinner
- Owner: dominicegginton
- License: mit
- Created: 2019-05-06T15:43:55.000Z (about 6 years ago)
- Default Branch: main
- Last Pushed: 2024-08-09T10:51:30.000Z (10 months ago)
- Last Synced: 2024-10-13T16:43:07.324Z (8 months ago)
- Topics: cli-spinner, cli-spinners, loading, spinner, spinner-animations, swift, terminal
- Language: Swift
- Homepage:
- Size: 2.51 MB
- Stars: 44
- Watchers: 3
- Forks: 5
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Spinner

- Over **80** built-in spinner patterns
- Create custom spinners patterns
- Customise the spinners format
- Handy built-in completion functions (success, error, warning, info)
- Time your spinner and display its duration
- Apply colors with the use of [rainbow](https://github.com/onevcat/Rainbow)
- Use a custom `SpinnerStream` for output## Install
Install via the [**Swift Package Manger**](https://swift.org/package-manager/) by declaring **Spinner** as a dependency in your projects `Package.swift`:
``` swift
.package(url: "https://github.com/dominicegginton/Spinner", from: "1.0.0")
```## Getting Started
``` swift
import Foundation
import Spinnerlet spinner = Spinner(.dots, "foo bar baz")
spinner.start()
sleep(2) // do work
spinner.stop()
```## Documentation
#### Creating a spinner
Create a **spinner** by initializing an instance of the `Spinner` class.
``` swift
let spinner = Spinner(.dots, "foo bar baz")
```The `Spinner()` class ins accepts optional arguments that customise the spinner.
``` swift
/**
Initialize spinner
- Parameter pattern: spinner pattern
- Parameter message: message to render
- Parameter color: spinner pattern color
- Parameter speed: speed of spinner animation
- Parameter format: spinner format
- Parameter stream: output steam for spinner
- Parameter signal: signal trap implementation for spinner
*/
public init(_ pattern: SpinnerPattern, _ message: String = "", color: Color = .default, speed: Double? = nil, format: String = "{S} {T}", stream: SpinnerStream? = nil, signal: SpinnerSignal? = nil)
```#### Start the spinner
Call the `Spinner.start()` function to start the spinner animation. This will also call the `SpinnerStream.hideCursor()` function to hide the cursor.
``` swift
let spinner = Spinner(.dots, "foo bar baz")
spinner.start()
```#### Stop the spinner
Call the `Spinner.stop()` function to stop the spinner animation. This will also call the `SpinnerStream.showCursor()` function to show the cursor.
``` swift
let spinner = Spinner(.dots, "foo bar baz")
spinner.stop()
```The `Spinner.stop()` function accepts optional arguments that customise its behaviour.
``` swift
/**
Stop the spinner
- Parameter frame: final frame to render before stopping
- Parameter message: final message to render before stopping
- Parameter color: final frame color
- Parameter terminator: the string to print after all items have been printed
*/
public func stop(frame: String? = nil, message: String? = nil, color: Color? = nil, terminator: String = "\n")
```#### Clear the spinner
The `Spinner.clear()` function is a helper function that stops and clears the spinner. Its implementation uses `Spinner.stop()` under the hood.
``` swift
let spinner = Spinner(.dots, "foo bar baz")
spinner.clear()
```#### Helper functions
Helper functions that implement `Spinner.stop()` under the hood are provided for common tasks.
``` swift
/**
Stop and clear the spinner
*/
public func clear()/**
Stop and render a green tick for the final pattern frame
- Parameter message: spinner message to render
*/
public func success(_ message: String? = nil)/**
Stop and render a red cross for the final pattern frame
- Parameter message: spinner message to render
*/
public func error(_ message: String? = nil)/**
Stop and render a yellow warning symbol for the final pattern frame
- Parameter message: spinner message to render
*/
public func warning(_ message: String? = nil)/**
Stop and render a blue information sign for the final pattern frame
- Parameter message: spinner message to render
*/
public func info(_ message: String? = nil)
```#### Updating the spinner while animating
Functions are provided to update the spinner while animating.
``` swift
/**
Update spinner pattern
- Parameter pattern: spinner pattern
*/
public func pattern(_ pattern: SpinnerPattern)/**
Update spinner message
- Parameter message: message to render
*/
public func message(_ message: String)/**
Update spinner animation speed
- Parameter speed: speed of spinner animation
*/
public func speed(_ speed: Double)/**
Update spinner pattern color
- Parameter color: spinner pattern color
*/
public func color(_ color: Color)/**
Update spinner format
- Parameter format: spinner format
*/
public func format(_ format: String)
```#### Spinner patterns
#### Customise the spinner render format
To the spinner the `Spinner.format` string is taken as a base and occurrences of keys are replaced to generate the rendered spinner.
- `{S}` renders the animated pattern
- `{T}` renders the message
- `{D}` renders the duration of since starting the spinner``` swift
let spinner = Spinner(.dots, "foo bar baz", format : "{T} - {S}") // foo bar baz - ⠧
```#### Timing the spinners duration
Use a custom `Spinner.format` string that includes `{D}` in order to render the duration of time since starting the spinner animation
```swift
let spinner = Spinner(.dots, "foo bar baz", format: "{D} {T} - {S}") // 8s ⠧ foo bar baz
```#### Creating Custom Patterns
The `SpinnerPattern()` enum initializer to create a **spinner** pattern with an array of strings.
``` swift
let pattern = SpinnerPattern(frames: ["1","2","3","4","5"])
let spinner = Spinner(pattern, "foo bar baz", speed: 0.3) // 1 foo bar baz
```#### CustomStreams
**Spinner** wraps output logic in a `SpinnerStream` protocol. This library provides the `StdOutSpinnerStream` class that implements to writing to **STDOUT**.
``` swift
struct SwiftCLISpinnerStream: SpinnerStream {
private let _stdout: WritableStreaminit(stdout: WritableStream) {
_stdout = stdout
}func write(string: String, terminator: String) {
_stdout.write(string, terminator: terminator)
}func hideCursor() {
_stdout.write("\u{001B}[?25l", terminator: "")
}func showCursor() {
_stdout.write("\u{001B}[?25h", terminator: "")
}
}let spinner = Spinner(.dots, "foo bar baz", stream: SwiftCLISpinnerStream(stdout: stdout))
```#### Caveat
In order to handle process interrupts (for example, SIGINT through ctrl+c) a signal handler is used to show the user's cursor before exiting. This library provides a `SpinnerSignal` protocol and a `DefaultSpinnerSignal` structure that handles this functionality by default. If this conflicts with other signals in use, a custom implementation of `SpinnerSignal` can be provided. See [IBM-Swift/BlueSignals](https://github.com/IBM-Swift/BlueSignals) for a clean and safe way of handling signals. The appropriate signal handler for your project could look something like:
``` swift
struct CustomSpinnerSignal: SpinnerSignal {
func trap() {
Signals.trap(signal: .int) { _ in
// print("\u{001B}[?25h", terminator: "")
// exit(0)
}
}
}let spinner = Spinner(.dots, "foo bar baz", signal: CustomSpinnerSignal())
```