Giter Club home page Giter Club logo

spinner's Introduction

Spinner

carbon (3)

  • 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
  • Use a custom SpinnerStream for output

Install

Install via the Swift Package Manger by declaring Spinner as a dependency in your projects Package.swift:

.package(url: "https://github.com/dominicegginton/Spinner", from: "1.0.0")

Getting Started

import Foundation
import Spinner

let 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.

let spinner = Spinner(.dots, "foo bar baz")

The Spinner() class ins accepts optional arguments that customise the spinner.

/**
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.

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.

let spinner = Spinner(.dots, "foo bar baz")
spinner.stop()

The Spinner.stop() function accepts optional arguments that customise its behaviour.

/**
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.

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.

/**
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.

/**
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
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

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.

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.

struct SwiftCLISpinnerStream: SpinnerStream {
    private let _stdout: WritableStream
  
    init(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 for a clean and safe way of handling signals. The appropriate signal handler for your project could look something like:

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())

spinner's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

spinner's Issues

Completion Functions Display with Wrong Color

When calling a completion hander the if the spinner has a custom color set it will override the completion spinners color and display the currently set color.

Steps to reproduce

let spinner = Spinner(.dots, "example", color: .red)
spinner.start()
spinner.succeed()

Expected behavior

.succeed() should display a green tick

Actual behavior

.succeed() displays a red tick. this is the custom color that the spinner was set up with

Environment

  • Swift version: 5.0.1
  • OS version: macOS 10.14.6 Beta (18G29g)

Clear function does not return to start of line

Steps to reproduce

import Spinner
import Foundation

let spinner = Spinner(.dots, "Spinner Text")
spinner.start()
sleep(3)
spinner.clear()
print("Not at start of line")

Expected behavior

Text should be printed at start of line

Actual behavior

Text is printed behind padding

Environment

  • Swift version: Apple Swift version 4.2.1
  • OS version: macOS 10.14.2

Support for Formatting the Spinner

Current spinner object prints the pattern frames before the text object. It would be nice to implement support for formatting this output. For example:

Spinner Text .
Spinner Text ..
Spinner Text ...
Spinner Text ....
Spinner Text ✔

This could be implemented with a string that is passed to the Spinner object. For example, “[p] [t]”.

Improved Clearing Sinner Capability

Currently .stopAndClear()clears both the spinner frame and text and returns to a new line. It would be nice to have the option for a better .clear() functionality where a new line isn’t created and the cursor is reset to the start of the line.

Contributing README File

This would be really nice to have a README file for contributing. Should fully explain the process of contributing to the project 😀

Add Colour To The Spinner Pattern

We could add color to the spinner pattern. This could be done of the init of the spinner. Maybe could be updated with public func ?

Spinner renders default color as white

Steps to reproduce

Set your terminal to a different color by default, then create a default Spinner object.

import Spinner

let mySpinner = Spinner(.dots, "My Spinner")
mySpinner.start()
sleep(2)
mySpinner.stop()

Expected behavior

The spinner pattern should render as the default color of the terminal not white

Actual behavior

The spinner pattern renders as white

Environment

  • Swift version: 5.1
  • OS version: 10.15 Beta (19A558d)

Completion functions render incorrectly when paired with custom format

Steps to reproduce

If a spinner has a custom completion type with the animated pattern rendering after the text and a completion function is used to stop the spinner, a render error can occur if the passed text is shorter than the original. I am assuming this will occur when updating the text too.

let mySpinner = Spinner(.dots, "My Spinner", format: "{T} {S}")
mySpinner.start()
sleep(2)
mySpinner.failure("Fail")

Expected behavior

This should render final completion frame next to the text

Actual behavior

This renders the final completion frame with space between the text and the spinner

Environment

  • Swift version: 5.1
  • OS version: 10.15 Beta (19A558d)

Support Time Recording

It would be really nice to support recoding the time between the start and finish of the spinner, and enable the user to display the time the spinner was active. Useful to benchmark code too 😄

Stop function does display space between final frame and text

Steps to reproduce

let spinner = Spinner(.dots, "Loading Unicorns")
spinner.start()
sleep(2)
spinner.stop(finalFrame: "🦄")

Expected behavior

The spinner should display a space between the final frame and the text

Actual behavior

The spinner does not display a space between the final frame and the text

Environment

  • Swift version: 5.0.1
  • OS version: 0.14.6 Beta (18G29g)

Color

Adding color to the spinner objects would be nice. This would be helpful when calling for errors, warnings and fails.

Implementation

Could be implemented using the Rainbow Package

New Animated Demo

Better demo in the readme files will attack more users of the library. Could also include gifs in the documentation

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.