tty-prompt 0.3.0 → 0.4.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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -1
  3. data/CHANGELOG.md +15 -0
  4. data/Gemfile +2 -2
  5. data/README.md +185 -25
  6. data/examples/enum.rb +8 -0
  7. data/examples/enum_select.rb +7 -0
  8. data/examples/in.rb +3 -1
  9. data/examples/slider.rb +6 -0
  10. data/lib/tty-prompt.rb +8 -2
  11. data/lib/tty/prompt.rb +63 -13
  12. data/lib/tty/prompt/converters.rb +12 -6
  13. data/lib/tty/prompt/enum_list.rb +222 -0
  14. data/lib/tty/prompt/list.rb +48 -15
  15. data/lib/tty/prompt/multi_list.rb +11 -11
  16. data/lib/tty/prompt/question.rb +38 -14
  17. data/lib/tty/prompt/question/checks.rb +5 -3
  18. data/lib/tty/prompt/reader.rb +12 -18
  19. data/lib/tty/prompt/reader/codes.rb +15 -9
  20. data/lib/tty/prompt/reader/key_event.rb +51 -24
  21. data/lib/tty/prompt/slider.rb +170 -0
  22. data/lib/tty/prompt/symbols.rb +7 -1
  23. data/lib/tty/prompt/utils.rb +31 -3
  24. data/lib/tty/prompt/version.rb +1 -1
  25. data/spec/spec_helper.rb +1 -0
  26. data/spec/unit/converters/convert_bool_spec.rb +1 -1
  27. data/spec/unit/converters/convert_date_spec.rb +11 -2
  28. data/spec/unit/converters/convert_file_spec.rb +1 -1
  29. data/spec/unit/converters/convert_number_spec.rb +19 -2
  30. data/spec/unit/converters/convert_path_spec.rb +1 -1
  31. data/spec/unit/converters/convert_range_spec.rb +4 -3
  32. data/spec/unit/enum_select_spec.rb +93 -0
  33. data/spec/unit/multi_select_spec.rb +14 -12
  34. data/spec/unit/question/checks_spec.rb +97 -0
  35. data/spec/unit/reader/key_event_spec.rb +67 -0
  36. data/spec/unit/select_spec.rb +15 -16
  37. data/spec/unit/slider_spec.rb +54 -0
  38. data/tty-prompt.gemspec +2 -1
  39. metadata +31 -5
  40. data/.ruby-version +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a6c43cfd17fb7fe5d5f256f124571fb904a3d6b3
4
- data.tar.gz: 0cc290a7c31157fe9d953133ce2f7a3df5042142
3
+ metadata.gz: b2e80fd1b397f9aae2abb3195844a6d1d3dc2dea
4
+ data.tar.gz: 266c5ccc26bcbe7ea0a9634e7f702e3387a2bce4
5
5
  SHA512:
6
- metadata.gz: b20f2aa8fab1798c62b8e5a9770351ab58fcf6de0afbbf7a60eba88c31e0b551273cd706944a3e17e3b6e1f6f1366d5e0d60f8c61b638c28dc6e9f0b657b9aac
7
- data.tar.gz: 6f2be862205c779ba31d2651b4e9d7874d5df4a4566218e0793224215db197900dc930022940418f04fb7427948036928897e7384f65570f5d741f05b7f405e8
6
+ metadata.gz: d249d03ac3dd16fc49b784e5d11983f31c15d30991c524fe6dbc1fd135c7509fef3476f1ef3b1ad4c5e1dd9bcf19ec938743771c4f121fcf96977b3913220ab2
7
+ data.tar.gz: eacb6d537e03baaf4219304af247d0baaf24f0d22efd2e49eec368d5f19a4f5449ec10af4ca9009eba2dc468b91d22580b5df47333c519b759ba010e8505d394
data/.travis.yml CHANGED
@@ -2,13 +2,14 @@
2
2
  language: ruby
3
3
  sudo: false
4
4
  cache: bundler
5
- bundler_args: --without yard benchmarks
5
+ bundler_args: --without tools
6
6
  script: "bundle exec rake ci"
7
7
  rvm:
8
8
  - 1.9.3
9
9
  - 2.0
10
10
  - 2.1
11
11
  - 2.2
12
+ - 2.3.0
12
13
  - ruby-head
13
14
  - jruby-19mode
14
15
  - jruby
@@ -23,3 +24,5 @@ matrix:
23
24
  fast_finish: true
24
25
  branches:
25
26
  only: master
27
+ notifications:
28
+ email: false
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Change log
2
2
 
3
+ ## [v0.4.0] - 2016-02-08
4
+
5
+ ### Added
6
+ * Add :enum option for #select & #multi_select to allow for numerical selection by @rtoshiro
7
+ * Add new key event types to KeyEvent
8
+ * Add #slider for picking values from range of numbers
9
+ * Add #enum_select for selecting option from enumerated list
10
+ * Add ability to configure error messages for #ask call
11
+ * Add new ConversionError type
12
+
13
+ ### Changed
14
+ * Move #blank? to Utils
15
+ * Update pastel dependency
16
+
3
17
  ## [v0.3.0] - 2015-12-28
4
18
 
5
19
  ### Added
@@ -44,6 +58,7 @@
44
58
 
45
59
  * Initial implementation and release
46
60
 
61
+ [v0.4.0]: https://github.com/peter-murach/tty-prompt/compare/v0.3.0...v0.4.0
47
62
  [v0.3.0]: https://github.com/peter-murach/tty-prompt/compare/v0.2.0...v0.3.0
48
63
  [v0.2.0]: https://github.com/peter-murach/tty-prompt/compare/v0.1.0...v0.2.0
49
64
  [v0.1.0]: https://github.com/peter-murach/tty-prompt/compare/v0.1.0
data/Gemfile CHANGED
@@ -2,10 +2,10 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- group :development do
6
- gem 'rspec', '~> 3.3.0'
5
+ group :tools do
7
6
  gem 'yard', '~> 0.8.7'
8
7
  gem 'benchmark-ips', '~> 2.0.0'
8
+ gem 'byebug', platform: :mri
9
9
  end
10
10
 
11
11
  group :metrics do
data/README.md CHANGED
@@ -18,7 +18,8 @@
18
18
  ## Features
19
19
 
20
20
  * Number of prompt types for gathering user input
21
- * A robust API for getting and validating complex inputs
21
+ * A robust API for validating complex inputs
22
+ * User friendly error feedback
22
23
 
23
24
  ## Installation
24
25
 
@@ -49,17 +50,20 @@ Or install it yourself as:
49
50
  * [2.2.5 modify](#225-modify)
50
51
  * [2.2.6 required](#226-required)
51
52
  * [2.2.7 validate](#227-validate)
53
+ * [2.2.8 messages](#228-messages)
52
54
  * [2.3 keypress](#23-keypress)
53
55
  * [2.4 multiline](#24-multiline)
54
56
  * [2.5 mask](#25-mask)
55
57
  * [2.6 yes?/no?](#26-yesno)
56
58
  * [2.7 select](#27-select)
57
59
  * [2.8 multi_select](#28-multi_select)
58
- * [2.9 suggest](#29-suggest)
59
- * [2.10 say](#210-say)
60
- * [2.11 ok](#211-ok)
61
- * [2.12 warn](#212-warn)
62
- * [2.13 error](#213-warn)
60
+ * [2.9 enum_select](#29-enum_select)
61
+ * [2.10 suggest](#210-suggest)
62
+ * [2.11 slider](#211-slider)
63
+ * [2.12 say](#212-say)
64
+ * [2.13 ok](#213-ok)
65
+ * [2.14 warn](#214-warn)
66
+ * [2.15 error](#215-warn)
63
67
 
64
68
  ## 1. Usage
65
69
 
@@ -105,7 +109,7 @@ Also, asking multiple choice questions is a breeze with `multi_select`:
105
109
 
106
110
  ```ruby
107
111
  choices = %w(vodka beer wine whisky bourbon)
108
- prompt.select("Select drinks?", choices)
112
+ prompt.multi_select("Select drinks?", choices)
109
113
  # =>
110
114
  #
111
115
  # Select drinks? (Use arrow keys, press Space to select and Enter to finish)"
@@ -116,6 +120,20 @@ prompt.select("Select drinks?", choices)
116
120
  # ⬡ bourbon
117
121
  ```
118
122
 
123
+ To ask for a selection from enumerated list you can use `enum_select`:
124
+
125
+ ```ruby
126
+ choices = %w(emacs nano vim)
127
+ prompt.enum_select("Select an editor?")
128
+ # =>
129
+ #
130
+ # Select an editor?
131
+ # 1) /bin/nano
132
+ # 2) /usr/bin/vim.basic
133
+ # 3) /usr/bin/vim.tiny
134
+ # Choose 1-3 [2]:
135
+ ```
136
+
119
137
  ## 2. Interface
120
138
 
121
139
  ### 2.1 ask
@@ -214,7 +232,7 @@ ask("Provide number in range: 0-9?") { |q| q.in('0-9') }
214
232
 
215
233
  #### 2.2.5 modify
216
234
 
217
- Set the `:modify` option if you want to handle whitespace or letter capitalization.
235
+ Set the `:modify` option if you want to handle whitespace or letter capitalization.
218
236
 
219
237
  ```ruby
220
238
  prompt.ask('Enter text:') do |q|
@@ -224,8 +242,8 @@ end
224
242
 
225
243
  Available letter casing settings are:
226
244
  ```ruby
227
- :up # change to small case
228
- :down # change to upper case
245
+ :up # change to upper case
246
+ :down # change to small case
229
247
  :capitalize # capitalize each word
230
248
  ```
231
249
 
@@ -244,7 +262,7 @@ To ensure that input is provided use `:required` option:
244
262
  ```ruby
245
263
  prompt.ask("What's your phone number?", required: true)
246
264
  # What's your phone number?
247
- # >> No value provided for required
265
+ # >> Value must be provided
248
266
  ```
249
267
 
250
268
  #### 2.2.7 validate
@@ -263,25 +281,43 @@ The **TTY::Prompt** comes with bult-in validations for `:email` and you can use
263
281
  prompt.ask('What is your email?') { |q| q.validate :email }
264
282
  ```
265
283
 
284
+ ### 2.2.8 messages
285
+
286
+ By default `tty-prompt` comes with predefined error messages for `required`, `in`, `validate` options. You can change these and configure to your liking either by inling them with the option:
287
+
288
+ ```ruby
289
+ prompt.ask('What is your email?') do |q|
290
+ question.validate(/\A\w+@\w+\.\w+\Z/, 'Invalid email address')
291
+ end
292
+ ```
293
+
294
+ or change the `messages` key entry out of `:required?`, `:valid?`, `:range?`:
295
+
296
+ ```ruby
297
+ prompt.ask('What is your email?') do |q|
298
+ question.validate(/\A\w+@\w+\.\w+\Z/)
299
+ question.messages[:valid?] = 'Invalid email address'
300
+ end
301
+ ```
302
+
266
303
  ### 2.3 keypress
267
304
 
268
- In order to ask question with a single character or keypress answer use `ask_keypress`:
305
+ In order to ask question with a single character or keypress answer use `keypress`:
269
306
 
270
307
  ```ruby
271
- prompt.ask_keypress("Which one do you prefer a, b, c or d ?")
308
+ prompt.keypress("Which one do you prefer a, b, c or d ?")
272
309
  ```
273
310
 
274
311
  ### 2.4 multiline
275
312
 
276
- Asking for multiline input can be done with `ask_multiline` method.
313
+ Asking for multiline input can be done with `multiline` method.
277
314
 
278
315
  ```ruby
279
- prompt.ask_multiline("Provide description?")
316
+ prompt.multiline("Provide description?")
280
317
  ```
281
318
 
282
319
  The reading of input will terminate when empty line is submitted.
283
320
 
284
-
285
321
  ### 2.5 mask
286
322
 
287
323
  If you require input of confidential information use `mask` method. By default each character that is printed is replaced by `•` symbol. All configuration options applicable to `ask` method can be used with `mask` as well.
@@ -325,7 +361,7 @@ There is also the opposite for asking confirmation of negative option:
325
361
  ```ruby
326
362
  prompt.no?('Do you hate Ruby?')
327
363
  # =>
328
- # Do you like Ruby? (y/N)
364
+ # Do you hate Ruby? (y/N)
329
365
  ```
330
366
 
331
367
  ### 2.7 select
@@ -341,7 +377,7 @@ prompt.select("Choose your destiny?", %w(Scorpion Kano Jax))
341
377
  # Jax
342
378
  ```
343
379
 
344
- You can also provide options through DSL using the `choice` method for single entry and/or `choices` call for more than one choice:
380
+ You can also provide options through DSL using the `choice` method for single entry and/or `choices` for more than one choice:
345
381
 
346
382
  ```ruby
347
383
  prompt.select("Choose your destiny?") do |menu|
@@ -395,6 +431,23 @@ end
395
431
  # ‣ Jax
396
432
  ```
397
433
 
434
+ For ordered choices set `enum` to any delimiter String. In that way, you can use arrows keys and numbers (0-9) to select the item.
435
+
436
+ ```ruby
437
+ prompt.select("Choose your destiny?") do |menu|
438
+ menu.enum '.'
439
+
440
+ menu.choice 'Scorpion', 1
441
+ menu.choice 'Kano', 2
442
+ menu.choice 'Jax', 3
443
+ end
444
+ # =>
445
+ # Choose your destiny? (Use arrow or number (0-9) keys, press Enter to select)
446
+ # 1. Scorpion
447
+ # 2. Kano
448
+ # ‣ 3. Jax
449
+ ```
450
+
398
451
  You can configure help message, marker like so
399
452
 
400
453
  ```ruby
@@ -466,6 +519,27 @@ end
466
519
  # ‣ ⬢ bourbon
467
520
  ```
468
521
 
522
+ Like `select`, for ordered choices set `enum` to any delimiter String. In that way, you can use arrows keys and numbers (0-9) to select the item.
523
+
524
+ ```ruby
525
+ prompt.multi_select("Select drinks?") do |menu|
526
+ menu.enum ')'
527
+
528
+ menu.choice :vodka, {score: 10}
529
+ menu.choice :beer, {score: 20}
530
+ menu.choice :wine, {score: 30}
531
+ menu.choice :whisky, {score: 40}
532
+ menu.choice :bourbon, {score: 50}
533
+ end
534
+ # =>
535
+ # Select drinks? beer, bourbon
536
+ # ⬡ 1) vodka
537
+ # ⬢ 2) beer
538
+ # ⬡ 3) wine
539
+ # ⬡ 4) whisky
540
+ # ‣ ⬢ 5) bourbon
541
+ ```
542
+
469
543
  And when you press enter you will see the following selected:
470
544
 
471
545
  ```ruby
@@ -473,7 +547,66 @@ And when you press enter you will see the following selected:
473
547
  # => [{score: 20}, {score: 50}]
474
548
  ```
475
549
 
476
- ### 2.9 suggest
550
+ ### 2.9 enum_select
551
+
552
+ In order to ask for standard selection from indexed list you can use `enum_select` and pass question together with possible choices:
553
+
554
+ ```ruby
555
+ choices = %w(emacs nano vim)
556
+ prompt.enum_select("Select an editor?")
557
+ # =>
558
+ #
559
+ # Select an editor?
560
+ # 1) nano
561
+ # 2) vim
562
+ # 3) emacs
563
+ # Choose 1-3 [1]:
564
+ ```
565
+
566
+ Similar to `select` and `multi_select`, you can provide question options through DSL using `choice` method and/or `choices` like so:
567
+
568
+ ```ruby
569
+ choices = %w(nano vim emacs)
570
+ prompt.enum_select("Select an editor?") do |menu|
571
+ menu.choice :nano, '/bin/nano'
572
+ menu.choice :vim, '/usr/bin/vim'
573
+ menu.choice :emacs, '/usr/bin/emacs'
574
+ end
575
+ # =>
576
+ #
577
+ # Select an editor?
578
+ # 1) nano
579
+ # 2) vim
580
+ # 3) emacs
581
+ # Choose 1-3 [1]:
582
+ #
583
+ # Select an editor? /bin/nano
584
+ ```
585
+
586
+ You can change the indexed numbers by passing `enum` option and the default option by using `default` like so
587
+
588
+ ```ruby
589
+ choices = %w(nano vim emacs)
590
+ prompt.enum_select("Select an editor?") do |menu|
591
+ menu.default 2
592
+ menu.enum '.'
593
+
594
+ menu.choice :nano, '/bin/nano'
595
+ menu.choice :vim, '/usr/bin/vim'
596
+ menu.choice :emacs, '/usr/bin/emacs'
597
+ end
598
+ # =>
599
+ #
600
+ # Select an editor?
601
+ # 1. nano
602
+ # 2. vim
603
+ # 3. emacs
604
+ # Choose 1-3 [2]:
605
+ #
606
+ # Select an editor? /usr/bin/vim
607
+ ```
608
+
609
+ ### 2.10 suggest
477
610
 
478
611
  To suggest possible matches for the user input use `suggest` method like so:
479
612
 
@@ -485,7 +618,7 @@ prompt.suggest('sta', ['stage', 'stash', 'commit', 'branch'])
485
618
  # stash
486
619
  ```
487
620
 
488
- To cusomize query text presented pass `:single_text` and `:plural_text` options to respectively change the message when one match is found or many.
621
+ To customize query text presented pass `:single_text` and `:plural_text` options to respectively change the message when one match is found or many.
489
622
 
490
623
  ```ruby
491
624
  possible = %w(status stage stash commit branch blame)
@@ -495,7 +628,34 @@ prompt.suggest('b', possible, indent: 4, single_text: 'Perhaps you meant?')
495
628
  # blame
496
629
  ```
497
630
 
498
- ### 2.10 say
631
+ ### 2.11 slider
632
+
633
+ If you have constrained range of numbers for user to choose from you may consider using `slider`. The slider provides easy visual way of picking a value marked by `O` marker.
634
+
635
+ ```ruby
636
+ prompt.slider('What size?', min: 32, max: 54, step: 2)
637
+ # =>
638
+ #
639
+ # What size? (User arrow keys, press Enter to select)
640
+ # |------O-----| 44
641
+ ```
642
+
643
+ Slider can be configured through DSL as well:
644
+
645
+ ```ruby
646
+ prompt.slider('What size?') do |range|
647
+ range.default 4
648
+ range.min 0
649
+ range.max 20
650
+ range.step 2
651
+ end
652
+ # =>
653
+ #
654
+ # What size? (User arrow keys, press Enter to select)
655
+ # |--O-------| 4
656
+ ```
657
+
658
+ ### 2.12 say
499
659
 
500
660
  To simply print message out to stdout use `say` like so:
501
661
 
@@ -507,7 +667,7 @@ The `say` method also accepts option `:color` which supports all the colors prov
507
667
 
508
668
  **TTY::Prompt** provides more specific versions of `say` method to better express intenation behind the message such as `ok`, `warn` and `error`.
509
669
 
510
- ### 2.11 ok
670
+ ### 2.13 ok
511
671
 
512
672
  Print message(s) in green do:
513
673
 
@@ -515,7 +675,7 @@ Print message(s) in green do:
515
675
  prompt.ok(...)
516
676
  ```
517
677
 
518
- ### 2.12 warn
678
+ ### 2.14 warn
519
679
 
520
680
  Print message(s) in yellow do:
521
681
 
@@ -523,7 +683,7 @@ Print message(s) in yellow do:
523
683
  prompt.warn(...)
524
684
  ```
525
685
 
526
- ### 2.13 error
686
+ ### 2.15 error
527
687
 
528
688
  Print message(s) in red do:
529
689
 
@@ -541,4 +701,4 @@ prompt.error(...)
541
701
 
542
702
  ## Copyright
543
703
 
544
- Copyright (c) 2015 Piotr Murach. See LICENSE for further details.
704
+ Copyright (c) 2015-2016 Piotr Murach. See LICENSE for further details.
data/examples/enum.rb ADDED
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+
3
+ require 'tty-prompt'
4
+
5
+ prompt = TTY::Prompt.new
6
+
7
+ warriors = %w(Scorpion Kano Jax)
8
+ prompt.select('Choose your destiny?', warriors, enum: ')')
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ require 'tty-prompt'
4
+
5
+ prompt = TTY::Prompt.new
6
+ choices = %w(/bin/nano /usr/bin/vim.basic /usr/bin/vim.tiny)
7
+ prompt.enum_select('Select an editor', choices, default: 2)
data/examples/in.rb CHANGED
@@ -4,4 +4,6 @@ require 'tty-prompt'
4
4
 
5
5
  prompt = TTY::Prompt.new
6
6
 
7
- prompt.ask('How do you like it on scale 1 - 10?', in: '1-10')
7
+ prompt.ask('How do you like it on scale 1 - 10?', in: '1-10') do |q|
8
+ q.messages[:range?] = "Sorry wrong one!"
9
+ end