tty-spinner 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +200 -42
- data/lib/tty/spinner.rb +169 -17
- data/lib/tty/spinner/formats.rb +119 -10
- data/lib/tty/spinner/version.rb +1 -1
- metadata +21 -38
- data/.gitignore +0 -14
- data/.rspec +0 -2
- data/.ruby-version +0 -1
- data/.travis.yml +0 -24
- data/Gemfile +0 -17
- data/Rakefile +0 -8
- data/examples/basic.rb +0 -9
- data/spec/spec_helper.rb +0 -45
- data/spec/unit/hide_cursor_spec.rb +0 -21
- data/spec/unit/new_spec.rb +0 -22
- data/spec/unit/reset_spec.rb +0 -23
- data/spec/unit/spin_spec.rb +0 -46
- data/spec/unit/stop_spec.rb +0 -49
- data/tasks/console.rake +0 -10
- data/tasks/coverage.rake +0 -11
- data/tasks/spec.rake +0 -29
- data/tty-spinner.gemspec +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e04e5566451769e21e19b19e1e737a2a4680529
|
4
|
+
data.tar.gz: f62fbd9e4da87305573bdf3214f32029d51efd41
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36bc537184f487b0d0b1ee2b97075c0179eb07e5bd1e7cdc42036d1a7fc67972b22161fd178577e96dbdd959a498073aa6f4cd7b36aef5c35f8ad7c6a326a81c
|
7
|
+
data.tar.gz: 02d7cf58e0fd5650249ee89e249211217f10793feee1d9aaa77600a220de2c789ec029150ebc5848e6446a105cdf9db673bfadd29306c31df1bf78de9e79b157
|
data/README.md
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
# TTY::Spinner
|
2
|
-
[][codeclimate]
|
5
|
-
[][gem]
|
3
|
+
[][travis]
|
4
|
+
[][codeclimate]
|
5
|
+
[][coverage]
|
6
|
+
[][inchpages]
|
6
7
|
|
7
8
|
[gem]: http://badge.fury.io/rb/tty-spinner
|
8
9
|
[travis]: http://travis-ci.org/peter-murach/tty-spinner
|
9
10
|
[codeclimate]: https://codeclimate.com/github/peter-murach/tty-spinner
|
10
11
|
[coverage]: https://coveralls.io/r/peter-murach/tty-spinner
|
12
|
+
[inchpages]: http://inch-ci.org/github/peter-murach/tty-spinner
|
11
13
|
|
12
|
-
A terminal spinner for tasks that have non-deterministic time frame.
|
14
|
+
> A terminal spinner for tasks that have non-deterministic time frame.
|
13
15
|
|
14
16
|
**TTY::Spinner** provides independent spinner component for [TTY](https://github.com/peter-murach/tty) toolkit.
|
15
17
|
|
@@ -32,61 +34,122 @@ Or install it yourself as:
|
|
32
34
|
## Contents
|
33
35
|
|
34
36
|
* [1. Usage](#1-usage)
|
35
|
-
|
36
|
-
* [1
|
37
|
-
* [
|
38
|
-
* [2.
|
39
|
-
* [
|
37
|
+
* [2. API](#2-api)
|
38
|
+
* [2.1 spin](#21-spin)
|
39
|
+
* [2.2 start](#22-start)
|
40
|
+
* [2.3 stop](#23-stop)
|
41
|
+
* [2.4 success](#24-success)
|
42
|
+
* [2.5 error](#25-error)
|
43
|
+
* [2.6 reset](#26-reset)
|
44
|
+
* [2.7 join](#27-join)
|
45
|
+
* [3. Configuration](#3-configuration)
|
46
|
+
* [3.1 :format](#31-format)
|
47
|
+
* [3.2 :frames](#32-frames)
|
48
|
+
* [3.3 :interval](#33-interval)
|
49
|
+
* [3.4 :hide_cursor](#34-hide_cursor)
|
50
|
+
* [3.5 :clear](#35-clear)
|
51
|
+
* [3.6 :success_mark](#36-success_mark)
|
52
|
+
* [3.7 :error_mark](#37-error_mark)
|
53
|
+
* [3.8 :output](#38-output)
|
54
|
+
* [4. Events](#4-events)
|
55
|
+
* [4.1 done](#41-done)
|
56
|
+
* [4.2 success](#42-success)
|
57
|
+
* [4.3 error](#43-error)
|
40
58
|
|
41
59
|
## 1. Usage
|
42
60
|
|
43
|
-
**TTY::
|
61
|
+
**TTY::Spinner** by default uses `:classic` type of formatter and requires no paramters:
|
44
62
|
|
45
63
|
```ruby
|
46
64
|
spinner = TTY::Spinner.new
|
47
65
|
```
|
48
66
|
|
49
|
-
In addition you can provide a message and format type you would like for the spinning display
|
67
|
+
In addition you can provide a message with `:spinner` token and format type you would like for the spinning display:
|
50
68
|
|
51
69
|
```ruby
|
52
|
-
spinner = TTY::Spinner.new(
|
70
|
+
spinner = TTY::Spinner.new("[:spinner] Loading ...", format: :pulse_2)
|
53
71
|
30.times do
|
54
72
|
spinner.spin
|
55
73
|
sleep(0.1)
|
56
74
|
end
|
75
|
+
spinner.stop('Done!')
|
76
|
+
```
|
77
|
+
|
78
|
+
This would produce animation in your terminal:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
⎺ Loading ...
|
57
82
|
```
|
58
83
|
|
59
|
-
|
84
|
+
and when finished output:
|
60
85
|
|
61
86
|
```ruby
|
62
|
-
Loading ...
|
87
|
+
_ Loading ... Done!
|
63
88
|
```
|
64
89
|
|
65
|
-
|
90
|
+
For more usage examples please see [examples directory](https://github.com/peter-murach/tty-spinner/tree/master/examples)
|
91
|
+
|
92
|
+
## 2. API
|
93
|
+
|
94
|
+
### 2.1 spin
|
66
95
|
|
67
96
|
The main workhorse of the spinner is the `spin` method. Looping over `spin` method will animate a given spinner.
|
68
97
|
|
69
|
-
###
|
98
|
+
### 2.2 start
|
99
|
+
|
100
|
+
To perform automatic spinning call `start` method like so:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
spinner.start
|
104
|
+
```
|
105
|
+
|
106
|
+
The speed with which the spinning happens is determined by the `:interval` parameter. All the spinner formats have their default intervals specified [see](https://github.com/peter-murach/tty-spinner/blob/master/lib/tty/spinner/formats.rb)
|
70
107
|
|
71
|
-
|
108
|
+
### 2.3 stop
|
109
|
+
|
110
|
+
In order to stop the spinner call `stop`. This will finish drawing the spinning animation and return to new line.
|
72
111
|
|
73
112
|
```ruby
|
74
113
|
spinner.stop
|
75
114
|
```
|
76
115
|
|
77
|
-
You can further pass a
|
116
|
+
You can further pass a message to print when animation is finished.
|
78
117
|
|
79
118
|
```ruby
|
80
119
|
spinner.stop('Done!')
|
81
120
|
```
|
82
121
|
|
83
|
-
|
122
|
+
### 2.4 success
|
123
|
+
|
124
|
+
Use `success` call to stop the spinning animation and replace the spinning symbol with checkmark character to indicate successful completion.
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
spinner = TTY::Spinner.new("[:spinner] Task name")
|
128
|
+
spinner.success('(successful)')
|
129
|
+
```
|
130
|
+
|
131
|
+
This will produce:
|
132
|
+
|
133
|
+
```
|
134
|
+
[✔] Task name (successful)
|
135
|
+
```
|
136
|
+
|
137
|
+
### 2.5 error
|
138
|
+
|
139
|
+
Use `error` call to stop the spining animation and replace the spinning symbol with cross character to indicate error completion.
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
spinner = TTY::Spinner.new("[:spinner] Task name")
|
143
|
+
spinner.error('(error)')
|
144
|
+
```
|
145
|
+
|
146
|
+
This will produce:
|
84
147
|
|
85
148
|
```ruby
|
86
|
-
|
149
|
+
[✖] Task name (error)
|
87
150
|
```
|
88
151
|
|
89
|
-
###
|
152
|
+
### 2.6 reset
|
90
153
|
|
91
154
|
In order to reset the spinner to its initial frame do:
|
92
155
|
|
@@ -94,30 +157,125 @@ In order to reset the spinner to its initial frame do:
|
|
94
157
|
spinner.reset
|
95
158
|
```
|
96
159
|
|
97
|
-
|
160
|
+
### 2.7 join
|
161
|
+
|
162
|
+
One way to wait while the spinning animates is to join the thread started with `start` method:
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
spinner.join
|
166
|
+
```
|
167
|
+
|
168
|
+
Optionally you can provide timeout:
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
spinner.join(0.5)
|
172
|
+
```
|
173
|
+
|
174
|
+
## 3. Configuration
|
98
175
|
|
99
|
-
There are number of configuration options that can be provided
|
176
|
+
There are number of configuration options that can be provided to customise the behaviour of a spinner.
|
100
177
|
|
101
|
-
|
102
|
-
* `output` the output stream defaulting to `stderr`
|
103
|
-
* `hide_cursor` to hide display cursor defaulting to `false`
|
178
|
+
### 3.1 :format
|
104
179
|
|
105
|
-
|
180
|
+
Use one of the predefined spinner styles by passing the formatting token `:format`
|
106
181
|
|
107
|
-
|
182
|
+
```ruby
|
183
|
+
spinner = TTY::Spinner.new(format: :pulse_2)
|
184
|
+
```
|
185
|
+
|
186
|
+
All spinner formats that **TTY::Spinner** accepts are defined in [/lib/tty/spinner/formats.rb](https://github.com/peter-murach/tty-spinner/blob/master/lib/tty/spinner/formats.rb)
|
187
|
+
|
188
|
+
If you wish to see all available formats in action run the `formats.rb` file in examples folder like so:
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
bundle exec ruby examples/formats.rb
|
192
|
+
```
|
193
|
+
|
194
|
+
### 3.2 :frames
|
195
|
+
|
196
|
+
If you wish to use custom formatting use the `:frames` option with either `array` or `string` of characters.
|
197
|
+
|
198
|
+
```ruby
|
199
|
+
spinner = TTY::Spinner.new(frames: [".", "o", "0", "@", "*"])
|
200
|
+
```
|
108
201
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
202
|
+
### 3.3 :interval
|
203
|
+
|
204
|
+
The `:interval` option accepts `integer` representing number of `Hz` units, for instance, frequency of 10 will mean that the spinning animation will be displayed 10 times per second.
|
205
|
+
|
206
|
+
```ruby
|
207
|
+
spinner = TTY::Spinner.new(interval: 20) # 20 Hz (20 times per second)
|
208
|
+
```
|
209
|
+
|
210
|
+
### 3.4 :hide_cursor
|
211
|
+
|
212
|
+
Hides cursor when spinning animation performs. Defaults to `false`.
|
213
|
+
|
214
|
+
```ruby
|
215
|
+
spinner = TTY::Spinner.new(hide_cursor: true)
|
216
|
+
```
|
217
|
+
|
218
|
+
### 3.5 :clear
|
219
|
+
|
220
|
+
After spinner is finished clears its output. Defaults to `false`.
|
221
|
+
|
222
|
+
```ruby
|
223
|
+
spinner = TTY::Spinner.new(clear: true)
|
224
|
+
```
|
225
|
+
|
226
|
+
### 3.6 :success_mark
|
227
|
+
|
228
|
+
To change marker indicating successful completion use the `:success_mark` option:
|
229
|
+
|
230
|
+
```ruby
|
231
|
+
spinner = TTY::Spinner.new(success_mark: '+')
|
232
|
+
```
|
233
|
+
|
234
|
+
### 3.7 :error_mark
|
235
|
+
|
236
|
+
To change marker indicating error completion use the `:error_mark` option:
|
237
|
+
|
238
|
+
```ruby
|
239
|
+
spinner = TTY::Spinner.new(error_mark: 'x')
|
240
|
+
```
|
241
|
+
|
242
|
+
### 3.8 :output
|
243
|
+
|
244
|
+
To change where data is streamed use `:output` option like so:
|
245
|
+
|
246
|
+
```
|
247
|
+
spinner = TTY::Spinner.new(output: $stdout)
|
248
|
+
```
|
249
|
+
|
250
|
+
The output stream defaults to `stderr`.
|
251
|
+
|
252
|
+
## 4. Events
|
253
|
+
|
254
|
+
**TTY::Spinner** emits `:done`, `:success` and `:error` event types when spinner is stopped.
|
255
|
+
|
256
|
+
### 4.1 done
|
257
|
+
|
258
|
+
This event is emitted irrespective of the completion method. In order to listen for this event you need to register callback:
|
259
|
+
|
260
|
+
```ruby
|
261
|
+
spinner.on(:done) { ... }
|
262
|
+
```
|
263
|
+
|
264
|
+
### 4.2 success
|
265
|
+
|
266
|
+
This event is fired when `success` call is made. In order to respond to the event, you need to register callback:
|
267
|
+
|
268
|
+
```ruby
|
269
|
+
spinner.on(:success) { ... }
|
270
|
+
```
|
271
|
+
|
272
|
+
### 4.3 error
|
273
|
+
|
274
|
+
This event is fired when `error` completion is called. In order to respond to the event, you need to register callback:
|
275
|
+
|
276
|
+
```ruby
|
277
|
+
spinner.on(:error) { ... }
|
278
|
+
```
|
121
279
|
|
122
280
|
## Contributing
|
123
281
|
|
@@ -129,4 +287,4 @@ There are number of configuration options that can be provided:
|
|
129
287
|
|
130
288
|
## Copyright
|
131
289
|
|
132
|
-
Copyright (c) 2014 Piotr Murach. See LICENSE for further details.
|
290
|
+
Copyright (c) 2014-2016 Piotr Murach. See LICENSE for further details.
|
data/lib/tty/spinner.rb
CHANGED
@@ -9,13 +9,19 @@ module TTY
|
|
9
9
|
# @api public
|
10
10
|
class Spinner
|
11
11
|
include Formats
|
12
|
-
ECMA_ESC = "\x1b"
|
13
|
-
ECMA_CSI = "\x1b["
|
14
|
-
ECMA_CHA = 'G'
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
ECMA_ESC = "\x1b".freeze
|
14
|
+
ECMA_CSI = "\x1b[".freeze
|
15
|
+
ECMA_CHA = 'G'.freeze
|
16
|
+
ECMA_CLR = 'K'.freeze
|
17
|
+
|
18
|
+
DEC_RST = 'l'.freeze
|
19
|
+
DEC_SET = 'h'.freeze
|
20
|
+
DEC_TCEM = '?25'.freeze
|
21
|
+
|
22
|
+
MATCHER = /:spinner/.freeze
|
23
|
+
TICK = '✔'.freeze
|
24
|
+
CROSS = '✖'.freeze
|
19
25
|
|
20
26
|
# The object that responds to print call defaulting to stderr
|
21
27
|
#
|
@@ -59,21 +65,98 @@ module TTY
|
|
59
65
|
# the object that responds to print call defaulting to stderr
|
60
66
|
# @option options [Boolean] :hide_cursor
|
61
67
|
# display or hide cursor
|
68
|
+
# @option options [Boolean] :clear
|
69
|
+
# clear ouptut when finished
|
70
|
+
# @option options [Float] :interval
|
71
|
+
# the interval for auto spinning
|
62
72
|
#
|
63
73
|
# @api public
|
64
74
|
def initialize(*args)
|
65
75
|
options = args.last.is_a?(::Hash) ? args.pop : {}
|
66
|
-
@message = args.empty? ? '' : args.pop
|
76
|
+
@message = args.empty? ? ':spinner' : args.pop
|
67
77
|
|
68
|
-
@format = options.fetch(:format) { :
|
78
|
+
@format = options.fetch(:format) { :classic }
|
69
79
|
@output = options.fetch(:output) { $stderr }
|
70
80
|
@hide_cursor = options.fetch(:hide_cursor) { false }
|
81
|
+
@frames = options.fetch(:frames) {
|
82
|
+
fetch_format(@format.to_sym, :frames) }
|
83
|
+
@clear = options.fetch(:clear) { false }
|
84
|
+
@success_mark= options.fetch(:success_mark) { TICK }
|
85
|
+
@error_mark = options.fetch(:error_mark) { CROSS }
|
86
|
+
@interval = options.fetch(:interval) {
|
87
|
+
fetch_format(@format.to_sym, :interval) }
|
71
88
|
|
72
|
-
@
|
89
|
+
@callbacks = Hash.new { |h, k| h[k] = [] }
|
73
90
|
@length = @frames.length
|
74
91
|
@current = 0
|
75
92
|
@done = false
|
76
|
-
@
|
93
|
+
@state = :stopped
|
94
|
+
end
|
95
|
+
|
96
|
+
def spinning?
|
97
|
+
@state == :spinning
|
98
|
+
end
|
99
|
+
|
100
|
+
def success?
|
101
|
+
@state == :success
|
102
|
+
end
|
103
|
+
|
104
|
+
def error?
|
105
|
+
@state == :error
|
106
|
+
end
|
107
|
+
|
108
|
+
# Register callback
|
109
|
+
#
|
110
|
+
# @api public
|
111
|
+
def on(name, &block)
|
112
|
+
@callbacks[name] << block
|
113
|
+
self
|
114
|
+
end
|
115
|
+
|
116
|
+
# Start automatic spinning
|
117
|
+
#
|
118
|
+
#
|
119
|
+
# @api public
|
120
|
+
def start
|
121
|
+
@started_at = Time.now
|
122
|
+
sleep_time = 1.0 / @interval
|
123
|
+
|
124
|
+
@thread = Thread.new do
|
125
|
+
while @started_at do
|
126
|
+
spin
|
127
|
+
sleep(sleep_time)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Duration of the spinning animation
|
133
|
+
#
|
134
|
+
# @return [Numeric]
|
135
|
+
#
|
136
|
+
# @api public
|
137
|
+
def duration
|
138
|
+
@started_at ? Time.now - @started_at : nil
|
139
|
+
end
|
140
|
+
|
141
|
+
# Join running spinner
|
142
|
+
#
|
143
|
+
# @param [Float] timeout
|
144
|
+
# the timeout for join
|
145
|
+
#
|
146
|
+
# @api public
|
147
|
+
def join(timeout = nil)
|
148
|
+
fail NotSpinningError.new(
|
149
|
+
"Cannot join spinner that is not running"
|
150
|
+
) unless @thread
|
151
|
+
|
152
|
+
timeout ? @thread.join(timeout) : @thread.join
|
153
|
+
end
|
154
|
+
|
155
|
+
# Kill running spinner
|
156
|
+
#
|
157
|
+
# @api public
|
158
|
+
def kill
|
159
|
+
@thread.kill if @thread
|
77
160
|
end
|
78
161
|
|
79
162
|
# Perform a spin
|
@@ -85,14 +168,14 @@ module TTY
|
|
85
168
|
def spin
|
86
169
|
return if @done
|
87
170
|
|
88
|
-
if @hide_cursor &&
|
171
|
+
if @hide_cursor && !spinning?
|
89
172
|
write(ECMA_CSI + DEC_TCEM + DEC_RST)
|
90
173
|
end
|
91
174
|
|
92
|
-
data = message
|
175
|
+
data = message.gsub(MATCHER, @frames[@current])
|
93
176
|
write(data, true)
|
94
|
-
@current
|
95
|
-
@
|
177
|
+
@current = (@current + 1) % @length
|
178
|
+
@state = :spinning
|
96
179
|
data
|
97
180
|
end
|
98
181
|
|
@@ -103,12 +186,55 @@ module TTY
|
|
103
186
|
#
|
104
187
|
# @api public
|
105
188
|
def stop(stop_message = '')
|
106
|
-
if @hide_cursor &&
|
189
|
+
if @hide_cursor && spinning?
|
107
190
|
write(ECMA_CSI + DEC_TCEM + DEC_SET, false)
|
108
191
|
end
|
109
192
|
@done = true
|
110
|
-
|
111
|
-
|
193
|
+
@started_at = nil
|
194
|
+
emit(:done)
|
195
|
+
return clear_line if @clear
|
196
|
+
|
197
|
+
char = if success?
|
198
|
+
@success_mark
|
199
|
+
elsif error?
|
200
|
+
@error_mark
|
201
|
+
else
|
202
|
+
@frames[@current - 1]
|
203
|
+
end
|
204
|
+
data = message.gsub(MATCHER, char)
|
205
|
+
|
206
|
+
if !stop_message.empty?
|
207
|
+
data << ' ' + stop_message
|
208
|
+
end
|
209
|
+
|
210
|
+
write(data, true)
|
211
|
+
write("\n", false) unless @clear
|
212
|
+
reset
|
213
|
+
end
|
214
|
+
|
215
|
+
# Finish spinning and set state to :success
|
216
|
+
#
|
217
|
+
# @api public
|
218
|
+
def success(stop_message = '')
|
219
|
+
@state = :success
|
220
|
+
stop(stop_message)
|
221
|
+
emit(:success)
|
222
|
+
end
|
223
|
+
|
224
|
+
# Finish spinning and set state to :error
|
225
|
+
#
|
226
|
+
# @api public
|
227
|
+
def error(stop_message = '')
|
228
|
+
@state = :error
|
229
|
+
stop(stop_message)
|
230
|
+
emit(:error)
|
231
|
+
end
|
232
|
+
|
233
|
+
# Clear current line
|
234
|
+
#
|
235
|
+
# @api public
|
236
|
+
def clear_line
|
237
|
+
output.print(ECMA_CSI + '0m' + ECMA_CSI + '1000D' + ECMA_CSI + ECMA_CLR)
|
112
238
|
end
|
113
239
|
|
114
240
|
# Reset the spinner to initial frame
|
@@ -116,6 +242,7 @@ module TTY
|
|
116
242
|
# @api public
|
117
243
|
def reset
|
118
244
|
@current = 0
|
245
|
+
@state = :stopped
|
119
246
|
end
|
120
247
|
|
121
248
|
private
|
@@ -130,5 +257,30 @@ module TTY
|
|
130
257
|
output.print(data)
|
131
258
|
output.flush
|
132
259
|
end
|
260
|
+
|
261
|
+
# Emit callback
|
262
|
+
#
|
263
|
+
# @api private
|
264
|
+
def emit(name, *args)
|
265
|
+
@callbacks[name].each do |block|
|
266
|
+
block.call(*args)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
# Find frames by token name
|
271
|
+
#
|
272
|
+
# @param [Symbol] token
|
273
|
+
# the name for the frames
|
274
|
+
#
|
275
|
+
# @return [Array, String]
|
276
|
+
#
|
277
|
+
# @api private
|
278
|
+
def fetch_format(token, property)
|
279
|
+
if FORMATS.key?(token)
|
280
|
+
FORMATS[token][property]
|
281
|
+
else
|
282
|
+
raise ArgumentError, "Unknown format token `:#{token}`"
|
283
|
+
end
|
284
|
+
end
|
133
285
|
end # Spinner
|
134
286
|
end # TTY
|
data/lib/tty/spinner/formats.rb
CHANGED
@@ -3,16 +3,125 @@
|
|
3
3
|
module TTY
|
4
4
|
module Formats
|
5
5
|
FORMATS = {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
6
|
+
classic: {
|
7
|
+
interval: 10,
|
8
|
+
frames: %w{| / - \\}
|
9
|
+
},
|
10
|
+
spin: {
|
11
|
+
interval: 10,
|
12
|
+
frames: %w{◴ ◷ ◶ ◵ }
|
13
|
+
},
|
14
|
+
spin_2: {
|
15
|
+
interval: 10,
|
16
|
+
frames: %w{◐ ◓ ◑ ◒ }
|
17
|
+
},
|
18
|
+
spin_3: {
|
19
|
+
interval: 10,
|
20
|
+
frames: %w{◰ ◳ ◲ ◱}
|
21
|
+
},
|
22
|
+
spin_4: {
|
23
|
+
inteval: 10,
|
24
|
+
frames: %w{╫ ╪'}
|
25
|
+
},
|
26
|
+
pulse: {
|
27
|
+
interval: 10,
|
28
|
+
frames: %w{⎺ ⎻ ⎼ ⎽ ⎼ ⎻}
|
29
|
+
},
|
30
|
+
pulse_2: {
|
31
|
+
interval: 15,
|
32
|
+
frames: %w{▁ ▃ ▅ ▆ ▇ █ ▇ ▆ ▅ ▃ }
|
33
|
+
},
|
34
|
+
pulse_3: {
|
35
|
+
interval: 20,
|
36
|
+
frames: '▉▊▋▌▍▎▏▎▍▌▋▊▉'
|
37
|
+
},
|
38
|
+
dots: {
|
39
|
+
interval: 10,
|
40
|
+
frames: [ "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏" ]
|
41
|
+
},
|
42
|
+
arrow: {
|
43
|
+
interval: 10,
|
44
|
+
frames: %w{← ↖ ↑ ↗ → ↘ ↓ ↙ }
|
45
|
+
},
|
46
|
+
arrow_pulse: {
|
47
|
+
interval: 10,
|
48
|
+
frames: [
|
49
|
+
"▹▹▹▹▹",
|
50
|
+
"▸▹▹▹▹",
|
51
|
+
"▹▸▹▹▹",
|
52
|
+
"▹▹▸▹▹",
|
53
|
+
"▹▹▹▸▹",
|
54
|
+
"▹▹▹▹▸"
|
55
|
+
]
|
56
|
+
},
|
57
|
+
triangle: {
|
58
|
+
interval: 10,
|
59
|
+
frames: %w{◢ ◣ ◤ ◥}
|
60
|
+
},
|
61
|
+
arc: {
|
62
|
+
interval: 10,
|
63
|
+
frames: %w{ ◜ ◠ ◝ ◞ ◡ ◟ }
|
64
|
+
},
|
65
|
+
pipe: {
|
66
|
+
interval: 10,
|
67
|
+
frames: %w{ ┤ ┘ ┴ └ ├ ┌ ┬ ┐ }
|
68
|
+
},
|
69
|
+
bouncing: {
|
70
|
+
interval: 10,
|
71
|
+
frames: [
|
72
|
+
"[ ]",
|
73
|
+
"[ =]",
|
74
|
+
"[ ==]",
|
75
|
+
"[ ===]",
|
76
|
+
"[====]",
|
77
|
+
"[=== ]",
|
78
|
+
"[== ]",
|
79
|
+
"[= ]"
|
80
|
+
]
|
81
|
+
},
|
82
|
+
bouncing_ball: {
|
83
|
+
interval: 10,
|
84
|
+
frames: [
|
85
|
+
"( ● )",
|
86
|
+
"( ● )",
|
87
|
+
"( ● )",
|
88
|
+
"( ● )",
|
89
|
+
"( ●)",
|
90
|
+
"( ● )",
|
91
|
+
"( ● )",
|
92
|
+
"( ● )",
|
93
|
+
"( ● )",
|
94
|
+
"(● )"
|
95
|
+
]
|
96
|
+
},
|
97
|
+
box_bounce: {
|
98
|
+
interval: 10,
|
99
|
+
frames: %w{ ▌ ▀ ▐ ▄ }
|
100
|
+
},
|
101
|
+
box_bounce_2: {
|
102
|
+
interval: 10,
|
103
|
+
frames: %w{ ▖ ▘ ▝ ▗ }
|
104
|
+
},
|
105
|
+
star: {
|
106
|
+
interval: 10,
|
107
|
+
frames: %w{ ✶ ✸ ✹ ✺ ✹ ✷ }
|
108
|
+
},
|
109
|
+
toggle: {
|
110
|
+
interval: 10,
|
111
|
+
frames: %w{ ■ □ ▪ ▫ }
|
112
|
+
},
|
113
|
+
balloon: {
|
114
|
+
interval: 10,
|
115
|
+
frames: %w{ . o O @ * }
|
116
|
+
},
|
117
|
+
balloon_2: {
|
118
|
+
interval: 10,
|
119
|
+
frames: %w{. o O ° O o . }
|
120
|
+
},
|
121
|
+
flip: {
|
122
|
+
interval: 10,
|
123
|
+
frames: '-◡⊙-◠'.freeze
|
124
|
+
}
|
16
125
|
}
|
17
126
|
end # Formats
|
18
127
|
end # TTY
|
data/lib/tty/spinner/version.rb
CHANGED
metadata
CHANGED
@@ -1,43 +1,49 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tty-spinner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.5.0
|
20
|
+
- - <
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2.0'
|
20
23
|
type: :development
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- -
|
27
|
+
- - '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.5.0
|
30
|
+
- - <
|
25
31
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
32
|
+
version: '2.0'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: rake
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
31
|
-
- -
|
37
|
+
- - '>='
|
32
38
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
39
|
+
version: '0'
|
34
40
|
type: :development
|
35
41
|
prerelease: false
|
36
42
|
version_requirements: !ruby/object:Gem::Requirement
|
37
43
|
requirements:
|
38
|
-
- -
|
44
|
+
- - '>='
|
39
45
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
46
|
+
version: '0'
|
41
47
|
description: A terminal spinner for tasks that have non-deterministic time frame.
|
42
48
|
email:
|
43
49
|
- pmurach@gmail.com
|
@@ -45,29 +51,12 @@ executables: []
|
|
45
51
|
extensions: []
|
46
52
|
extra_rdoc_files: []
|
47
53
|
files:
|
48
|
-
- .gitignore
|
49
|
-
- .rspec
|
50
|
-
- .ruby-version
|
51
|
-
- .travis.yml
|
52
|
-
- Gemfile
|
53
|
-
- LICENSE.txt
|
54
|
-
- README.md
|
55
|
-
- Rakefile
|
56
|
-
- examples/basic.rb
|
57
|
-
- lib/tty-spinner.rb
|
58
|
-
- lib/tty/spinner.rb
|
59
54
|
- lib/tty/spinner/formats.rb
|
60
55
|
- lib/tty/spinner/version.rb
|
61
|
-
-
|
62
|
-
-
|
63
|
-
-
|
64
|
-
-
|
65
|
-
- spec/unit/spin_spec.rb
|
66
|
-
- spec/unit/stop_spec.rb
|
67
|
-
- tasks/console.rake
|
68
|
-
- tasks/coverage.rake
|
69
|
-
- tasks/spec.rake
|
70
|
-
- tty-spinner.gemspec
|
56
|
+
- lib/tty/spinner.rb
|
57
|
+
- lib/tty-spinner.rb
|
58
|
+
- LICENSE.txt
|
59
|
+
- README.md
|
71
60
|
homepage: https://github.com/peter-murach/tty-spinner
|
72
61
|
licenses:
|
73
62
|
- MIT
|
@@ -92,11 +81,5 @@ rubygems_version: 2.0.3
|
|
92
81
|
signing_key:
|
93
82
|
specification_version: 4
|
94
83
|
summary: A terminal spinner for tasks that have non-deterministic time frame.
|
95
|
-
test_files:
|
96
|
-
- spec/spec_helper.rb
|
97
|
-
- spec/unit/hide_cursor_spec.rb
|
98
|
-
- spec/unit/new_spec.rb
|
99
|
-
- spec/unit/reset_spec.rb
|
100
|
-
- spec/unit/spin_spec.rb
|
101
|
-
- spec/unit/stop_spec.rb
|
84
|
+
test_files: []
|
102
85
|
has_rdoc:
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.0.0
|
data/.travis.yml
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
bundler_args: --without yard benchmarks
|
3
|
-
script: "bundle exec rake ci"
|
4
|
-
rvm:
|
5
|
-
- 1.9.3
|
6
|
-
- 2.0.0
|
7
|
-
- 2.1.0
|
8
|
-
- ruby-head
|
9
|
-
matrix:
|
10
|
-
include:
|
11
|
-
- rvm: jruby-19mode
|
12
|
-
- rvm: jruby-20mode
|
13
|
-
- rvm: jruby-21mode
|
14
|
-
- rvm: jruby-head
|
15
|
-
- rvm: rbx-2
|
16
|
-
allow_failures:
|
17
|
-
- rvm: ruby-head
|
18
|
-
- rvm: jruby-head
|
19
|
-
- rvm: jruby-19mode
|
20
|
-
- rvm: jruby-20mode
|
21
|
-
- rvm: jruby-21mode
|
22
|
-
fast_finish: true
|
23
|
-
branches:
|
24
|
-
only: master
|
data/Gemfile
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gemspec
|
4
|
-
|
5
|
-
group :development do
|
6
|
-
gem 'rake', '~> 10.3.2'
|
7
|
-
gem 'rspec', '~> 3.1.0'
|
8
|
-
gem 'yard', '~> 0.8.7'
|
9
|
-
gem 'timecop', '~> 0.7.1'
|
10
|
-
gem 'pastel', '~> 0.3.0'
|
11
|
-
end
|
12
|
-
|
13
|
-
group :metrics do
|
14
|
-
gem 'coveralls', '~> 0.7.0'
|
15
|
-
gem 'simplecov', '~> 0.8.2'
|
16
|
-
gem 'yardstick', '~> 0.9.9'
|
17
|
-
end
|
data/Rakefile
DELETED
data/examples/basic.rb
DELETED
data/spec/spec_helper.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
if RUBY_VERSION > '1.9' and (ENV['COVERAGE'] || ENV['TRAVIS'])
|
4
|
-
require 'simplecov'
|
5
|
-
require 'coveralls'
|
6
|
-
|
7
|
-
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
8
|
-
SimpleCov::Formatter::HTMLFormatter,
|
9
|
-
Coveralls::SimpleCov::Formatter
|
10
|
-
]
|
11
|
-
|
12
|
-
SimpleCov.start do
|
13
|
-
command_name 'spec'
|
14
|
-
add_filter 'spec'
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
require 'tty-spinner'
|
19
|
-
|
20
|
-
RSpec.configure do |config|
|
21
|
-
config.expect_with :rspec do |expectations|
|
22
|
-
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
23
|
-
end
|
24
|
-
|
25
|
-
config.mock_with :rspec do |mocks|
|
26
|
-
mocks.verify_partial_doubles = true
|
27
|
-
end
|
28
|
-
|
29
|
-
# Limits the available syntax to the non-monkey patched syntax that is recommended.
|
30
|
-
config.disable_monkey_patching!
|
31
|
-
|
32
|
-
# This setting enables warnings. It's recommended, but in some cases may
|
33
|
-
# be too noisy due to issues in dependencies.
|
34
|
-
config.warnings = true
|
35
|
-
|
36
|
-
if config.files_to_run.one?
|
37
|
-
config.default_formatter = 'doc'
|
38
|
-
end
|
39
|
-
|
40
|
-
config.profile_examples = 2
|
41
|
-
|
42
|
-
config.order = :random
|
43
|
-
|
44
|
-
Kernel.srand config.seed
|
45
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe TTY::Spinner, 'hide_cursor' do
|
6
|
-
let(:output) { StringIO.new('', 'w+') }
|
7
|
-
|
8
|
-
it "hides cursor" do
|
9
|
-
spinner = TTY::Spinner.new(output: output, hide_cursor: true)
|
10
|
-
4.times { spinner.spin }
|
11
|
-
spinner.stop
|
12
|
-
output.rewind
|
13
|
-
expect(output.read).to eq([
|
14
|
-
"\e[?25l\e[1G|",
|
15
|
-
"\e[1G/",
|
16
|
-
"\e[1G-",
|
17
|
-
"\e[1G\\",
|
18
|
-
"\e[?25h"
|
19
|
-
].join)
|
20
|
-
end
|
21
|
-
end
|
data/spec/unit/new_spec.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe TTY::Spinner, '.new' do
|
6
|
-
|
7
|
-
it "creates spinner with default format" do
|
8
|
-
spinner = TTY::Spinner.new
|
9
|
-
expect(spinner.format).to eq(:spin_1)
|
10
|
-
end
|
11
|
-
|
12
|
-
it "allows to pass message in" do
|
13
|
-
spinner = TTY::Spinner.new("Initializing...")
|
14
|
-
expect(spinner.message).to eq("Initializing...")
|
15
|
-
end
|
16
|
-
|
17
|
-
it "allows to set default output" do
|
18
|
-
output = $stdout
|
19
|
-
spinner = TTY::Spinner.new(output: output)
|
20
|
-
expect(spinner.output).to eq(output)
|
21
|
-
end
|
22
|
-
end
|
data/spec/unit/reset_spec.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe TTY::Spinner, '.reset' do
|
6
|
-
let(:output) { StringIO.new('', 'w+') }
|
7
|
-
|
8
|
-
it "spins default frames" do
|
9
|
-
spinner = TTY::Spinner.new(output: output)
|
10
|
-
5.times do |n|
|
11
|
-
spinner.spin
|
12
|
-
spinner.reset if n == 2
|
13
|
-
end
|
14
|
-
output.rewind
|
15
|
-
expect(output.read).to eq([
|
16
|
-
"\e[1G|",
|
17
|
-
"\e[1G/",
|
18
|
-
"\e[1G-",
|
19
|
-
"\e[1G|",
|
20
|
-
"\e[1G/"
|
21
|
-
].join)
|
22
|
-
end
|
23
|
-
end
|
data/spec/unit/spin_spec.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe TTY::Spinner, '.spin' do
|
6
|
-
let(:output) { StringIO.new('', 'w+') }
|
7
|
-
|
8
|
-
it "spins default frames" do
|
9
|
-
spinner = TTY::Spinner.new(output: output)
|
10
|
-
5.times { spinner.spin }
|
11
|
-
output.rewind
|
12
|
-
expect(output.read).to eq([
|
13
|
-
"\e[1G|",
|
14
|
-
"\e[1G/",
|
15
|
-
"\e[1G-",
|
16
|
-
"\e[1G\\",
|
17
|
-
"\e[1G|"
|
18
|
-
].join)
|
19
|
-
end
|
20
|
-
|
21
|
-
it "spins chosen frame" do
|
22
|
-
spinner = TTY::Spinner.new(output: output, format: :spin_3)
|
23
|
-
5.times { spinner.spin }
|
24
|
-
output.rewind
|
25
|
-
expect(output.read).to eq([
|
26
|
-
"\e[1G◴",
|
27
|
-
"\e[1G◷",
|
28
|
-
"\e[1G◶",
|
29
|
-
"\e[1G◵",
|
30
|
-
"\e[1G◴"
|
31
|
-
].join)
|
32
|
-
end
|
33
|
-
|
34
|
-
it "spins with message" do
|
35
|
-
message = "Loading ... "
|
36
|
-
spinner = TTY::Spinner.new(message, output: output)
|
37
|
-
4.times { spinner.spin }
|
38
|
-
output.rewind
|
39
|
-
expect(output.read).to eq([
|
40
|
-
"\e[1G#{message}|",
|
41
|
-
"\e[1G#{message}/",
|
42
|
-
"\e[1G#{message}-",
|
43
|
-
"\e[1G#{message}\\"
|
44
|
-
].join)
|
45
|
-
end
|
46
|
-
end
|
data/spec/unit/stop_spec.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe TTY::Spinner, '.stop' do
|
6
|
-
let(:output) { StringIO.new('', 'w+') }
|
7
|
-
|
8
|
-
it "stops after 2 spins" do
|
9
|
-
spinner = TTY::Spinner.new(output: output)
|
10
|
-
5.times do |n|
|
11
|
-
spinner.spin
|
12
|
-
spinner.stop if n == 1
|
13
|
-
end
|
14
|
-
output.rewind
|
15
|
-
expect(output.read).to eq([
|
16
|
-
"\e[1G|",
|
17
|
-
"\e[1G/"
|
18
|
-
].join)
|
19
|
-
end
|
20
|
-
|
21
|
-
it "stops after 2 spins and prints stop message" do
|
22
|
-
spinner = TTY::Spinner.new(output: output)
|
23
|
-
5.times do |n|
|
24
|
-
spinner.spin
|
25
|
-
spinner.stop('Done!') if n == 1
|
26
|
-
end
|
27
|
-
output.rewind
|
28
|
-
expect(output.read).to eq([
|
29
|
-
"\e[1G|",
|
30
|
-
"\e[1G/",
|
31
|
-
"\e[1GDone!"
|
32
|
-
].join)
|
33
|
-
end
|
34
|
-
|
35
|
-
it "stops after 2 spins with message and prints stop message" do
|
36
|
-
message = "Loading ... "
|
37
|
-
spinner = TTY::Spinner.new(message, output: output)
|
38
|
-
5.times do |n|
|
39
|
-
spinner.spin
|
40
|
-
spinner.stop('Done!') if n == 1
|
41
|
-
end
|
42
|
-
output.rewind
|
43
|
-
expect(output.read).to eq([
|
44
|
-
"\e[1G#{message}|",
|
45
|
-
"\e[1G#{message}/",
|
46
|
-
"\e[1G#{message}Done!"
|
47
|
-
].join)
|
48
|
-
end
|
49
|
-
end
|
data/tasks/console.rake
DELETED
data/tasks/coverage.rake
DELETED
data/tasks/spec.rake
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
begin
|
4
|
-
require 'rspec/core/rake_task'
|
5
|
-
|
6
|
-
desc 'Run all specs'
|
7
|
-
RSpec::Core::RakeTask.new(:spec) do |task|
|
8
|
-
task.pattern = 'spec/{unit,integration}{,/*/**}/*_spec.rb'
|
9
|
-
end
|
10
|
-
|
11
|
-
namespace :spec do
|
12
|
-
desc 'Run unit specs'
|
13
|
-
RSpec::Core::RakeTask.new(:unit) do |task|
|
14
|
-
task.pattern = 'spec/unit{,/*/**}/*_spec.rb'
|
15
|
-
end
|
16
|
-
|
17
|
-
desc 'Run integration specs'
|
18
|
-
RSpec::Core::RakeTask.new(:integration) do |task|
|
19
|
-
task.pattern = 'spec/integration{,/*/**}/*_spec.rb'
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
rescue LoadError
|
24
|
-
%w[spec spec:unit spec:integration].each do |name|
|
25
|
-
task name do
|
26
|
-
$stderr.puts "In order to run #{name}, do `gem install rspec`"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
data/tty-spinner.gemspec
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'tty/spinner/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = "tty-spinner"
|
8
|
-
spec.version = TTY::Spinner::VERSION
|
9
|
-
spec.authors = ["Piotr Murach"]
|
10
|
-
spec.email = ["pmurach@gmail.com"]
|
11
|
-
spec.summary = %q{A terminal spinner for tasks that have non-deterministic time frame.}
|
12
|
-
spec.description = %q{A terminal spinner for tasks that have non-deterministic time frame.}
|
13
|
-
spec.homepage = "https://github.com/peter-murach/tty-spinner"
|
14
|
-
spec.license = "MIT"
|
15
|
-
|
16
|
-
spec.files = `git ls-files -z`.split("\x0")
|
17
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = ["lib"]
|
20
|
-
|
21
|
-
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
-
end
|