whirly 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 09dc6464dd66bfd1b0efbfb714f46c772e455755
4
+ data.tar.gz: 6cbb8096a92177335fa21c0e9ae6e84d3b114b64
5
+ SHA512:
6
+ metadata.gz: fb4ef9f577068ecfe20eadf4b4632440a1babf4d5a3d3007240590ca37810c15c8d018d52d85344df3c026786c7a80b167b38d66e63dd5dc4b803d1ee81ce4a4
7
+ data.tar.gz: 0ab11d2404dd4326f0af3c87d26f1ce02396ad566bc95a29ff15b6de43912867aca5c8f63959bab4531b0a335c913b38f9914eaa9f05a810396aefa430c33523
data/.README.md.swp ADDED
Binary file
data/.euruko.rb.swp ADDED
Binary file
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ Gemfile.lock
2
+ /pkg
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "data/external/cli-spinners"]
2
+ path = data/external/cli-spinners
3
+ url = https://github.com/sindresorhus/cli-spinners.git
data/.travis.yml ADDED
@@ -0,0 +1,20 @@
1
+ sudo: false
2
+ language: ruby
3
+
4
+ script: bundle exec ruby spec/whirly_spec.rb
5
+
6
+ rvm:
7
+ - 2.3.0
8
+ - 2.2
9
+ - 2.1
10
+ - 2.0
11
+ - ruby-head
12
+ - rbx-2
13
+ - jruby-head
14
+ - jruby-9000
15
+
16
+ cache:
17
+ - bundler
18
+
19
+ # matrix:
20
+ # fast_finish: true
data/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ ## CHANGELOG
2
+
3
+ ### 0.1.0
4
+
5
+ * Inital release
6
+
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at opensource@janlelis.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'minitest'
data/MIT-LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2016 Jan Lelis, mail@janlelis.de
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # Whirly [![[version]](https://badge.fury.io/rb/whirly.svg)](http://badge.fury.io/rb/whirly) [![[travis]](https://travis-ci.org/janlelis/whirly.png)](https://travis-ci.org/janlelis/whirly)
2
+
3
+ Whirly terminal spinner for Ruby, influenced by [ora](https://github.com/sindresorhus/ora), includes [cli-spinners](https://github.com/sindresorhus/cli-spinners).
4
+
5
+ ALPHA RELEASE FOR EURUKO
6
+
7
+ ## Setup
8
+
9
+ Add to your `Gemfile`:
10
+
11
+ ```ruby
12
+ gem 'whirly'
13
+ gem 'paint' # makes whirly colorful (recommended)
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ ### Basic Usage
19
+
20
+ ```ruby
21
+ Whirly.start do
22
+ Whirly.status = "Working on it…"
23
+ sleep 3
24
+ Whirly.status = "Almoste done…
25
+ sleep 2
26
+ end
27
+ ```
28
+
29
+ ### Non-Block Syntax, World Spinner
30
+
31
+ ```ruby
32
+ Whirly.start spinner: "world"
33
+ Whirly.status = "Working on it…"
34
+ sleep 3
35
+ Whirly.status = "Almoste done…"
36
+ Whirly.stop
37
+ ```
38
+
39
+ ### No Colors, Pong Spinner, Initial Status
40
+
41
+ ```ruby
42
+ Whirly.start spinner: "pong", use_color: false, status: "The Game of Pong" do
43
+ sleep 10
44
+ end
45
+ ```
46
+
47
+ ### Slower Interval, Don't Hide Cursor
48
+
49
+ ```ruby
50
+ Whirly.start spinner: "clock", interval: 1000, hide_cursor: false do
51
+ sleep 5
52
+ end
53
+ ```
54
+
55
+ ## Included Spinners & Custom Spinners
56
+
57
+ - See `data/cursors.json`
58
+ - Spinners are either an Array of frames or an enumerator [...]
59
+ - Extra fun spinners :random_character, :random_emoticon (SOON)
60
+
61
+ ## Remarks, Troubleshooting, Caveats
62
+
63
+ - Interval is milliseconds, but don't rely on exact timing
64
+ - Will not do anything if stream is not a real console
65
+ - Colors not working? Be sure to include the [paint](https://github.com/janlelis/paint/) gem
66
+ - Don't set very short intervals (or it might affect performance substantly)
67
+
68
+ ## MIT License
69
+
70
+ - Copyright (C) 2016 Jan Lelis <http://janlelis.com>. Released under the MIT license.
71
+ - Contains data from cli-spinners: MIT License, Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ # # #
2
+ # Get gemspec info
3
+
4
+ gemspec_file = Dir['*.gemspec'].first
5
+ gemspec = eval File.read(gemspec_file), binding, gemspec_file
6
+ info = "#{gemspec.name} | #{gemspec.version} | " \
7
+ "#{gemspec.runtime_dependencies.size} dependencies | " \
8
+ "#{gemspec.files.size} files"
9
+
10
+
11
+ # # #
12
+ # Gem build and install task
13
+
14
+ desc info
15
+ task :gem do
16
+ puts info + "\n\n"
17
+ print " "; sh "gem build #{gemspec_file}"
18
+ FileUtils.mkdir_p 'pkg'
19
+ FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", 'pkg'
20
+ puts; sh %{gem install --no-document pkg/#{gemspec.name}-#{gemspec.version}.gem}
21
+ end
22
+
23
+
24
+ # # #
25
+ # Start an IRB session with the gem loaded
26
+
27
+ desc "#{gemspec.name} | IRB"
28
+ task :irb do
29
+ sh "irb -I ./lib -r #{gemspec.name.gsub '-','/'}"
30
+ end
31
+
32
+
33
+ # # #
34
+ # Update spinners
35
+ desc "Update spinners"
36
+ task :update_spinners do
37
+ sh "git submodule update"
38
+ cp "data/external/cli-spinners/spinners.json", "data/spinners.json"
39
+ end
@@ -0,0 +1,731 @@
1
+ {
2
+ "dots": {
3
+ "interval": 80,
4
+ "frames": [
5
+ "⠋",
6
+ "⠙",
7
+ "⠹",
8
+ "⠸",
9
+ "⠼",
10
+ "⠴",
11
+ "⠦",
12
+ "⠧",
13
+ "⠇",
14
+ "⠏"
15
+ ]
16
+ },
17
+ "dots2": {
18
+ "interval": 80,
19
+ "frames": [
20
+ "⣾",
21
+ "⣽",
22
+ "⣻",
23
+ "⢿",
24
+ "⡿",
25
+ "⣟",
26
+ "⣯",
27
+ "⣷"
28
+ ]
29
+ },
30
+ "dots3": {
31
+ "interval": 80,
32
+ "frames": [
33
+ "⠋",
34
+ "⠙",
35
+ "⠚",
36
+ "⠞",
37
+ "⠖",
38
+ "⠦",
39
+ "⠴",
40
+ "⠲",
41
+ "⠳",
42
+ "⠓"
43
+ ]
44
+ },
45
+ "dots4": {
46
+ "interval": 80,
47
+ "frames": [
48
+ "⠄",
49
+ "⠆",
50
+ "⠇",
51
+ "⠋",
52
+ "⠙",
53
+ "⠸",
54
+ "⠰",
55
+ "⠠",
56
+ "⠰",
57
+ "⠸",
58
+ "⠙",
59
+ "⠋",
60
+ "⠇",
61
+ "⠆"
62
+ ]
63
+ },
64
+ "dots5": {
65
+ "interval": 80,
66
+ "frames": [
67
+ "⠋",
68
+ "⠙",
69
+ "⠚",
70
+ "⠒",
71
+ "⠂",
72
+ "⠂",
73
+ "⠒",
74
+ "⠲",
75
+ "⠴",
76
+ "⠦",
77
+ "⠖",
78
+ "⠒",
79
+ "⠐",
80
+ "⠐",
81
+ "⠒",
82
+ "⠓",
83
+ "⠋"
84
+ ]
85
+ },
86
+ "dots6": {
87
+ "interval": 80,
88
+ "frames": [
89
+ "⠁",
90
+ "⠉",
91
+ "⠙",
92
+ "⠚",
93
+ "⠒",
94
+ "⠂",
95
+ "⠂",
96
+ "⠒",
97
+ "⠲",
98
+ "⠴",
99
+ "⠤",
100
+ "⠄",
101
+ "⠄",
102
+ "⠤",
103
+ "⠴",
104
+ "⠲",
105
+ "⠒",
106
+ "⠂",
107
+ "⠂",
108
+ "⠒",
109
+ "⠚",
110
+ "⠙",
111
+ "⠉",
112
+ "⠁"
113
+ ]
114
+ },
115
+ "dots7": {
116
+ "interval": 80,
117
+ "frames": [
118
+ "⠈",
119
+ "⠉",
120
+ "⠋",
121
+ "⠓",
122
+ "⠒",
123
+ "⠐",
124
+ "⠐",
125
+ "⠒",
126
+ "⠖",
127
+ "⠦",
128
+ "⠤",
129
+ "⠠",
130
+ "⠠",
131
+ "⠤",
132
+ "⠦",
133
+ "⠖",
134
+ "⠒",
135
+ "⠐",
136
+ "⠐",
137
+ "⠒",
138
+ "⠓",
139
+ "⠋",
140
+ "⠉",
141
+ "⠈"
142
+ ]
143
+ },
144
+ "dots8": {
145
+ "interval": 80,
146
+ "frames": [
147
+ "⠁",
148
+ "⠁",
149
+ "⠉",
150
+ "⠙",
151
+ "⠚",
152
+ "⠒",
153
+ "⠂",
154
+ "⠂",
155
+ "⠒",
156
+ "⠲",
157
+ "⠴",
158
+ "⠤",
159
+ "⠄",
160
+ "⠄",
161
+ "⠤",
162
+ "⠠",
163
+ "⠠",
164
+ "⠤",
165
+ "⠦",
166
+ "⠖",
167
+ "⠒",
168
+ "⠐",
169
+ "⠐",
170
+ "⠒",
171
+ "⠓",
172
+ "⠋",
173
+ "⠉",
174
+ "⠈",
175
+ "⠈"
176
+ ]
177
+ },
178
+ "dots9": {
179
+ "interval": 80,
180
+ "frames": [
181
+ "⢹",
182
+ "⢺",
183
+ "⢼",
184
+ "⣸",
185
+ "⣇",
186
+ "⡧",
187
+ "⡗",
188
+ "⡏"
189
+ ]
190
+ },
191
+ "dots10": {
192
+ "interval": 80,
193
+ "frames": [
194
+ "⢄",
195
+ "⢂",
196
+ "⢁",
197
+ "⡁",
198
+ "⡈",
199
+ "⡐",
200
+ "⡠"
201
+ ]
202
+ },
203
+ "dots11": {
204
+ "interval": 100,
205
+ "frames": [
206
+ "⠁",
207
+ "⠂",
208
+ "⠄",
209
+ "⡀",
210
+ "⢀",
211
+ "⠠",
212
+ "⠐",
213
+ "⠈"
214
+ ]
215
+ },
216
+ "line": {
217
+ "interval": 130,
218
+ "frames": [
219
+ "-",
220
+ "\\",
221
+ "|",
222
+ "/"
223
+ ]
224
+ },
225
+ "line2": {
226
+ "interval": 100,
227
+ "frames": [
228
+ "⠂",
229
+ "-",
230
+ "–",
231
+ "—",
232
+ "–",
233
+ "-"
234
+ ]
235
+ },
236
+ "pipe": {
237
+ "interval": 100,
238
+ "frames": [
239
+ "┤",
240
+ "┘",
241
+ "┴",
242
+ "└",
243
+ "├",
244
+ "┌",
245
+ "┬",
246
+ "┐"
247
+ ]
248
+ },
249
+ "simpleDots": {
250
+ "interval": 400,
251
+ "frames": [
252
+ ". ",
253
+ ".. ",
254
+ "...",
255
+ " "
256
+ ]
257
+ },
258
+ "simpleDotsScrolling": {
259
+ "interval": 200,
260
+ "frames": [
261
+ ". ",
262
+ ".. ",
263
+ "...",
264
+ " ..",
265
+ " .",
266
+ " "
267
+ ]
268
+ },
269
+ "star": {
270
+ "interval": 70,
271
+ "frames": [
272
+ "✶",
273
+ "✸",
274
+ "✹",
275
+ "✺",
276
+ "✹",
277
+ "✷"
278
+ ]
279
+ },
280
+ "star2": {
281
+ "interval": 80,
282
+ "frames": [
283
+ "+",
284
+ "x",
285
+ "*"
286
+ ]
287
+ },
288
+ "flip": {
289
+ "interval": 70,
290
+ "frames": [
291
+ "_",
292
+ "_",
293
+ "_",
294
+ "-",
295
+ "`",
296
+ "`",
297
+ "'",
298
+ "´",
299
+ "-",
300
+ "_",
301
+ "_",
302
+ "_"
303
+ ]
304
+ },
305
+ "hamburger": {
306
+ "interval": 100,
307
+ "frames": [
308
+ "☱",
309
+ "☲",
310
+ "☴"
311
+ ]
312
+ },
313
+ "growVertical": {
314
+ "interval": 120,
315
+ "frames": [
316
+ "▁",
317
+ "▃",
318
+ "▄",
319
+ "▅",
320
+ "▆",
321
+ "▇",
322
+ "▆",
323
+ "▅",
324
+ "▄",
325
+ "▃"
326
+ ]
327
+ },
328
+ "growHorizontal": {
329
+ "interval": 120,
330
+ "frames": [
331
+ "▏",
332
+ "▎",
333
+ "▍",
334
+ "▌",
335
+ "▋",
336
+ "▊",
337
+ "▉",
338
+ "▊",
339
+ "▋",
340
+ "▌",
341
+ "▍",
342
+ "▎"
343
+ ]
344
+ },
345
+ "balloon": {
346
+ "interval": 140,
347
+ "frames": [
348
+ " ",
349
+ ".",
350
+ "o",
351
+ "O",
352
+ "@",
353
+ "*",
354
+ " "
355
+ ]
356
+ },
357
+ "balloon2": {
358
+ "interval": 120,
359
+ "frames": [
360
+ ".",
361
+ "o",
362
+ "O",
363
+ "°",
364
+ "O",
365
+ "o",
366
+ "."
367
+ ]
368
+ },
369
+ "noise": {
370
+ "interval": 100,
371
+ "frames": [
372
+ "▓",
373
+ "▒",
374
+ "░"
375
+ ]
376
+ },
377
+ "bounce": {
378
+ "interval": 120,
379
+ "frames": [
380
+ "⠁",
381
+ "⠂",
382
+ "⠄",
383
+ "⠂"
384
+ ]
385
+ },
386
+ "boxBounce": {
387
+ "interval": 120,
388
+ "frames": [
389
+ "▖",
390
+ "▘",
391
+ "▝",
392
+ "▗"
393
+ ]
394
+ },
395
+ "boxBounce2": {
396
+ "interval": 100,
397
+ "frames": [
398
+ "▌",
399
+ "▀",
400
+ "▐",
401
+ "▄"
402
+ ]
403
+ },
404
+ "triangle": {
405
+ "interval": 50,
406
+ "frames": [
407
+ "◢",
408
+ "◣",
409
+ "◤",
410
+ "◥"
411
+ ]
412
+ },
413
+ "arc": {
414
+ "interval": 100,
415
+ "frames": [
416
+ "◜",
417
+ "◠",
418
+ "◝",
419
+ "◞",
420
+ "◡",
421
+ "◟"
422
+ ]
423
+ },
424
+ "circle": {
425
+ "interval": 120,
426
+ "frames": [
427
+ "◡",
428
+ "⊙",
429
+ "◠"
430
+ ]
431
+ },
432
+ "squareCorners": {
433
+ "interval": 180,
434
+ "frames": [
435
+ "◰",
436
+ "◳",
437
+ "◲",
438
+ "◱"
439
+ ]
440
+ },
441
+ "circleQuarters": {
442
+ "interval": 120,
443
+ "frames": [
444
+ "◴",
445
+ "◷",
446
+ "◶",
447
+ "◵"
448
+ ]
449
+ },
450
+ "circleHalves": {
451
+ "interval": 50,
452
+ "frames": [
453
+ "◐",
454
+ "◓",
455
+ "◑",
456
+ "◒"
457
+ ]
458
+ },
459
+ "squish": {
460
+ "interval": 100,
461
+ "frames": [
462
+ "╫",
463
+ "╪"
464
+ ]
465
+ },
466
+ "toggle": {
467
+ "interval": 250,
468
+ "frames": [
469
+ "⊶",
470
+ "⊷"
471
+ ]
472
+ },
473
+ "toggle2": {
474
+ "interval": 80,
475
+ "frames": [
476
+ "▫",
477
+ "▪"
478
+ ]
479
+ },
480
+ "toggle3": {
481
+ "interval": 120,
482
+ "frames": [
483
+ "□",
484
+ "■"
485
+ ]
486
+ },
487
+ "toggle4": {
488
+ "interval": 100,
489
+ "frames": [
490
+ "■",
491
+ "□",
492
+ "▪",
493
+ "▫"
494
+ ]
495
+ },
496
+ "toggle5": {
497
+ "interval": 100,
498
+ "frames": [
499
+ "▮",
500
+ "▯"
501
+ ]
502
+ },
503
+ "toggle6": {
504
+ "interval": 300,
505
+ "frames": [
506
+ "ဝ",
507
+ "၀"
508
+ ]
509
+ },
510
+ "toggle7": {
511
+ "interval": 80,
512
+ "frames": [
513
+ "⦾",
514
+ "⦿"
515
+ ]
516
+ },
517
+ "toggle8": {
518
+ "interval": 100,
519
+ "frames": [
520
+ "◍",
521
+ "◌"
522
+ ]
523
+ },
524
+ "toggle9": {
525
+ "interval": 100,
526
+ "frames": [
527
+ "◉",
528
+ "◎"
529
+ ]
530
+ },
531
+ "toggle10": {
532
+ "interval": 100,
533
+ "frames": [
534
+ "㊂",
535
+ "㊀",
536
+ "㊁"
537
+ ]
538
+ },
539
+ "toggle11": {
540
+ "interval": 50,
541
+ "frames": [
542
+ "⧇",
543
+ "⧆"
544
+ ]
545
+ },
546
+ "toggle12": {
547
+ "interval": 120,
548
+ "frames": [
549
+ "☗",
550
+ "☖"
551
+ ]
552
+ },
553
+ "toggle13": {
554
+ "interval": 80,
555
+ "frames": [
556
+ "=",
557
+ "*",
558
+ "-"
559
+ ]
560
+ },
561
+ "arrow": {
562
+ "interval": 100,
563
+ "frames": [
564
+ "←",
565
+ "↖",
566
+ "↑",
567
+ "↗",
568
+ "→",
569
+ "↘",
570
+ "↓",
571
+ "↙"
572
+ ]
573
+ },
574
+ "arrow2": {
575
+ "interval": 80,
576
+ "frames": [
577
+ "⬆️ ",
578
+ "↗️ ",
579
+ "➡️ ",
580
+ "↘️ ",
581
+ "⬇️ ",
582
+ "↙️ ",
583
+ "⬅️ ",
584
+ "↖️ "
585
+ ]
586
+ },
587
+ "arrow3": {
588
+ "interval": 120,
589
+ "frames": [
590
+ "▹▹▹▹▹",
591
+ "▸▹▹▹▹",
592
+ "▹▸▹▹▹",
593
+ "▹▹▸▹▹",
594
+ "▹▹▹▸▹",
595
+ "▹▹▹▹▸"
596
+ ]
597
+ },
598
+ "bouncingBar": {
599
+ "interval": 80,
600
+ "frames": [
601
+ "[ ]",
602
+ "[ =]",
603
+ "[ ==]",
604
+ "[ ===]",
605
+ "[====]",
606
+ "[=== ]",
607
+ "[== ]",
608
+ "[= ]"
609
+ ]
610
+ },
611
+ "bouncingBall": {
612
+ "interval": 80,
613
+ "frames": [
614
+ "( ● )",
615
+ "( ● )",
616
+ "( ● )",
617
+ "( ● )",
618
+ "( ●)",
619
+ "( ● )",
620
+ "( ● )",
621
+ "( ● )",
622
+ "( ● )",
623
+ "(● )"
624
+ ]
625
+ },
626
+ "smiley": {
627
+ "interval": 200,
628
+ "frames": [
629
+ "😄 ",
630
+ "😝 "
631
+ ]
632
+ },
633
+ "monkey": {
634
+ "interval": 300,
635
+ "frames": [
636
+ "🙈 ",
637
+ "🙈 ",
638
+ "🙉 ",
639
+ "🙊 "
640
+ ]
641
+ },
642
+ "hearts": {
643
+ "interval": 100,
644
+ "frames": [
645
+ "💛 ",
646
+ "💙 ",
647
+ "💜 ",
648
+ "💚 ",
649
+ "❤️ "
650
+ ]
651
+ },
652
+ "clock": {
653
+ "interval": 100,
654
+ "frames": [
655
+ "🕐 ",
656
+ "🕑 ",
657
+ "🕒 ",
658
+ "🕓 ",
659
+ "🕔 ",
660
+ "🕕 ",
661
+ "🕖 ",
662
+ "🕗 ",
663
+ "🕘 ",
664
+ "🕙 ",
665
+ "🕚 "
666
+ ]
667
+ },
668
+ "earth": {
669
+ "interval": 180,
670
+ "frames": [
671
+ "🌍 ",
672
+ "🌎 ",
673
+ "🌏 "
674
+ ]
675
+ },
676
+ "moon": {
677
+ "interval": 80,
678
+ "frames": [
679
+ "🌑 ",
680
+ "🌒 ",
681
+ "🌓 ",
682
+ "🌔 ",
683
+ "🌕 ",
684
+ "🌖 ",
685
+ "🌗 ",
686
+ "🌘 "
687
+ ]
688
+ },
689
+ "runner": {
690
+ "interval": 140,
691
+ "frames": [
692
+ "🚶 ",
693
+ "🏃 "
694
+ ]
695
+ },
696
+ "pong": {
697
+ "interval": 80,
698
+ "frames": [
699
+ "▐⠂ ▌",
700
+ "▐⠈ ▌",
701
+ "▐ ⠂ ▌",
702
+ "▐ ⠠ ▌",
703
+ "▐ ⡀ ▌",
704
+ "▐ ⠠ ▌",
705
+ "▐ ⠂ ▌",
706
+ "▐ ⠈ ▌",
707
+ "▐ ⠂ ▌",
708
+ "▐ ⠠ ▌",
709
+ "▐ ⡀ ▌",
710
+ "▐ ⠠ ▌",
711
+ "▐ ⠂ ▌",
712
+ "▐ ⠈ ▌",
713
+ "▐ ⠂▌",
714
+ "▐ ⠠▌",
715
+ "▐ ⡀▌",
716
+ "▐ ⠠ ▌",
717
+ "▐ ⠂ ▌",
718
+ "▐ ⠈ ▌",
719
+ "▐ ⠂ ▌",
720
+ "▐ ⠠ ▌",
721
+ "▐ ⡀ ▌",
722
+ "▐ ⠠ ▌",
723
+ "▐ ⠂ ▌",
724
+ "▐ ⠈ ▌",
725
+ "▐ ⠂ ▌",
726
+ "▐ ⠠ ▌",
727
+ "▐ ⡀ ▌",
728
+ "▐⠠ ▌"
729
+ ]
730
+ }
731
+ }
data/euruko.rb ADDED
@@ -0,0 +1,117 @@
1
+ require_relative 'lib/whirly'
2
+ require 'paint'
3
+
4
+ # # # Whirly
5
+
6
+ print "\033c"
7
+ puts Paint["Whirly", :underline]
8
+
9
+ Whirly.start status: 'Generating something huge…' do
10
+ sleep 15
11
+ Whirly.status = "(actually it's just `sleep 15`)"
12
+ sleep 15
13
+ Whirly.status = "Almost done…"
14
+ sleep 3
15
+ Whirly.status = "10 more seconds!"
16
+ sleep 10
17
+ end
18
+
19
+ puts
20
+ puts
21
+ puts
22
+ puts "Done"
23
+ sleep 5
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+ # # # Earth
36
+
37
+ print "\033c"
38
+ puts Paint["Earth Spinner", :underline]
39
+
40
+ Whirly.start spinner: "earth"
41
+ Whirly.status = "Travelling…"
42
+ sleep 9
43
+ Whirly.stop
44
+
45
+ puts
46
+ puts
47
+ puts
48
+ puts "Done"
49
+ sleep 5
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
59
+ # # # Pong Game
60
+
61
+ print "\033c"
62
+ puts Paint["Pong", :underline]
63
+
64
+ Whirly.start spinner: "pong", use_color: false, status: "Two computers in a game of Pong" do
65
+ sleep 9
66
+ end
67
+
68
+
69
+ puts
70
+ puts
71
+ puts
72
+ puts "Done"
73
+ sleep 5
74
+
75
+
76
+
77
+
78
+
79
+
80
+
81
+
82
+
83
+
84
+ # # # Ticking Clock
85
+
86
+ print "\033c"
87
+ puts Paint["Clock", :underline]
88
+
89
+ Whirly.start spinner: "clock", interval: 1000 do
90
+ sleep 12
91
+ end
92
+
93
+ puts
94
+ puts
95
+ puts
96
+ puts "Time is over"
97
+
98
+
99
+
100
+
101
+
102
+
103
+
104
+
105
+
106
+
107
+
108
+ # # # URL
109
+
110
+
111
+ print "\033c"
112
+ puts Paint["Get WHIRLY", :bold]
113
+
114
+ Whirly.start status: 'https://github.com/janlelis/whirly' do
115
+ sleep 60
116
+ end
117
+
Binary file
data/lib/whirly.rb ADDED
@@ -0,0 +1,142 @@
1
+ require_relative "whirly/version"
2
+ require_relative "whirly/spinners"
3
+
4
+ require "paint"
5
+
6
+ # TODO configure extra-line below
7
+ # TODO clear previous frame
8
+
9
+ module Whirly
10
+ CLI_COMMANDS = {
11
+ hide_cursor: "\x1b[?25l",
12
+ show_cursor: "\x1b[?25h",
13
+ }
14
+
15
+ class << self
16
+ attr_accessor :status
17
+ end
18
+
19
+ def self.enabled?
20
+ @enabled
21
+ end
22
+
23
+ def self.paused?
24
+ @paused
25
+ end
26
+
27
+ def self.start(stream: $stdout,
28
+ interval: nil,
29
+ spinner: "whirly",
30
+ use_color: defined?(Paint),
31
+ color_change_rate: 30,
32
+ status: nil,
33
+ hide_cursor: true)
34
+ # only actviate if we are on a real terminal
35
+ return false unless stream.tty?
36
+
37
+ # ensure cursor is visible after exit
38
+ at_exit{ @stream.print CLI_COMMANDS[:show_cursor] } if !defined?(@enabled) && hide_cursor
39
+
40
+ # only activate once
41
+ return false if @enabled
42
+
43
+ # save options and preprocess
44
+ @enabled = true
45
+ @paused = false
46
+ @stream = stream
47
+ @status = status
48
+ @spinner = SPINNERS[spinner.to_s]
49
+ raise(ArgumentError, "Whirly: Invalid spinner given") if !@spinner || (!@spinner["frames"] && !@spinner["proc"])
50
+ @hide_cursor = hide_cursor
51
+ @interval = (interval || @spinner["interval"] || 100) * 0.001
52
+ @frames = @spinner["frames"] && @spinner["frames"].cycle
53
+ @proc = @spinner["proc"]
54
+
55
+ # init color
56
+ if use_color
57
+ if defined?(Paint)
58
+ @color = "%.6x" % rand(16777216)
59
+ @color_directions = (0..2).map{ |e| rand(3) - 1 }
60
+ @color_change_rate = color_change_rate
61
+ else
62
+ warn "Whirly warning: Using colors requires the paint gem"
63
+ end
64
+ end
65
+
66
+ # hide cursor
67
+ @stream.print CLI_COMMANDS[:hide_cursor] if @hide_cursor
68
+
69
+ # start spinner loop
70
+ @thread = Thread.new do
71
+ while true # it's just a spinner, no exact timing here
72
+ next_color if @color
73
+ render
74
+ sleep(@interval)
75
+ end
76
+ end
77
+
78
+ # idiomatic block syntax
79
+ if block_given?
80
+ yield
81
+ Whirly.stop
82
+ end
83
+
84
+ true
85
+ end
86
+
87
+ def self.stop(delete = false)
88
+ return false unless @enabled
89
+ @thread.terminate
90
+ @enabled = false
91
+ @stream.print CLI_COMMANDS[:show_cursor] if @hide_cursor
92
+ print "TODO" if delete
93
+
94
+ true
95
+ end
96
+
97
+ def self.pause
98
+ # unrender
99
+ @paused = true
100
+ @stream.print CLI_COMMANDS[:show_cursor] if @hide_cursor
101
+ if block_given?
102
+ yield
103
+ continue
104
+ end
105
+ end
106
+
107
+ def self.continue
108
+ @stream.print CLI_COMMANDS[:hide_cursor] if @hide_cursor
109
+ @paused = false
110
+ end
111
+
112
+ def self.unrender
113
+ return unless @current_frame
114
+ current_frame_size = @current_frame.size
115
+ @stream.print "\n\e[s#{' ' * current_frame_size}\e[u\e[1A"
116
+ end
117
+
118
+ def self.render
119
+ return if @paused
120
+ unrender
121
+ @current_frame = @proc ? @proc.call : @frames.next
122
+ @current_frame = Paint[@current_frame, @color] if @color
123
+ @current_frame += " #{@status}" if @status
124
+ # @stream.print "\e[s#{@current_frame}\e[u"
125
+ @stream.print "\n\e[s#{@current_frame}\e[u\e[1A"
126
+ end
127
+
128
+ def self.next_color
129
+ @color = @color.scan(/../).map.with_index{ |c, i|
130
+ color_change = rand(@color_change_rate) * @color_directions[i]
131
+ nc = c.to_i(16) + color_change
132
+ if nc <= 0
133
+ nc = 0
134
+ @color_directions[i] = rand(3) - 1
135
+ elsif nc >= 255
136
+ nc = 255
137
+ @color_directions[i] = rand(3) - 1
138
+ end
139
+ "%.2x" % nc
140
+ }.join
141
+ end
142
+ end
@@ -0,0 +1,6 @@
1
+ require "json"
2
+
3
+ module Whirly
4
+ SPINNERS = JSON.load(File.read(File.dirname(__FILE__) + "/../../data/spinners.json"))
5
+ SPINNERS["whirly"] = { "proc" => ->(){ [0x1F600 + rand(55)].pack("U") }, "interval" => 200 }
6
+ end
@@ -0,0 +1,4 @@
1
+ module Whirly
2
+ VERSION = "0.1.0".freeze
3
+ end
4
+
@@ -0,0 +1,9 @@
1
+ require_relative "../lib/whirly"
2
+ require "minitest/autorun"
3
+
4
+ describe Whirly do
5
+ it "works" do
6
+ assert_equal true, false
7
+ end
8
+ end
9
+
data/whirly.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require File.dirname(__FILE__) + "/lib/whirly/version"
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "whirly"
7
+ gem.version = Whirly::VERSION
8
+ gem.summary = "Whirly: The friendly terminal spinner"
9
+ gem.description = "Whirly: The friendly terminal spinner"
10
+ gem.authors = ["Jan Lelis"]
11
+ gem.email = ["mail@janlelis.de"]
12
+ gem.homepage = "https://github.com/janlelis/whirly"
13
+ gem.license = "MIT"
14
+
15
+ gem.files = Dir["{**/}{.*,*}"].select{ |path| File.file?(path) && path !~ /^(pkg|data)/ } + %w[
16
+ data/spinners.json
17
+ ]
18
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
19
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
+ gem.require_paths = ["lib"]
21
+
22
+ gem.required_ruby_version = "~> 2.0"
23
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: whirly
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jan Lelis
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-09-23 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: 'Whirly: The friendly terminal spinner'
14
+ email:
15
+ - mail@janlelis.de
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".README.md.swp"
21
+ - ".euruko.rb.swp"
22
+ - ".gitignore"
23
+ - ".gitmodules"
24
+ - ".travis.yml"
25
+ - CHANGELOG.md
26
+ - CODE_OF_CONDUCT.md
27
+ - Gemfile
28
+ - Gemfile.lock
29
+ - MIT-LICENSE.txt
30
+ - README.md
31
+ - Rakefile
32
+ - data/spinners.json
33
+ - euruko.rb
34
+ - lib/.whirly.rb.swp
35
+ - lib/whirly.rb
36
+ - lib/whirly/spinners.rb
37
+ - lib/whirly/version.rb
38
+ - spec/whirly_spec.rb
39
+ - whirly.gemspec
40
+ homepage: https://github.com/janlelis/whirly
41
+ licenses:
42
+ - MIT
43
+ metadata: {}
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: '2.0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubyforge_project:
60
+ rubygems_version: 2.4.8
61
+ signing_key:
62
+ specification_version: 4
63
+ summary: 'Whirly: The friendly terminal spinner'
64
+ test_files:
65
+ - spec/whirly_spec.rb