tty-spinner 0.2.0 → 0.3.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 +70 -19
- data/lib/tty/spinner.rb +98 -26
- data/lib/tty/spinner/version.rb +1 -1
- metadata +16 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b97fa767937b67b27ecbba2fb06a5b9f69c4d6b
|
4
|
+
data.tar.gz: 20dee6fe62ec0e5f431424f54a26848291773245
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bae4dcda349f6d01fe50d39dafbc1519a386e160e0d3568702c588648fcbdd2d673c2e06a8c6508c3b8623cf558ddbe76101c67384892e37d41e7e195f321458
|
7
|
+
data.tar.gz: e319158428db89baa850bbcd14dba26caa9ad9230377bb2f65cde8fdfd42c40b53eec9f205962421e8745a44f31d0406b8cd85f67a49f191aa55956d4b82fbfa
|
data/README.md
CHANGED
@@ -1,19 +1,22 @@
|
|
1
|
-
# TTY::Spinner
|
1
|
+
# TTY::Spinner [][gitter]
|
2
2
|
[][gem]
|
3
|
-
[][travis]
|
4
|
+
[][codeclimate]
|
5
|
+
[][coverage]
|
6
|
+
[][inchpages]
|
7
7
|
|
8
|
+
[gitter]: https://gitter.im/piotrmurach/tty
|
8
9
|
[gem]: http://badge.fury.io/rb/tty-spinner
|
9
|
-
[travis]: http://travis-ci.org/
|
10
|
-
[codeclimate]: https://codeclimate.com/github/
|
11
|
-
[coverage]: https://coveralls.io/r/
|
12
|
-
[inchpages]: http://inch-ci.org/github/
|
10
|
+
[travis]: http://travis-ci.org/piotrmurach/tty-spinner
|
11
|
+
[codeclimate]: https://codeclimate.com/github/piotrmurach/tty-spinner
|
12
|
+
[coverage]: https://coveralls.io/r/piotrmurach/tty-spinner
|
13
|
+
[inchpages]: http://inch-ci.org/github/piotrmurach/tty-spinner
|
13
14
|
|
14
15
|
> A terminal spinner for tasks that have non-deterministic time frame.
|
15
16
|
|
16
|
-
**TTY::Spinner** provides independent spinner component for [TTY](https://github.com/
|
17
|
+
**TTY::Spinner** provides independent spinner component for [TTY](https://github.com/piotrmurach/tty) toolkit.
|
18
|
+
|
19
|
+

|
17
20
|
|
18
21
|
## Installation
|
19
22
|
|
@@ -38,8 +41,10 @@ Or install it yourself as:
|
|
38
41
|
* [2.1 spin](#21-spin)
|
39
42
|
* [2.2 start](#22-start)
|
40
43
|
* [2.3 stop](#23-stop)
|
41
|
-
|
42
|
-
|
44
|
+
* [2.3.1 success](#231-success)
|
45
|
+
* [2.3.2 error](#232-error)
|
46
|
+
* [2.4 run](#24-run)
|
47
|
+
* [2.5 update](#25-update)
|
43
48
|
* [2.6 reset](#26-reset)
|
44
49
|
* [2.7 join](#27-join)
|
45
50
|
* [3. Configuration](#3-configuration)
|
@@ -87,13 +92,21 @@ and when finished output:
|
|
87
92
|
_ Loading ... Done!
|
88
93
|
```
|
89
94
|
|
90
|
-
For more usage examples please see [examples directory](https://github.com/
|
95
|
+
For more usage examples please see [examples directory](https://github.com/piotrmurach/tty-spinner/tree/master/examples)
|
91
96
|
|
92
97
|
## 2. API
|
93
98
|
|
94
99
|
### 2.1 spin
|
95
100
|
|
96
|
-
The main workhorse of the spinner is the `spin` method.
|
101
|
+
The main workhorse of the spinner is the `spin` method.
|
102
|
+
|
103
|
+
Looping over `spin` method will animate a given spinner.
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
loop do
|
107
|
+
spinner.spin
|
108
|
+
end
|
109
|
+
```
|
97
110
|
|
98
111
|
### 2.2 start
|
99
112
|
|
@@ -103,7 +116,7 @@ To perform automatic spinning call `start` method like so:
|
|
103
116
|
spinner.start
|
104
117
|
```
|
105
118
|
|
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/
|
119
|
+
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/piotrmurach/tty-spinner/blob/master/lib/tty/spinner/formats.rb)).
|
107
120
|
|
108
121
|
### 2.3 stop
|
109
122
|
|
@@ -119,7 +132,7 @@ You can further pass a message to print when animation is finished.
|
|
119
132
|
spinner.stop('Done!')
|
120
133
|
```
|
121
134
|
|
122
|
-
|
135
|
+
#### 2.3.1 success
|
123
136
|
|
124
137
|
Use `success` call to stop the spinning animation and replace the spinning symbol with checkmark character to indicate successful completion.
|
125
138
|
|
@@ -134,7 +147,7 @@ This will produce:
|
|
134
147
|
[✔] Task name (successful)
|
135
148
|
```
|
136
149
|
|
137
|
-
|
150
|
+
#### 2.3.2 error
|
138
151
|
|
139
152
|
Use `error` call to stop the spining animation and replace the spinning symbol with cross character to indicate error completion.
|
140
153
|
|
@@ -149,6 +162,44 @@ This will produce:
|
|
149
162
|
[✖] Task name (error)
|
150
163
|
```
|
151
164
|
|
165
|
+
### 2.4 run
|
166
|
+
|
167
|
+
Use `run` with a code block that will automatically display spinning animation while the block executes and finish animation when the block terminates. Optionally you can provide a stop message to display when animation is finished.
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
spinner.run('Done!') { ... }
|
171
|
+
```
|
172
|
+
|
173
|
+
### 2.5 update
|
174
|
+
|
175
|
+
Use `update` call to dynamically change label name(s).
|
176
|
+
|
177
|
+
Provide an arbitrary token name(s) in the message string, such as `:title`
|
178
|
+
|
179
|
+
```ruby
|
180
|
+
spinner = TTY::Spinner.new("[:spinner] :title")
|
181
|
+
```
|
182
|
+
|
183
|
+
and then pass token name and value:
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
spinner.update(title: 'Downloading file1')
|
187
|
+
```
|
188
|
+
|
189
|
+
next start animation:
|
190
|
+
|
191
|
+
```ruby
|
192
|
+
spinner.run { ... }
|
193
|
+
# => | Downloading file1
|
194
|
+
```
|
195
|
+
|
196
|
+
Once animation finishes you can kick start another one with a different name:
|
197
|
+
|
198
|
+
```ruby
|
199
|
+
spinner.update(title: 'Downloading file2')
|
200
|
+
spinner.run { ... }
|
201
|
+
```
|
202
|
+
|
152
203
|
### 2.6 reset
|
153
204
|
|
154
205
|
In order to reset the spinner to its initial frame do:
|
@@ -183,7 +234,7 @@ Use one of the predefined spinner styles by passing the formatting token `:forma
|
|
183
234
|
spinner = TTY::Spinner.new(format: :pulse_2)
|
184
235
|
```
|
185
236
|
|
186
|
-
All spinner formats that **TTY::Spinner** accepts are defined in [/lib/tty/spinner/formats.rb](https://github.com/
|
237
|
+
All spinner formats that **TTY::Spinner** accepts are defined in [/lib/tty/spinner/formats.rb](https://github.com/piotrmurach/tty-spinner/blob/master/lib/tty/spinner/formats.rb)
|
187
238
|
|
188
239
|
If you wish to see all available formats in action run the `formats.rb` file in examples folder like so:
|
189
240
|
|
@@ -279,7 +330,7 @@ spinner.on(:error) { ... }
|
|
279
330
|
|
280
331
|
## Contributing
|
281
332
|
|
282
|
-
1. Fork it ( https://github.com/
|
333
|
+
1. Fork it ( https://github.com/piotrmurach/tty-spinner/fork )
|
283
334
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
284
335
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
285
336
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/lib/tty/spinner.rb
CHANGED
@@ -10,6 +10,9 @@ module TTY
|
|
10
10
|
class Spinner
|
11
11
|
include Formats
|
12
12
|
|
13
|
+
# @raised when attempting to join dead thread
|
14
|
+
NotSpinningError = Class.new(StandardError)
|
15
|
+
|
13
16
|
ECMA_ESC = "\x1b".freeze
|
14
17
|
ECMA_CSI = "\x1b[".freeze
|
15
18
|
ECMA_CHA = 'G'.freeze
|
@@ -19,7 +22,7 @@ module TTY
|
|
19
22
|
DEC_SET = 'h'.freeze
|
20
23
|
DEC_TCEM = '?25'.freeze
|
21
24
|
|
22
|
-
MATCHER = /:spinner
|
25
|
+
MATCHER = /:spinner/
|
23
26
|
TICK = '✔'.freeze
|
24
27
|
CROSS = '✖'.freeze
|
25
28
|
|
@@ -50,6 +53,14 @@ module TTY
|
|
50
53
|
# @api public
|
51
54
|
attr_reader :message
|
52
55
|
|
56
|
+
# Tokens for the message
|
57
|
+
#
|
58
|
+
# @return [Hash[Symbol, Object]]
|
59
|
+
# the current tokens
|
60
|
+
#
|
61
|
+
# @api public
|
62
|
+
attr_reader :tokens
|
63
|
+
|
53
64
|
# Initialize a spinner
|
54
65
|
#
|
55
66
|
# @example
|
@@ -74,23 +85,27 @@ module TTY
|
|
74
85
|
def initialize(*args)
|
75
86
|
options = args.last.is_a?(::Hash) ? args.pop : {}
|
76
87
|
@message = args.empty? ? ':spinner' : args.pop
|
88
|
+
@tokens = {}
|
77
89
|
|
78
90
|
@format = options.fetch(:format) { :classic }
|
79
91
|
@output = options.fetch(:output) { $stderr }
|
80
92
|
@hide_cursor = options.fetch(:hide_cursor) { false }
|
81
|
-
@frames = options.fetch(:frames)
|
82
|
-
fetch_format(@format.to_sym, :frames)
|
93
|
+
@frames = options.fetch(:frames) do
|
94
|
+
fetch_format(@format.to_sym, :frames)
|
95
|
+
end
|
83
96
|
@clear = options.fetch(:clear) { false }
|
84
97
|
@success_mark= options.fetch(:success_mark) { TICK }
|
85
98
|
@error_mark = options.fetch(:error_mark) { CROSS }
|
86
|
-
@interval = options.fetch(:interval)
|
87
|
-
fetch_format(@format.to_sym, :interval)
|
99
|
+
@interval = options.fetch(:interval) do
|
100
|
+
fetch_format(@format.to_sym, :interval)
|
101
|
+
end
|
88
102
|
|
89
103
|
@callbacks = Hash.new { |h, k| h[k] = [] }
|
90
104
|
@length = @frames.length
|
91
105
|
@current = 0
|
92
106
|
@done = false
|
93
107
|
@state = :stopped
|
108
|
+
@thread = nil
|
94
109
|
end
|
95
110
|
|
96
111
|
def spinning?
|
@@ -113,22 +128,41 @@ module TTY
|
|
113
128
|
self
|
114
129
|
end
|
115
130
|
|
116
|
-
# Start automatic spinning
|
117
|
-
#
|
131
|
+
# Start automatic spinning animation
|
118
132
|
#
|
119
133
|
# @api public
|
120
134
|
def start
|
121
135
|
@started_at = Time.now
|
136
|
+
@done = false
|
122
137
|
sleep_time = 1.0 / @interval
|
123
138
|
|
124
139
|
@thread = Thread.new do
|
125
|
-
while @started_at
|
140
|
+
while @started_at
|
126
141
|
spin
|
127
142
|
sleep(sleep_time)
|
128
143
|
end
|
129
144
|
end
|
130
145
|
end
|
131
146
|
|
147
|
+
# Run spinner while executing job
|
148
|
+
#
|
149
|
+
# @param [String] stop_message
|
150
|
+
# the message displayed when block is finished
|
151
|
+
#
|
152
|
+
# @yield automatically animate and finish spinner
|
153
|
+
#
|
154
|
+
# @example
|
155
|
+
# spinner.run('Migrated DB') { ... }
|
156
|
+
#
|
157
|
+
# @api public
|
158
|
+
def run(stop_message = nil, &block)
|
159
|
+
start
|
160
|
+
@work = Thread.new(&block)
|
161
|
+
@work.join
|
162
|
+
ensure
|
163
|
+
stop(stop_message)
|
164
|
+
end
|
165
|
+
|
132
166
|
# Duration of the spinning animation
|
133
167
|
#
|
134
168
|
# @return [Numeric]
|
@@ -145,9 +179,9 @@ module TTY
|
|
145
179
|
#
|
146
180
|
# @api public
|
147
181
|
def join(timeout = nil)
|
148
|
-
|
149
|
-
|
150
|
-
|
182
|
+
unless @thread
|
183
|
+
raise(NotSpinningError, 'Cannot join spinner that is not running')
|
184
|
+
end
|
151
185
|
|
152
186
|
timeout ? @thread.join(timeout) : @thread.join
|
153
187
|
end
|
@@ -173,6 +207,7 @@ module TTY
|
|
173
207
|
end
|
174
208
|
|
175
209
|
data = message.gsub(MATCHER, @frames[@current])
|
210
|
+
data = replace_tokens(data)
|
176
211
|
write(data, true)
|
177
212
|
@current = (@current + 1) % @length
|
178
213
|
@state = :spinning
|
@@ -186,30 +221,42 @@ module TTY
|
|
186
221
|
#
|
187
222
|
# @api public
|
188
223
|
def stop(stop_message = '')
|
189
|
-
if @
|
224
|
+
return if @done
|
225
|
+
|
226
|
+
if @hide_cursor
|
190
227
|
write(ECMA_CSI + DEC_TCEM + DEC_SET, false)
|
191
228
|
end
|
192
|
-
@done = true
|
193
|
-
@started_at = nil
|
194
|
-
emit(:done)
|
195
229
|
return clear_line if @clear
|
196
230
|
|
197
|
-
|
198
|
-
|
199
|
-
elsif error?
|
200
|
-
@error_mark
|
201
|
-
else
|
202
|
-
@frames[@current - 1]
|
203
|
-
end
|
204
|
-
data = message.gsub(MATCHER, char)
|
205
|
-
|
231
|
+
data = message.gsub(MATCHER, next_char)
|
232
|
+
data = replace_tokens(data)
|
206
233
|
if !stop_message.empty?
|
207
234
|
data << ' ' + stop_message
|
208
235
|
end
|
209
236
|
|
210
237
|
write(data, true)
|
211
238
|
write("\n", false) unless @clear
|
212
|
-
|
239
|
+
ensure
|
240
|
+
@state = :stopped
|
241
|
+
@done = true
|
242
|
+
@started_at = nil
|
243
|
+
emit(:done)
|
244
|
+
kill
|
245
|
+
end
|
246
|
+
|
247
|
+
# Retrieve next character
|
248
|
+
#
|
249
|
+
# @return [String]
|
250
|
+
#
|
251
|
+
# @api private
|
252
|
+
def next_char
|
253
|
+
if success?
|
254
|
+
@success_mark
|
255
|
+
elsif error?
|
256
|
+
@error_mark
|
257
|
+
else
|
258
|
+
@frames[@current - 1]
|
259
|
+
end
|
213
260
|
end
|
214
261
|
|
215
262
|
# Finish spinning and set state to :success
|
@@ -237,12 +284,21 @@ module TTY
|
|
237
284
|
output.print(ECMA_CSI + '0m' + ECMA_CSI + '1000D' + ECMA_CSI + ECMA_CLR)
|
238
285
|
end
|
239
286
|
|
287
|
+
# Update string formatting tokens
|
288
|
+
#
|
289
|
+
# @param [Hash[Symbol]] tokens
|
290
|
+
# the tokens used in formatting string
|
291
|
+
#
|
292
|
+
# @api public
|
293
|
+
def update(tokens)
|
294
|
+
@tokens.merge!(tokens)
|
295
|
+
end
|
296
|
+
|
240
297
|
# Reset the spinner to initial frame
|
241
298
|
#
|
242
299
|
# @api public
|
243
300
|
def reset
|
244
301
|
@current = 0
|
245
|
-
@state = :stopped
|
246
302
|
end
|
247
303
|
|
248
304
|
private
|
@@ -282,5 +338,21 @@ module TTY
|
|
282
338
|
raise ArgumentError, "Unknown format token `:#{token}`"
|
283
339
|
end
|
284
340
|
end
|
341
|
+
|
342
|
+
# Replace any token inside string
|
343
|
+
#
|
344
|
+
# @param [String] string
|
345
|
+
# the string containing tokens
|
346
|
+
#
|
347
|
+
# @return [String]
|
348
|
+
#
|
349
|
+
# @api private
|
350
|
+
def replace_tokens(string)
|
351
|
+
data = string.dup
|
352
|
+
@tokens.each do |name, val|
|
353
|
+
data.gsub!(/\:#{name}/, val)
|
354
|
+
end
|
355
|
+
data
|
356
|
+
end
|
285
357
|
end # Spinner
|
286
358
|
end # TTY
|
data/lib/tty/spinner/version.rb
CHANGED
metadata
CHANGED
@@ -1,47 +1,47 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tty-spinner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.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: 2016-
|
11
|
+
date: 2016-07-14 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
19
|
version: 1.5.0
|
20
|
-
- - <
|
20
|
+
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: '2.0'
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 1.5.0
|
30
|
-
- - <
|
30
|
+
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '2.0'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: rake
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
|
-
- -
|
37
|
+
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
39
|
version: '0'
|
40
40
|
type: :development
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
|
-
- -
|
44
|
+
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '0'
|
47
47
|
description: A terminal spinner for tasks that have non-deterministic time frame.
|
@@ -51,13 +51,13 @@ executables: []
|
|
51
51
|
extensions: []
|
52
52
|
extra_rdoc_files: []
|
53
53
|
files:
|
54
|
-
- lib/tty/spinner/formats.rb
|
55
|
-
- lib/tty/spinner/version.rb
|
56
|
-
- lib/tty/spinner.rb
|
57
|
-
- lib/tty-spinner.rb
|
58
54
|
- LICENSE.txt
|
59
55
|
- README.md
|
60
|
-
|
56
|
+
- lib/tty-spinner.rb
|
57
|
+
- lib/tty/spinner.rb
|
58
|
+
- lib/tty/spinner/formats.rb
|
59
|
+
- lib/tty/spinner/version.rb
|
60
|
+
homepage: https://github.com/piotrmurach/tty-spinner
|
61
61
|
licenses:
|
62
62
|
- MIT
|
63
63
|
metadata: {}
|
@@ -67,17 +67,17 @@ require_paths:
|
|
67
67
|
- lib
|
68
68
|
required_ruby_version: !ruby/object:Gem::Requirement
|
69
69
|
requirements:
|
70
|
-
- -
|
70
|
+
- - ">="
|
71
71
|
- !ruby/object:Gem::Version
|
72
72
|
version: '0'
|
73
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
74
|
requirements:
|
75
|
-
- -
|
75
|
+
- - ">="
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '0'
|
78
78
|
requirements: []
|
79
79
|
rubyforge_project:
|
80
|
-
rubygems_version: 2.
|
80
|
+
rubygems_version: 2.5.1
|
81
81
|
signing_key:
|
82
82
|
specification_version: 4
|
83
83
|
summary: A terminal spinner for tasks that have non-deterministic time frame.
|