tty-prompt 0.18.1 → 0.23.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +95 -0
  3. data/README.md +598 -256
  4. data/lib/tty-prompt.rb +1 -2
  5. data/lib/tty/prompt.rb +192 -144
  6. data/lib/tty/prompt/answers_collector.rb +5 -5
  7. data/lib/tty/prompt/{enum_paginator.rb → block_paginator.rb} +20 -19
  8. data/lib/tty/prompt/choice.rb +9 -10
  9. data/lib/tty/prompt/choices.rb +30 -12
  10. data/lib/tty/prompt/confirm_question.rb +42 -16
  11. data/lib/tty/prompt/const.rb +17 -0
  12. data/lib/tty/prompt/converter_dsl.rb +6 -7
  13. data/lib/tty/prompt/converter_registry.rb +31 -26
  14. data/lib/tty/prompt/converters.rb +139 -32
  15. data/lib/tty/prompt/enum_list.rb +81 -26
  16. data/lib/tty/prompt/errors.rb +31 -0
  17. data/lib/tty/prompt/evaluator.rb +2 -2
  18. data/lib/tty/prompt/expander.rb +45 -15
  19. data/lib/tty/prompt/keypress.rb +33 -36
  20. data/lib/tty/prompt/list.rb +198 -63
  21. data/lib/tty/prompt/mask_question.rb +11 -8
  22. data/lib/tty/prompt/multi_list.rb +131 -28
  23. data/lib/tty/prompt/multiline.rb +9 -7
  24. data/lib/tty/prompt/paginator.rb +38 -26
  25. data/lib/tty/prompt/question.rb +92 -37
  26. data/lib/tty/prompt/question/checks.rb +20 -2
  27. data/lib/tty/prompt/question/modifier.rb +4 -2
  28. data/lib/tty/prompt/question/validation.rb +3 -3
  29. data/lib/tty/prompt/selected_choices.rb +77 -0
  30. data/lib/tty/prompt/slider.rb +125 -30
  31. data/lib/tty/prompt/statement.rb +3 -3
  32. data/lib/tty/prompt/suggestion.rb +7 -6
  33. data/lib/tty/prompt/symbols.rb +58 -34
  34. data/lib/tty/prompt/test.rb +36 -0
  35. data/lib/tty/prompt/timer.rb +75 -0
  36. data/lib/tty/prompt/utils.rb +1 -3
  37. data/lib/tty/prompt/version.rb +1 -1
  38. metadata +29 -227
  39. data/Rakefile +0 -8
  40. data/examples/ask.rb +0 -7
  41. data/examples/ask_valid.rb +0 -12
  42. data/examples/collect.rb +0 -21
  43. data/examples/echo.rb +0 -11
  44. data/examples/enum_select.rb +0 -7
  45. data/examples/enum_select_disabled.rb +0 -16
  46. data/examples/enum_select_paged.rb +0 -9
  47. data/examples/enum_select_wrapped.rb +0 -15
  48. data/examples/expand.rb +0 -29
  49. data/examples/in.rb +0 -9
  50. data/examples/inputs.rb +0 -10
  51. data/examples/key_events.rb +0 -15
  52. data/examples/keypress.rb +0 -9
  53. data/examples/mask.rb +0 -13
  54. data/examples/multi_select.rb +0 -8
  55. data/examples/multi_select_disabled.rb +0 -17
  56. data/examples/multi_select_paged.rb +0 -9
  57. data/examples/multi_select_wrapped.rb +0 -15
  58. data/examples/multiline.rb +0 -9
  59. data/examples/pause.rb +0 -9
  60. data/examples/select.rb +0 -24
  61. data/examples/select_disabled.rb +0 -18
  62. data/examples/select_enum.rb +0 -8
  63. data/examples/select_filtered.rb +0 -11
  64. data/examples/select_paginated.rb +0 -11
  65. data/examples/select_wrapped.rb +0 -15
  66. data/examples/slider.rb +0 -6
  67. data/examples/validation.rb +0 -9
  68. data/examples/yes_no.rb +0 -7
  69. data/lib/tty/prompt/messages.rb +0 -49
  70. data/lib/tty/prompt/timeout.rb +0 -78
  71. data/lib/tty/test_prompt.rb +0 -20
  72. data/spec/spec_helper.rb +0 -45
  73. data/spec/unit/ask_spec.rb +0 -132
  74. data/spec/unit/choice/eql_spec.rb +0 -22
  75. data/spec/unit/choice/from_spec.rb +0 -96
  76. data/spec/unit/choices/add_spec.rb +0 -12
  77. data/spec/unit/choices/each_spec.rb +0 -13
  78. data/spec/unit/choices/find_by_spec.rb +0 -10
  79. data/spec/unit/choices/new_spec.rb +0 -10
  80. data/spec/unit/choices/pluck_spec.rb +0 -9
  81. data/spec/unit/collect_spec.rb +0 -96
  82. data/spec/unit/converters/convert_bool_spec.rb +0 -58
  83. data/spec/unit/converters/convert_char_spec.rb +0 -11
  84. data/spec/unit/converters/convert_custom_spec.rb +0 -14
  85. data/spec/unit/converters/convert_date_spec.rb +0 -34
  86. data/spec/unit/converters/convert_file_spec.rb +0 -18
  87. data/spec/unit/converters/convert_number_spec.rb +0 -39
  88. data/spec/unit/converters/convert_path_spec.rb +0 -15
  89. data/spec/unit/converters/convert_range_spec.rb +0 -22
  90. data/spec/unit/converters/convert_regex_spec.rb +0 -12
  91. data/spec/unit/converters/convert_string_spec.rb +0 -21
  92. data/spec/unit/converters/on_error_spec.rb +0 -9
  93. data/spec/unit/distance/distance_spec.rb +0 -73
  94. data/spec/unit/enum_paginator_spec.rb +0 -75
  95. data/spec/unit/enum_select_spec.rb +0 -446
  96. data/spec/unit/error_spec.rb +0 -20
  97. data/spec/unit/evaluator_spec.rb +0 -67
  98. data/spec/unit/expand_spec.rb +0 -198
  99. data/spec/unit/keypress_spec.rb +0 -72
  100. data/spec/unit/mask_spec.rb +0 -132
  101. data/spec/unit/multi_select_spec.rb +0 -511
  102. data/spec/unit/multiline_spec.rb +0 -77
  103. data/spec/unit/new_spec.rb +0 -20
  104. data/spec/unit/ok_spec.rb +0 -10
  105. data/spec/unit/paginator_spec.rb +0 -73
  106. data/spec/unit/question/checks_spec.rb +0 -97
  107. data/spec/unit/question/default_spec.rb +0 -31
  108. data/spec/unit/question/echo_spec.rb +0 -38
  109. data/spec/unit/question/in_spec.rb +0 -115
  110. data/spec/unit/question/initialize_spec.rb +0 -12
  111. data/spec/unit/question/modifier/apply_to_spec.rb +0 -24
  112. data/spec/unit/question/modifier/letter_case_spec.rb +0 -41
  113. data/spec/unit/question/modifier/whitespace_spec.rb +0 -51
  114. data/spec/unit/question/modify_spec.rb +0 -41
  115. data/spec/unit/question/required_spec.rb +0 -92
  116. data/spec/unit/question/validate_spec.rb +0 -115
  117. data/spec/unit/question/validation/call_spec.rb +0 -31
  118. data/spec/unit/question/validation/coerce_spec.rb +0 -30
  119. data/spec/unit/result_spec.rb +0 -40
  120. data/spec/unit/say_spec.rb +0 -67
  121. data/spec/unit/select_spec.rb +0 -660
  122. data/spec/unit/slider_spec.rb +0 -100
  123. data/spec/unit/statement/initialize_spec.rb +0 -15
  124. data/spec/unit/subscribe_spec.rb +0 -22
  125. data/spec/unit/suggest_spec.rb +0 -28
  126. data/spec/unit/warn_spec.rb +0 -21
  127. data/spec/unit/yes_no_spec.rb +0 -251
  128. data/tasks/console.rake +0 -11
  129. data/tasks/coverage.rake +0 -11
  130. data/tasks/spec.rake +0 -29
  131. data/tty-prompt.gemspec +0 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4993a3639c2dec47c658cddd6a8c3d98b4efb7bec6cc3d1b90dfd184d9b6f889
4
- data.tar.gz: d069f2c94118978bbfa04e54c967a0d8ce185adc6d7eb74446988350bca21d06
3
+ metadata.gz: 3dcdfb83f0945b162d19c5a068386009fbc5cc2f90969374018ee9aad72bd116
4
+ data.tar.gz: 004ebca9f017ea58bca8d4400e61d4817394b55343c0ecc3a3727f8818103d8f
5
5
  SHA512:
6
- metadata.gz: c1dd9287d14e3aa2eb8357d9ff759cdec52182535bc9697f97d4da7ab7c111f27ec61bfc176cc16cc7c8f4f2ca1dcd3af4784df1c82e95b0382f4cb2dc7cc782
7
- data.tar.gz: 62ed0bc598c3a6b6b65ed7a5f14a7bacd769a5d46dfa041afb67d4d7a4de407e4cb5334fc25942351551414c0c29d68a9fc51aa238e198931677639c3ad4d382
6
+ metadata.gz: e9fe7560e4dd4aca6e47d6ca67dca40079b4350ac97834d9bdca8c21254048097b338092177bebe5a1a2da1609fce1e155ee4a373c3d16c6979fc261a02dcc52
7
+ data.tar.gz: eff0e563cde0179831056cf107f61e17681269b705f7d499a657d84f365197500c5ea0220aad8b3959ef3d82bd0ac1db49d8beb4566881cb257112b2f69beafa
@@ -1,5 +1,95 @@
1
1
  # Change log
2
2
 
3
+ ## [v0.23.0] - 2020-12-14
4
+
5
+ ### Added
6
+ * Add the ability to provide an arbitrary array of values to Prompt::Slider by Katelyn Schiesser (@slowbro)
7
+
8
+ ### Changed
9
+ * Change to allow default option to be choice name as well as index in select, multi_select and enum_select prompts
10
+
11
+ ### Fixed
12
+ * Fix left and right key navigation while filtering choices in the #select and #multi_select prompts
13
+
14
+ ## [v0.22.0] - 2020-07-20
15
+
16
+ ### Added
17
+ * Add #slider format customization with a proc by Sven Pchnit(@2called-chaos)
18
+ * Add convert message customization
19
+ * Add conversion of input into Array, Hash or URI object
20
+ * Add callable objects as possible values in :active_color and :help_color
21
+ * Add shortcuts to select of all/reverse choices in #multi_select prompt
22
+ * Add :help option to #slider prompt
23
+ * Add :quiet option to remove final prompt output by Katelyn Schiesser (@slowbro)
24
+ * Add :show_help option to control help display in #select, #multi_select, #enum_select
25
+ and #slider prompts
26
+
27
+ ### Changed
28
+ * Changed question :validation option to :validate by Sven Pachnit(@2called-chaos)
29
+ * Change ConverterRegistry to store only proc values and simplify interface
30
+ * Change Converters to stop raising errors and print console error messages instead
31
+ * Change :range conversion to handle float numbers
32
+ * Change yes?/no? prompt to infer default value from words and raise when
33
+ no boolean can be deduced
34
+ * Change Prompt#new to use keyword arguments
35
+ * Change #select/#multi_select prompts default help text
36
+ * Change #multi_select to preserve original ordering in returned answers
37
+ * Change to remove necromancer dependency
38
+ * Change TTY::TestPrompt to TTY::Prompt::Test
39
+ * Change #select,#multi_select & #enum_select to allow mix of options and block parameters configuration
40
+ * Change to allow filtering through symbol choice names
41
+ * Change all errors to inherit from common Error class
42
+
43
+ ### Fixed
44
+ * Fix multiline prompt to return default value when no input provided
45
+ * Fix color option overriding in say, ok, error and warn prompts
46
+ * Fix Prompt#inspect format to display all public attributes
47
+
48
+ ## [v0.21.0] - 2020-03-08
49
+
50
+ ### Added
51
+ * Add :min option to #multi_select prompt by Katelyn Schiesser(@slowbro)
52
+
53
+ ### Changed
54
+ * Change gemspec to remove test artifacts
55
+
56
+ ### Fixed
57
+ * Fix :help_color option for multi_select prompt by @robbystk
58
+
59
+ ## [v0.20.0] - 2019-11-24
60
+
61
+ ### Changed
62
+ * Change to update tty-reader dependency
63
+ * Change gemspec to include metadata
64
+
65
+ ### Fixed
66
+ * Fix Choice#from to differentiate between nil and false by Katelyn Schiesser(@slowbro)
67
+ * Fix yes? and no? prompts to stop raising on invalid/blank input by Katelyn Schiesser(@slowbro)
68
+ * Fix Ruby 2.7 keyword arguments warnings
69
+ * Fix question validation to work with nil input
70
+
71
+ ## [v0.19.0] - 2019-05-27
72
+
73
+ ### Added
74
+ * Add Prompt#debug to allow displaying values in terminal's top right corner
75
+ * Add :max to limit number of choices in #multi_select prompt
76
+ * Add :value to pre populate #ask prompt line content
77
+ * Add :auto_hint to expand default hint in #expand prompt by Ewoudt Kellerman(@hellola)
78
+ * Add Timer to track and timeout code execution
79
+
80
+ ### Changed
81
+ * Change Paginator to expose #start_index & #end_index
82
+ * Change Paginator to figure out #start_index based on per page size and adjust boundaries to match active selection
83
+ * Change #ask prompt to allow no question
84
+ * Change #enum_select to automatically assigned non-disabled default option
85
+ * Change #enum_select to set default choice when navigating by page
86
+ * Change #select & #multi_select to allow navigation by page with left/right keys
87
+ * Change #keypress to use Timer
88
+ * Change Choice#from to allow any object coercible to string
89
+ * Change to remove test artifacts from the gem bundle
90
+ * Change to remove timers dependency
91
+ * Change to update tty-reader dependency
92
+
3
93
  ## [v0.18.1] - 2018-12-29
4
94
 
5
95
  ### Changed
@@ -304,6 +394,11 @@
304
394
 
305
395
  * Initial implementation and release
306
396
 
397
+ [v0.23.0]: https://github.com/piotrmurach/tty-prompt/compare/v0.22.0...v0.23.0
398
+ [v0.22.0]: https://github.com/piotrmurach/tty-prompt/compare/v0.21.0...v0.22.0
399
+ [v0.21.0]: https://github.com/piotrmurach/tty-prompt/compare/v0.20.0...v0.21.0
400
+ [v0.20.0]: https://github.com/piotrmurach/tty-prompt/compare/v0.19.0...v0.20.0
401
+ [v0.19.0]: https://github.com/piotrmurach/tty-prompt/compare/v0.18.1...v0.19.0
307
402
  [v0.18.1]: https://github.com/piotrmurach/tty-prompt/compare/v0.18.0...v0.18.1
308
403
  [v0.18.0]: https://github.com/piotrmurach/tty-prompt/compare/v0.17.2...v0.18.0
309
404
  [v0.17.2]: https://github.com/piotrmurach/tty-prompt/compare/v0.17.1...v0.17.2
data/README.md CHANGED
@@ -1,11 +1,11 @@
1
1
  <div align="center">
2
- <a href="https://piotrmurach.github.io/tty" target="_blank"><img width="130" src="https://cdn.rawgit.com/piotrmurach/tty/master/images/tty.png" alt="tty logo" /></a>
2
+ <a href="https://ttytoolkit.org"><img width="130" src="https://github.com/piotrmurach/tty/raw/master/images/tty.png" alt="TTY Toolkit logo" /></a>
3
3
  </div>
4
4
 
5
5
  # TTY::Prompt [![Gitter](https://badges.gitter.im/Join%20Chat.svg)][gitter]
6
6
 
7
7
  [![Gem Version](https://badge.fury.io/rb/tty-prompt.svg)][gem]
8
- [![Build Status](https://secure.travis-ci.org/piotrmurach/tty-prompt.svg?branch=master)][travis]
8
+ [![Actions CI](https://github.com/piotrmurach/tty-prompt/workflows/CI/badge.svg?branch=master)][gh_actions_ci]
9
9
  [![Build status](https://ci.appveyor.com/api/projects/status/4cguoiah5dprbq7n?svg=true)][appveyor]
10
10
  [![Code Climate](https://codeclimate.com/github/piotrmurach/tty-prompt/badges/gpa.svg)][codeclimate]
11
11
  [![Coverage Status](https://coveralls.io/repos/github/piotrmurach/tty-prompt/badge.svg)][coverage]
@@ -13,6 +13,7 @@
13
13
 
14
14
  [gitter]: https://gitter.im/piotrmurach/tty
15
15
  [gem]: http://badge.fury.io/rb/tty-prompt
16
+ [gh_actions_ci]: https://github.com/piotrmurach/tty-prompt/actions?query=workflow%3ACI
16
17
  [travis]: http://travis-ci.org/piotrmurach/tty-prompt
17
18
  [appveyor]: https://ci.appveyor.com/project/piotrmurach/tty-prompt
18
19
  [codeclimate]: https://codeclimate.com/github/piotrmurach/tty-prompt
@@ -47,7 +48,7 @@ For Windows, consider installing [ConEmu](https://conemu.github.io/), [cmder](ht
47
48
  Add this line to your application's Gemfile:
48
49
 
49
50
  ```ruby
50
- gem 'tty-prompt'
51
+ gem "tty-prompt"
51
52
  ```
52
53
 
53
54
  And then execute:
@@ -63,14 +64,15 @@ Or install it yourself as:
63
64
  * [1. Usage](#1-usage)
64
65
  * [2. Interface](#2-interface)
65
66
  * [2.1 ask](#21-ask)
66
- * [2.1.1 convert](#211-convert)
67
- * [2.1.2 default](#212-default)
68
- * [2.1.3 echo](#213-echo)
69
- * [2.1.4 error messages](#214-error-messages)
70
- * [2.1.5 in](#215-in)
71
- * [2.1.6 modify](#216-modify)
72
- * [2.1.7 required](#217-required)
73
- * [2.1.8 validate](#218-validate)
67
+ * [2.1.1 :convert](#211-convert)
68
+ * [2.1.2 :default](#212-default)
69
+ * [2.1.3 :value](#213-value)
70
+ * [2.1.4 :echo](#214-echo)
71
+ * [2.1.5 error messages](#215-error-messages)
72
+ * [2.1.6 :in](#216-in)
73
+ * [2.1.7 :modify](#217-modify)
74
+ * [2.1.8 :required](#218-required)
75
+ * [2.1.9 :validate](#219-validate)
74
76
  * [2.2 keypress](#22-keypress)
75
77
  * [2.2.1 :timeout](#221-timeout)
76
78
  * [2.3 multiline](#23-multiline)
@@ -80,14 +82,28 @@ Or install it yourself as:
80
82
  * [2.6.1 choices](#261-choices)
81
83
  * [2.6.1.1 :disabled](#2611-disabled)
82
84
  * [2.6.2 select](#262-select)
83
- * [2.6.2.1 :disabled](#2621-disabled)
84
- * [2.6.2.2 :filter](#2622-filter)
85
+ * [2.6.2.1 :cycle](#2621-cycle)
86
+ * [2.6.2.2 :enum](#2622-enum)
87
+ * [2.6.2.3 :help](#2623-help)
88
+ * [2.6.2.4 :marker](#2624-marker)
89
+ * [2.6.2.5 :per_page](#2625-per_page)
90
+ * [2.6.2.6 :disabled](#2626-disabled)
91
+ * [2.6.2.7 :filter](#2627-filter)
85
92
  * [2.6.3 multi_select](#263-multi_select)
86
- * [2.6.3.1 :disabled](#2631-disabled)
87
- * [2.6.3.2 :echo](#2632-echo)
88
- * [2.6.3.3 :filter](#2633-filter)
93
+ * [2.6.3.1 :cycle](#2631-cycle)
94
+ * [2.6.3.2 :enum](#2632-enum)
95
+ * [2.6.3.3 :help](#2633-help)
96
+ * [2.6.3.4 :per_page](#2634-per_page)
97
+ * [2.6.3.5 :disabled](#2635-disabled)
98
+ * [2.6.3.6 :echo](#2636-echo)
99
+ * [2.6.3.7 :filter](#2637-filter)
100
+ * [2.6.3.8 :min](#2638-min)
101
+ * [2.6.3.9 :max](#2639-max)
89
102
  * [2.6.4 enum_select](#264-enum_select)
103
+ * [2.6.4.1 :per_page](#2641-per_page)
104
+ * [2.6.4.1 :disabled](#2641-disabled)
90
105
  * [2.7 expand](#27-expand)
106
+ * [2.7.1 :auto_hint](#271-auto_hint)
91
107
  * [2.8 collect](#28-collect)
92
108
  * [2.9 suggest](#29-suggest)
93
109
  * [2.10 slider](#210-slider)
@@ -97,32 +113,36 @@ Or install it yourself as:
97
113
  * [2.11.3 error](#2113-error)
98
114
  * [2.12 keyboard events](#212-keyboard-events)
99
115
  * [3. settings](#3-settings)
100
- * [3.1 active_color](#31-active_color)
101
- * [3.2 enable_color](#32-enable-color)
102
- * [3.3 help_color](#33-help_color)
103
- * [3.4 interrupt](#34-interrupt)
104
- * [3.5 prefix](#35-prefix)
105
- * [3.6 track_history](#36-track_history)
116
+ * [3.1 :symbols](#31-symbols)
117
+ * [3.2 :active_color](#32-active_color)
118
+ * [3.3 :enable_color](#33-enable_color)
119
+ * [3.4 :help_color](#34-help_color)
120
+ * [3.5 :interrupt](#35-interrupt)
121
+ * [3.6 :prefix](#36-prefix)
122
+ * [3.7 :quiet](#37-quiet)
123
+ * [3.8 :track_history](#38-track_history)
106
124
 
107
125
  ## 1. Usage
108
126
 
109
127
  In order to start asking questions on the command line, create prompt:
110
128
 
111
129
  ```ruby
130
+ require "tty-prompt"
131
+
112
132
  prompt = TTY::Prompt.new
113
133
  ```
114
134
 
115
- and then call `ask` with the question for simple input:
135
+ And then call `ask` with the question for simple input:
116
136
 
117
137
  ```ruby
118
- prompt.ask('What is your name?', default: ENV['USER'])
138
+ prompt.ask("What is your name?", default: ENV["USER"])
119
139
  # => What is your name? (piotr)
120
140
  ```
121
141
 
122
142
  To confirm input use `yes?`:
123
143
 
124
144
  ```ruby
125
- prompt.yes?('Do you like Ruby?')
145
+ prompt.yes?("Do you like Ruby?")
126
146
  # => Do you like Ruby? (Y/n)
127
147
  ```
128
148
 
@@ -138,7 +158,7 @@ Asking question with list of options couldn't be easier using `select` like so:
138
158
  ```ruby
139
159
  prompt.select("Choose your destiny?", %w(Scorpion Kano Jax))
140
160
  # =>
141
- # Choose your destiny? (Use arrow keys, press Enter to select)
161
+ # Choose your destiny? (Use ↑/↓ arrow keys, press Enter to select)
142
162
  # ‣ Scorpion
143
163
  # Kano
144
164
  # Jax
@@ -151,7 +171,7 @@ choices = %w(vodka beer wine whisky bourbon)
151
171
  prompt.multi_select("Select drinks?", choices)
152
172
  # =>
153
173
  #
154
- # Select drinks? (Use arrow keys, press Space to select and Enter to finish)"
174
+ # Select drinks? (Use ↑/↓ arrow keys, press Space to select and Enter to finish)"
155
175
  # ‣ ⬡ vodka
156
176
  # ⬡ beer
157
177
  # ⬡ wine
@@ -177,13 +197,13 @@ However, if you have a lot of options to choose from you may want to use `expand
177
197
 
178
198
  ```ruby
179
199
  choices = [
180
- { key: 'y', name: 'overwrite this file', value: :yes },
181
- { key: 'n', name: 'do not overwrite this file', value: :no },
182
- { key: 'a', name: 'overwrite this file and all later files', value: :all },
183
- { key: 'd', name: 'show diff', value: :diff },
184
- { key: 'q', name: 'quit; do not overwrite this file ', value: :quit }
200
+ { key: "y", name: "overwrite this file", value: :yes },
201
+ { key: "n", name: "do not overwrite this file", value: :no },
202
+ { key: "a", name: "overwrite this file and all later files", value: :all },
203
+ { key: "d", name: "show diff", value: :diff },
204
+ { key: "q", name: "quit; do not overwrite this file ", value: :quit }
185
205
  ]
186
- prompt.expand('Overwrite Gemfile?', choices)
206
+ prompt.expand("Overwrite Gemfile?", choices)
187
207
  # =>
188
208
  # Overwrite Gemfile? (enter "h" for help) [y,n,a,d,q,h]
189
209
  ```
@@ -192,14 +212,14 @@ If you wish to collect more than one answer use `collect`:
192
212
 
193
213
  ```ruby
194
214
  result = prompt.collect do
195
- key(:name).ask('Name?')
215
+ key(:name).ask("Name?")
196
216
 
197
- key(:age).ask('Age?', convert: :int)
217
+ key(:age).ask("Age?", convert: :int)
198
218
 
199
219
  key(:address) do
200
- key(:street).ask('Street?', required: true)
201
- key(:city).ask('City?')
202
- key(:zip).ask('Zip?', validate: /\A\d{3}\Z/)
220
+ key(:street).ask("Street?", required: true)
221
+ key(:city).ask("City?")
222
+ key(:zip).ask("Zip?", validate: /\A\d{3}\Z/)
203
223
  end
204
224
  end
205
225
  # =>
@@ -226,25 +246,41 @@ prompt.ask("What is your name?") do |q|
226
246
  end
227
247
  ```
228
248
 
229
- #### 2.1.1 convert
249
+ #### 2.1.1 `:convert`
230
250
 
231
251
  The `convert` property is used to convert input to a required type.
232
252
 
233
- By default no conversion is performed. The following conversions are provided:
253
+ By default no conversion of input is performed. To change this use one of the following conversions:
234
254
 
235
- ```ruby
236
- :bool # true or false for strings such as "Yes", "No"
237
- :date # date type
238
- :datetime # datetime type
239
- :file # File object
240
- :float # decimal or error if cannot convert
241
- :int # integer or error if cannot convert
242
- :path # Pathname object
243
- :range # range type
244
- :regexp # regex expression
245
- :string # string
246
- :symbol # symbol
247
- ```
255
+ * `:boolean`|`:bool` - e.g. 'yes/1/y/t/' becomes `true`, 'no/0/n/f' becomes `false`
256
+ * `:date` - parses dates formats "28/03/2020", "March 28th 2020"
257
+ * `:time` - parses time formats "11:20:03"
258
+ * `:float` - e.g. `-1` becomes `-1.0`
259
+ * `:int`|`:integer` - e.g. `+1` becomes `1`
260
+ * `:sym`|`:symbol` - e.g. "foo" becomes `:foo`
261
+ * `:filepath` - converts to file path
262
+ * `:path`|`:pathname` - converts to `Pathname` object
263
+ * `:range` - e.g. '1-10' becomes `1..10` range object
264
+ * `:regexp` - e.g. "foo|bar" becomes `/foo|bar/`
265
+ * `:uri` - converts to `URI` object
266
+ * `:list`|`:array` - e.g. 'a,b,c' becomes `["a", "b", "c"]`
267
+ * `:map`|`:hash` - e.g. 'a:1 b:2 c:3' becomes `{a: "1", b: "2", c: "3"}`
268
+
269
+ In addition you can specify a plural or append `list` or `array` to any base type:
270
+
271
+ * `:ints` or `:int_list` - will convert to a list of integers
272
+ * `:floats` or `:float_list` - will convert to a list of floats
273
+ * `:bools` or `:bool_list` - will convert to a list of booleans, e.g. `t,f,t` becomes `[true, false, true]`
274
+
275
+ Similarly, you can append `map` or `hash` to any base type:
276
+
277
+ * `:int_map`|`:integer_map`|`:int_hash` - will convert to a hash of integers, e.g `a:1 b:2 c:3` becomes `{a: 1, b: 2, c: 3}`
278
+ * `:bool_map` | `:boolean_map`|`:bool_hash` - will convert to a hash of booleans, e.g `a:t b:f c:t` becomes `{a: true, b: false, c: true}`
279
+
280
+ By default, `map` converts keys to symbols, if you wish to use strings instead specify key type like so:
281
+
282
+ * `:str_int_map` - will convert to a hash of string keys and integer values
283
+ * `:string_integer_hash` - will convert to a hash of string keys and integer values
248
284
 
249
285
  For example, if you are interested in range type as answer do the following:
250
286
 
@@ -254,78 +290,115 @@ prompt.ask("Provide range of numbers?", convert: :range)
254
290
  # => 1..10
255
291
  ```
256
292
 
293
+ If, on the other hand, you wish to convert input to a hash of integer values do:
294
+
295
+ ```ruby
296
+ prompt.ask("Provide keys and values:", convert: :int_map)
297
+ # Provide keys and values: a=1 b=2 c=3
298
+ # => {a: 1, b: 2, c: 3}
299
+ ```
300
+
301
+ If a user provides a wrong type for conversion an error message will be printed in the console:
302
+
303
+ ```ruby
304
+ prompt.ask("Provide digit:", convert: :float)
305
+ # Provide digit: x
306
+ # >> Cannot convert `x` into 'float' type
307
+ ```
308
+
309
+ You can further customize error message:
310
+
311
+ ```ruby
312
+ prompt.ask("Provide digit:", convert: :float) do |q|
313
+ q.convert(:float, "Wrong value of %{value} for %{type} conversion")
314
+ # or
315
+ q.convert :float
316
+ q.messages[:convert?] = "Wrong value of %{value} for %{type} conversion"
317
+ end
318
+ ```
319
+
257
320
  You can also provide a custom conversion like so:
258
321
 
259
322
  ```ruby
260
- prompt.ask('Ingredients? (comma sep list)') do |q|
323
+ prompt.ask("Ingredients? (comma sep list)") do |q|
261
324
  q.convert -> (input) { input.split(/,\s*/) }
262
325
  end
263
326
  # Ingredients? (comma sep list) milk, eggs, flour
264
- # => ['milk', 'eggs', 'flour']
327
+ # => ["milk", "eggs", "flour"]
265
328
  ```
266
329
 
267
- #### 2.1.2 default
330
+ #### 2.1.2 `:default`
268
331
 
269
332
  The `:default` option is used if the user presses return key:
270
333
 
271
334
  ```ruby
272
- prompt.ask('What is your name?', default: 'Anonymous')
335
+ prompt.ask("What is your name?", default: "Anonymous")
273
336
  # =>
274
337
  # What is your name? (Anonymous)
275
338
  ```
276
339
 
277
- #### 2.1.3 echo
340
+ #### 2.1.3 `:value`
341
+
342
+ To pre-populate the input line for editing use `:value` option:
343
+
344
+ ```ruby
345
+ prompt.ask("What is your name?", value: "Piotr")
346
+ # =>
347
+ # What is your name? Piotr
348
+ ```
349
+
350
+ #### 2.1.4 `:echo`
278
351
 
279
352
  To control whether the input is shown back in terminal or not use `:echo` option like so:
280
353
 
281
354
  ```ruby
282
- prompt.ask('password:', echo: false)
355
+ prompt.ask("password:", echo: false)
283
356
  ```
284
357
 
285
- #### 2.1.4 error messages
358
+ #### 2.1.5 error messages
286
359
 
287
360
  By default `tty-prompt` comes with predefined error messages for `required`, `in`, `validate` options.
288
361
 
289
362
  You can change these and configure to your liking either by passing message as second argument with the option:
290
363
 
291
364
  ```ruby
292
- prompt.ask('What is your email?') do |q|
293
- q.validate(/\A\w+@\w+\.\w+\Z/, 'Invalid email address')
365
+ prompt.ask("What is your email?") do |q|
366
+ q.validate(/\A\w+@\w+\.\w+\Z/, "Invalid email address")
294
367
  end
295
368
  ```
296
369
 
297
- or change the `messages` key entry out of `:required?`, `:valid?`, `:range?`:
370
+ Or change the `messages` key entry out of `:required?`, `:valid?`, `:range?`:
298
371
 
299
372
  ```ruby
300
- prompt.ask('What is your email?') do |q|
373
+ prompt.ask("What is your email?") do |q|
301
374
  q.validate(/\A\w+@\w+\.\w+\Z/)
302
- q.messages[:valid?] = 'Invalid email address'
375
+ q.messages[:valid?] = "Invalid email address"
303
376
  end
304
377
  ```
305
378
 
306
- to change default range validation error message do:
379
+ To change default range validation error message do:
307
380
 
308
381
  ```ruby
309
- prompt.ask('How spicy on scale (1-5)? ') do |q|
310
- q.in '1-5'
311
- q.messages[:range?] = '%{value} out of expected range #{in}'
382
+ prompt.ask("How spicy on scale (1-5)? ") do |q|
383
+ q.in "1-5"
384
+ q.messages[:range?] = "%{value} out of expected range %{in}"
312
385
  end
313
386
  ```
314
387
 
315
- #### 2.1.5 in
388
+ #### 2.1.6 `:in`
316
389
 
317
390
  In order to check that provided input falls inside a range of inputs use the `in` option. For example, if we wanted to ask a user for a single digit in given range we may do following:
318
391
 
319
392
  ```ruby
320
- ask("Provide number in range: 0-9?") { |q| q.in('0-9') }
393
+ prompt.ask("Provide number in range: 0-9?") { |q| q.in("0-9") }
321
394
  ```
322
395
 
323
- #### 2.1.6 modify
396
+ #### 2.1.7 `:modify`
324
397
 
325
398
  Set the `:modify` option if you want to handle whitespace or letter capitalization.
326
399
 
327
400
  ```ruby
328
- prompt.ask('Enter text:') do |q|
401
+ prompt.ask("Enter text:") do |q|
329
402
  q.modify :strip, :collapse
330
403
  end
331
404
  ```
@@ -338,14 +411,16 @@ Available letter casing settings are:
338
411
  ```
339
412
 
340
413
  Available whitespace settings are:
414
+
341
415
  ```ruby
342
416
  :trim # remove whitespace from both ends of the input
417
+ :strip # same as :trim
343
418
  :chomp # remove whitespace at the end of input
344
419
  :collapse # reduce all whitespace to single character
345
420
  :remove # remove all whitespace
346
421
  ```
347
422
 
348
- #### 2.1.7 required
423
+ #### 2.1.8 `:required`
349
424
 
350
425
  To ensure that input is provided use `:required` option:
351
426
 
@@ -355,20 +430,26 @@ prompt.ask("What's your phone number?", required: true)
355
430
  # >> Value must be provided
356
431
  ```
357
432
 
358
- #### 2.1.8 validate
433
+ #### 2.1.9 `:validate`
359
434
 
360
- In order to validate that input matches a given patter you can pass the `validate` option. Validate setting accepts `Regex`, `Proc` or `Symbol`.
435
+ In order to validate that input matches a given pattern you can pass the `validate` option. Validate setting accepts `Regex`, `Proc` or `Symbol`.
361
436
 
362
437
  ```ruby
363
- prompt.ask('What is your username?') do |q|
364
- q.validate /^[^\.]+\.[^\.]+/
438
+ prompt.ask("What is your username?") do |q|
439
+ q.validate(/\A[^.]+\.[^.]+\Z/)
440
+ end
441
+ ```
442
+
443
+ ```ruby
444
+ prompt.ask("What is your username?") do |q|
445
+ q.validate ->(input) { input =~ /\A[^.]+\.[^.]+\Z/ }
365
446
  end
366
447
  ```
367
448
 
368
449
  The **TTY::Prompt** comes with built-in validations for `:email` and you can use them directly like so:
369
450
 
370
- ```prompt
371
- prompt.ask('What is your email?') { |q| q.validate :email }
451
+ ```ruby
452
+ prompt.ask("What is your email?") { |q| q.validate :email }
372
453
  ```
373
454
 
374
455
  ### 2.2. keypress
@@ -411,21 +492,22 @@ prompt.multiline("Description?")
411
492
  # I know not all that may be coming,
412
493
  # but be it what it will,
413
494
  # I'll go to it laughing.
414
- # => ["I know not all that may be coming,\n", "but be it what it will,\n", "I'll go to it laughing.\n"]
495
+ # =>
496
+ # ["I know not all that may be coming,\n", "but be it what it will,\n", "I'll go to it laughing.\n"]
415
497
  ```
416
498
 
417
499
  The `multiline` uses similar options to those supported by `ask` prompt. For example, to provide default description:
418
500
 
419
501
  ```ruby
420
- prompt.multiline("Description?", default: 'A super sweet prompt.')
502
+ prompt.multiline("Description?", default: "A super sweet prompt.")
421
503
  ```
422
504
 
423
- or using DSL:
505
+ Or using DSL:
424
506
 
425
507
  ```ruby
426
508
  prompt.multiline("Description?") do |q|
427
- q.default 'A super sweet prompt.'
428
- q.help 'Press thy ctrl+d to end'
509
+ q.default "A super sweet prompt."
510
+ q.help "Press thy ctrl+d to end"
429
511
  end
430
512
  ```
431
513
 
@@ -434,28 +516,28 @@ end
434
516
  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.
435
517
 
436
518
  ```ruby
437
- prompt.mask('What is your secret?')
519
+ prompt.mask("What is your secret?")
438
520
  # => What is your secret? ••••
439
521
  ```
440
522
 
441
- The masking character can be changed by passing `:mask` option:
523
+ The masking character can be changed by passing the `:mask` key:
442
524
 
443
525
  ```ruby
444
- heart = prompt.decorate('❤ ', :magenta)
445
- prompt.mask('What is your secret?', mask: heart)
446
- # => What is your secret? ❤ ❤ ❤ ❤ ❤
526
+ heart = prompt.decorate(prompt.symbols[:heart] + " ", :magenta)
527
+ prompt.mask("What is your secret?", mask: heart)
528
+ # => What is your secret? ❤ ❤ ❤ ❤ ❤
447
529
  ```
448
530
 
449
531
  If you don't wish to show any output use `:echo` option like so:
450
532
 
451
533
  ```ruby
452
- prompt.mask('What is your secret?', echo: false)
534
+ prompt.mask("What is your secret?", echo: false)
453
535
  ```
454
536
 
455
537
  You can also provide validation for your mask to enforce for instance strong passwords:
456
538
 
457
539
  ```ruby
458
- prompt.mask('What is your secret?', mask: heart) do |q|
540
+ prompt.mask("What is your secret?", mask: heart) do |q|
459
541
  q.validate(/[a-z\ ]{5,15}/)
460
542
  end
461
543
  ```
@@ -465,7 +547,7 @@ end
465
547
  In order to display a query asking for boolean input from user use `yes?` like so:
466
548
 
467
549
  ```ruby
468
- prompt.yes?('Do you like Ruby?')
550
+ prompt.yes?("Do you like Ruby?")
469
551
  # =>
470
552
  # Do you like Ruby? (Y/n)
471
553
  ```
@@ -476,7 +558,7 @@ It's enough to provide the `suffix` option for the prompt to accept matching ans
476
558
 
477
559
  ```ruby
478
560
  prompt.yes?("Are you a human?") do |q|
479
- q.suffix 'Yup/nope'
561
+ q.suffix "Yup/nope"
480
562
  end
481
563
  # =>
482
564
  # Are you a human? (Yup/nope)
@@ -487,8 +569,8 @@ Alternatively, instead of `suffix` option provide the `positive` and `negative`
487
569
  ```ruby
488
570
  prompt.yes?("Are you a human?") do |q|
489
571
  q.default false
490
- q.positive 'Yup'
491
- q.negative 'Nope'
572
+ q.positive "Yup"
573
+ q.negative "Nope"
492
574
  end
493
575
  # =>
494
576
  # Are you a human? (yup/Nope)
@@ -497,10 +579,10 @@ end
497
579
  Finally, providing all available options you can ask fully customized question:
498
580
 
499
581
  ```ruby
500
- prompt.yes?('Are you a human?') do |q|
501
- q.suffix 'Agree/Disagree'
502
- q.positive 'Agree'
503
- q.negative 'Disagree'
582
+ prompt.yes?("Are you a human?") do |q|
583
+ q.suffix "Agree/Disagree"
584
+ q.positive "Agree"
585
+ q.negative "Disagree"
504
586
  q.convert -> (input) { !input.match(/^agree$/i).nil? }
505
587
  end
506
588
  # =>
@@ -510,7 +592,7 @@ end
510
592
  There is also the opposite for asking confirmation of negative question:
511
593
 
512
594
  ```ruby
513
- prompt.no?('Do you hate Ruby?')
595
+ prompt.no?("Do you hate Ruby?")
514
596
  # =>
515
597
  # Do you hate Ruby? (y/N)
516
598
  ```
@@ -531,15 +613,21 @@ By default the choice name is also the value the prompt will return when selecte
531
613
 
532
614
  ```ruby
533
615
  choices = {small: 1, medium: 2, large: 3}
616
+ prompt.select("What size?", choices)
617
+ # =>
618
+ # What size? (Press ↑/↓ arrow to move and Enter to select)
619
+ # ‣ small
620
+ # medium
621
+ # large
534
622
  ```
535
623
 
536
624
  Finally, you can define an array of choices where each choice is a hash value with `:name` & `:value` keys which can include other options for customising individual choices:
537
625
 
538
626
  ```ruby
539
627
  choices = [
540
- {name: 'small', value: 1},
541
- {name: 'medium', value: 2, disabled: '(out of stock)'},
542
- {name: 'large', value: 3}
628
+ {name: "small", value: 1},
629
+ {name: "medium", value: 2, disabled: "(out of stock)"},
630
+ {name: "large", value: 3}
543
631
  ]
544
632
  ```
545
633
 
@@ -548,20 +636,25 @@ You can specify `:key` as an additional option which will be used as short name
548
636
  Another way to create menu with choices is using the DSL and the `choice` method. For example, the previous array of choices with hash values can be translated as:
549
637
 
550
638
  ```ruby
551
- prompt.select('What size?') do |menu|
552
- menu.choice name: 'small', value: 1
553
- menu.choice name: 'medium', value: 2, disabled: '(out of stock)'
554
- menu.choice name: 'large', value: 3
639
+ prompt.select("What size?") do |menu|
640
+ menu.choice name: "small", value: 1
641
+ menu.choice name: "medium", value: 2, disabled: "(out of stock)"
642
+ menu.choice name: "large", value: 3
555
643
  end
644
+ # =>
645
+ # What size? (Press ↑/↓ arrow to move and Enter to select)
646
+ # ‣ small
647
+ # ✘ medium (out of stock)
648
+ # large
556
649
  ```
557
650
 
558
651
  or in a more compact way:
559
652
 
560
653
  ```ruby
561
- prompt.select('What size?') do |menu|
562
- menu.choice 'small', 1
563
- menu.choice 'medium', 2, disabled: '(out of stock)'
564
- menu.choice 'large', 3
654
+ prompt.select("What size?") do |menu|
655
+ menu.choice "small", 1
656
+ menu.choice "medium", 2, disabled: "(out of stock)"
657
+ menu.choice "large", 3
565
658
  end
566
659
  ```
567
660
 
@@ -571,9 +664,9 @@ The `:disabled` key indicates to display a choice as currently unavailable to se
571
664
 
572
665
  ```ruby
573
666
  choices = [
574
- {name: 'small', value: 1},
575
- {name: 'medium', value: 2, disabled: '(out of stock)'}
576
- {name: 'large', value: 3}
667
+ {name: "small", value: 1},
668
+ {name: "medium", value: 2, disabled: "(out of stock)"},
669
+ {name: "large", value: 3}
577
670
  ]
578
671
  ```
579
672
 
@@ -584,7 +677,7 @@ For asking questions involving list of options use `select` method by passing th
584
677
  ```ruby
585
678
  prompt.select("Choose your destiny?", %w(Scorpion Kano Jax))
586
679
  # =>
587
- # Choose your destiny? (Use arrow keys, press Enter to select)
680
+ # Choose your destiny? (Use ↑/↓ arrow keys, press Enter to select)
588
681
  # ‣ Scorpion
589
682
  # Kano
590
683
  # Jax
@@ -594,12 +687,12 @@ You can also provide options through DSL using the `choice` method for single en
594
687
 
595
688
  ```ruby
596
689
  prompt.select("Choose your destiny?") do |menu|
597
- menu.choice 'Scorpion'
598
- menu.choice 'Kano'
599
- menu.choice 'Jax'
690
+ menu.choice "Scorpion"
691
+ menu.choice "Kano"
692
+ menu.choice "Jax"
600
693
  end
601
694
  # =>
602
- # Choose your destiny? (Use arrow keys, press Enter to select)
695
+ # Choose your destiny? (Use ↑/↓ arrow keys, press Enter to select)
603
696
  # ‣ Scorpion
604
697
  # Kano
605
698
  # Jax
@@ -609,12 +702,12 @@ By default the choice name is used as return value, but you can provide your cus
609
702
 
610
703
  ```ruby
611
704
  prompt.select("Choose your destiny?") do |menu|
612
- menu.choice 'Scorpion', 1
613
- menu.choice 'Kano', 2
614
- menu.choice 'Jax', -> { 'Nice choice captain!' }
705
+ menu.choice "Scorpion", 1
706
+ menu.choice "Kano", 2
707
+ menu.choice "Jax", -> { "Nice choice captain!" }
615
708
  end
616
709
  # =>
617
- # Choose your destiny? (Use arrow keys, press Enter to select)
710
+ # Choose your destiny? (Use ↑/↓ arrow keys, press Enter to select)
618
711
  # ‣ Scorpion
619
712
  # Kano
620
713
  # Jax
@@ -623,112 +716,140 @@ end
623
716
  If you wish you can also provide a simple hash to denote choice name and its value like so:
624
717
 
625
718
  ```ruby
626
- choices = {'Scorpion' => 1, 'Kano' => 2, 'Jax' => 3}
719
+ choices = {"Scorpion" => 1, "Kano" => 2, "Jax" => 3}
627
720
  prompt.select("Choose your destiny?", choices)
628
721
  ```
629
722
 
630
- To mark particular answer as selected use `default` with index of the option starting from `1`:
723
+ To mark particular answer as selected use `default` with either an index of the choice starting from `1` or a choice's name:
631
724
 
632
725
  ```ruby
633
726
  prompt.select("Choose your destiny?") do |menu|
634
727
  menu.default 3
728
+ # or menu.default "Jax"
635
729
 
636
- menu.choice 'Scorpion', 1
637
- menu.choice 'Kano', 2
638
- menu.choice 'Jax', 3
730
+ menu.choice "Scorpion", 1
731
+ menu.choice "Kano", 2
732
+ menu.choice "Jax", 3
639
733
  end
640
734
  # =>
641
- # Choose your destiny? (Use arrow keys, press Enter to select)
735
+ # Choose your destiny? (Use ↑/↓ arrow keys, press Enter to select)
642
736
  # Scorpion
643
737
  # Kano
644
738
  # ‣ Jax
645
739
  ```
646
740
 
647
- You can navigate the choices using the arrow keys or define your own key mappings (see [keyboard events](#212-keyboard-events). When reaching the top/bottom of the list, the selection does not cycle around by default. If you wish to enable cycling, you can pass `cycle: true` to `select` and `mutli_select`:
741
+ #### 2.6.2.1 `:cycle`
742
+
743
+ You can navigate the choices using the arrow keys or define your own key mappings (see [keyboard events](#212-keyboard-events). When reaching the top/bottom of the list, the selection does not cycle around by default. If you wish to enable cycling, you can pass `cycle: true` to `select` and `multi_select`:
648
744
 
649
745
  ```ruby
650
746
  prompt.select("Choose your destiny?", %w(Scorpion Kano Jax), cycle: true)
651
747
  # =>
652
- # Choose your destiny? (Use arrow keys, press Enter to select)
748
+ # Choose your destiny? (Use ↑/↓ arrow keys, press Enter to select)
653
749
  # ‣ Scorpion
654
750
  # Kano
655
751
  # Jax
656
752
  ```
657
753
 
754
+ #### 2.6.2.2 `:enum`
755
+
658
756
  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.
659
757
 
660
758
  ```ruby
661
759
  prompt.select("Choose your destiny?") do |menu|
662
- menu.enum '.'
760
+ menu.enum "."
663
761
 
664
- menu.choice 'Scorpion', 1
665
- menu.choice 'Kano', 2
666
- menu.choice 'Jax', 3
762
+ menu.choice "Scorpion", 1
763
+ menu.choice "Kano", 2
764
+ menu.choice "Jax", 3
667
765
  end
668
766
  # =>
669
- # Choose your destiny? (Use arrow or number (0-9) keys, press Enter to select)
767
+ # Choose your destiny? (Use ↑/↓ arrow or number (0-9) keys, press Enter to select)
670
768
  # 1. Scorpion
671
769
  # 2. Kano
672
770
  # ‣ 3. Jax
673
771
  ```
674
772
 
675
- You can configure help message and/or marker like so
773
+ #### 2.6.2.3 `:help`
774
+
775
+ You can configure help message with `:help` and when to display it with `:show_help` options. The help can be displayed on `start`, `never` or `always`:
676
776
 
677
777
  ```ruby
678
778
  choices = %w(Scorpion Kano Jax)
679
- prompt.select("Choose your destiny?", choices, help: "(Bash keyboard)", marker: '>')
779
+ prompt.select("Choose your destiny?", choices, help: "(Bash keyboard keys)", show_help: :always)
680
780
  # =>
681
- # Choose your destiny? (Bash keyboard)
781
+ # Choose your destiny? (Bash keyboard keys)
682
782
  # > Scorpion
683
783
  # Kano
684
784
  # Jax
685
785
  ```
686
786
 
787
+ #### 2.6.2.4 `:marker`
788
+
789
+ You can configure active marker like so:
790
+
791
+ ```ruby
792
+ choices = %w(Scorpion Kano Jax)
793
+ prompt.select("Choose your destiny?", choices, symbols: { marker: ">" })
794
+ # =>
795
+ # Choose your destiny? (Use ↑/↓ and ←/→ arrow keys, press Enter to select)
796
+ # > Scorpion
797
+ # Kano
798
+ # Jax
799
+ ```
800
+
801
+ #### 2.6.2.5 `:per_page`
802
+
687
803
  By default the menu is paginated if selection grows beyond `6` items. To change this setting use `:per_page` configuration.
688
804
 
689
805
  ```ruby
690
- letters = ('A'..'Z').to_a
806
+ letters = ("A".."Z").to_a
691
807
  prompt.select("Choose your letter?", letters, per_page: 4)
692
808
  # =>
693
- # Which letter? (Use arrow keys, press Enter to select)
809
+ # Which letter? (Use ↑/↓ and ←/→ arrow keys, press Enter to select)
694
810
  # ‣ A
695
811
  # B
696
812
  # C
697
813
  # D
698
- # (Move up or down to reveal more choices)
699
814
  ```
700
815
 
701
- You can also customise page navigation text using `:page_help` option:
816
+ You can also customise page navigation text using `:help` option:
702
817
  ```ruby
703
- letters = ('A'..'Z').to_a
818
+ letters = ("A".."Z").to_a
704
819
  prompt.select("Choose your letter?") do |menu|
705
820
  menu.per_page 4
706
- menu.page_help '(Wiggle thy finger up or down to see more)'
821
+ menu.help "(Wiggle thy finger up/down and left/right to see more)"
707
822
  menu.choices letters
708
823
  end
824
+ # =>
825
+ # Which letter? (Wiggle thy finger up/down and left/right to see more)
826
+ # ‣ A
827
+ # B
828
+ # C
829
+ # D
709
830
  ```
710
831
 
711
- #### 2.6.2.1 `:disabled`
832
+ #### 2.6.2.6 `:disabled`
712
833
 
713
834
  To disable menu choice, use the `:disabled` key with a value that explains the reason for the choice being unavailable. For example, out of all warriors, the Goro is currently injured:
714
835
 
715
836
  ```ruby
716
837
  warriors = [
717
- 'Scorpion',
718
- 'Kano',
719
- { name: 'Goro', disabled: '(injury)' },
720
- 'Jax',
721
- 'Kitana',
722
- 'Raiden'
838
+ "Scorpion",
839
+ "Kano",
840
+ { name: "Goro", disabled: "(injury)" },
841
+ "Jax",
842
+ "Kitana",
843
+ "Raiden"
723
844
  ]
724
845
  ```
725
846
 
726
847
  The disabled choice will be displayed with a cross `✘` character next to it and followed by an explanation:
727
848
 
728
849
  ```ruby
729
- prompt.select('Choose your destiny?', warriors)
850
+ prompt.select("Choose your destiny?", warriors)
730
851
  # =>
731
- # Choose your destiny? (Use arrow keys, press Enter to select)
852
+ # Choose your destiny? (Use ↑/↓ arrow keys, press Enter to select)
732
853
  # ‣ Scorpion
733
854
  # Kano
734
855
  # ✘ Goro (injury)
@@ -737,15 +858,15 @@ prompt.select('Choose your destiny?', warriors)
737
858
  # Raiden
738
859
  ```
739
860
 
740
- #### 2.6.2.2 `:filter`
861
+ #### 2.6.2.7 `:filter`
741
862
 
742
863
  To activate dynamic list searching on letter/number key presses use `:filter` option:
743
864
 
744
865
  ```ruby
745
866
  warriors = %w(Scorpion Kano Jax Kitana Raiden)
746
- prompt.select('Choose your destiny?', warriors, filter: true)
867
+ prompt.select("Choose your destiny?", warriors, filter: true)
747
868
  # =>
748
- # Choose your destiny? (Use arrow keys, press Enter to select, and letter keys to filter)
869
+ # Choose your destiny? (Use ↑/↓ arrow keys, press Enter to select, and letter keys to filter)
749
870
  # ‣ Scorpion
750
871
  # Kano
751
872
  # Jax
@@ -783,7 +904,7 @@ choices = %w(vodka beer wine whisky bourbon)
783
904
  prompt.multi_select("Select drinks?", choices)
784
905
  # =>
785
906
  #
786
- # Select drinks? (Use arrow keys, press Space to select and Enter to finish)"
907
+ # Select drinks? (Use ↑/↓ arrow keys, press Space to select and Enter to finish)"
787
908
  # ‣ ⬡ vodka
788
909
  # ⬡ beer
789
910
  # ⬡ wine
@@ -812,11 +933,12 @@ prompt.multi_select("Select drinks?") do |menu|
812
933
  end
813
934
  ```
814
935
 
815
- To mark choice(s) as selected use the `default` option with index(s) of the option(s) starting from `1`:
936
+ To mark choice(s) as selected use the `default` option with either index(s) of the choice(s) starting from `1` or choice name(s):
816
937
 
817
938
  ```ruby
818
939
  prompt.multi_select("Select drinks?") do |menu|
819
940
  menu.default 2, 5
941
+ # or menu.default :beer, :whisky
820
942
 
821
943
  menu.choice :vodka, {score: 10}
822
944
  menu.choice :beer, {score: 20}
@@ -833,11 +955,21 @@ end
833
955
  # ‣ ⬢ bourbon
834
956
  ```
835
957
 
958
+ #### 2.6.3.1 `:cycle`
959
+
960
+ Also like, `select`, the method takes an option `cycle` (which defaults to `false`), which lets you configure whether the selection should cycle around when reaching the top/bottom of the list when navigating:
961
+
962
+ ```ruby
963
+ prompt.multi_select("Select drinks?", %w(vodka beer wine), cycle: true)
964
+ ```
965
+
966
+ #### 2.6.3.2 `:enum`
967
+
836
968
  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.
837
969
 
838
970
  ```ruby
839
971
  prompt.multi_select("Select drinks?") do |menu|
840
- menu.enum ')'
972
+ menu.enum ")"
841
973
 
842
974
  menu.choice :vodka, {score: 10}
843
975
  menu.choice :beer, {score: 20}
@@ -861,17 +993,13 @@ And when you press enter you will see the following selected:
861
993
  # => [{score: 20}, {score: 50}]
862
994
  ```
863
995
 
864
- Also like, `select`, the method takes an option `cycle` (which defaults to `false`), which lets you configure whether the selection should cycle around when reaching the top/bottom of the list when navigating:
996
+ #### 2.6.3.3 `:help`
865
997
 
866
- ```ruby
867
- prompt.multi_select("Select drinks?", %w(vodka beer wine), cycle: true)
868
- ```
869
-
870
- You can configure help message and/or marker like so
998
+ You can configure help message with `:help` and when to display it with `:show_help` options. The help can be displayed on `start`, `never` or `always`:
871
999
 
872
1000
  ```ruby
873
1001
  choices = {vodka: 1, beer: 2, wine: 3, whisky: 4, bourbon: 5}
874
- prompt.multi_select("Select drinks?", choices, help: 'Press beer can against keyboard')
1002
+ prompt.multi_select("Select drinks?", choices, help: "Press beer can against keyboard", show_help: :always)
875
1003
  # =>
876
1004
  # Select drinks? (Press beer can against keyboard)"
877
1005
  # ‣ ⬡ vodka
@@ -881,41 +1009,42 @@ prompt.multi_select("Select drinks?", choices, help: 'Press beer can against key
881
1009
  # ⬡ bourbon
882
1010
  ```
883
1011
 
1012
+ #### 2.6.3.4 `:per_page`
1013
+
884
1014
  By default the menu is paginated if selection grows beyond `6` items. To change this setting use `:per_page` configuration.
885
1015
 
886
1016
  ```ruby
887
- letters = ('A'..'Z').to_a
1017
+ letters = ("A".."Z").to_a
888
1018
  prompt.multi_select("Choose your letter?", letters, per_page: 4)
889
1019
  # =>
890
- # Which letter? (Use arrow keys, press Space to select and Enter to finish)
1020
+ # Which letter? (Use ↑/↓ and ←/→ arrow keys, press Space to select and Enter to finish)
891
1021
  # ‣ ⬡ A
892
1022
  # ⬡ B
893
1023
  # ⬡ C
894
1024
  # ⬡ D
895
- # (Move up or down to reveal more choices)
896
1025
  ```
897
1026
 
898
- #### 2.6.3.1 `:disabled`
1027
+ #### 2.6.3.5 `:disabled`
899
1028
 
900
1029
  To disable menu choice, use the `:disabled` key with a value that explains the reason for the choice being unavailable. For example, out of all drinks, the sake and beer are currently out of stock:
901
1030
 
902
1031
  ```ruby
903
1032
  drinks = [
904
- 'bourbon',
905
- {name: 'sake', disabled: '(out of stock)'},
906
- 'vodka',
907
- {name: 'beer', disabled: '(out of stock)'},
908
- 'wine',
909
- 'whisky'
1033
+ "bourbon",
1034
+ {name: "sake", disabled: "(out of stock)"},
1035
+ "vodka",
1036
+ {name: "beer", disabled: "(out of stock)"},
1037
+ "wine",
1038
+ "whisky"
910
1039
  ]
911
1040
  ```
912
1041
 
913
1042
  The disabled choice will be displayed with a cross `✘` character next to it and followed by an explanation:
914
1043
 
915
1044
  ```ruby
916
- prompt.multi_select('Choose your favourite drink?', drinks)
1045
+ prompt.multi_select("Choose your favourite drink?", drinks)
917
1046
  # =>
918
- # Choose your favourite drink? (Use arrow keys, press Space to select and Enter to finish)
1047
+ # Choose your favourite drink? (Use ↑/↓ arrow keys, press Space to select and Enter to finish)
919
1048
  # ‣ ⬡ bourbon
920
1049
  # ✘ sake (out of stock)
921
1050
  # ⬡ vodka
@@ -924,7 +1053,7 @@ prompt.multi_select('Choose your favourite drink?', drinks)
924
1053
  # ⬡ whisky
925
1054
  ```
926
1055
 
927
- #### 2.6.3.2 `:echo`
1056
+ #### 2.6.3.6 `:echo`
928
1057
 
929
1058
  To control whether the selected items are shown on the question
930
1059
  header use the :echo option:
@@ -941,7 +1070,7 @@ prompt.multi_select("Select drinks?", choices, echo: false)
941
1070
  # ‣ ⬢ 5) bourbon
942
1071
  ```
943
1072
 
944
- #### 2.6.3.3 `:filter`
1073
+ #### 2.6.3.7 `:filter`
945
1074
 
946
1075
  To activate dynamic list filtering on letter/number typing, use the :filter option:
947
1076
 
@@ -949,7 +1078,7 @@ To activate dynamic list filtering on letter/number typing, use the :filter opti
949
1078
  choices = %w(vodka beer wine whisky bourbon)
950
1079
  prompt.multi_select("Select drinks?", choices, filter: true)
951
1080
  # =>
952
- # Select drinks? (Use arrow keys, press Space to select and Enter to finish, and letter keys to filter)
1081
+ # Select drinks? (Use ↑/↓ arrow keys, press Space to select and Enter to finish, and letter keys to filter)
953
1082
  # ‣ ⬡ vodka
954
1083
  # ⬡ beer
955
1084
  # ⬡ wine
@@ -971,13 +1100,45 @@ If the user changes or deletes a filter, the choices previously selected remain
971
1100
 
972
1101
  The `filter` option is not compatible with `enum`.
973
1102
 
1103
+ #### 2.6.3.8 `:min`
1104
+
1105
+ To force the minimum number of choices an user must select, use the `:min` option:
1106
+
1107
+ ```ruby
1108
+ choices = %w(vodka beer wine whisky bourbon)
1109
+ prompt.multi_select("Select drinks?", choices, min: 3)
1110
+ # =>
1111
+ # Select drinks? (min. 3) vodka, beer
1112
+ # ⬢ vodka
1113
+ # ⬢ beer
1114
+ # ⬡ wine
1115
+ # ⬡ wiskey
1116
+ # ‣ ⬡ bourbon
1117
+ ```
1118
+
1119
+ #### 2.6.3.9 `:max`
1120
+
1121
+ To limit the number of choices an user can select, use the `:max` option:
1122
+
1123
+ ```ruby
1124
+ choices = %w(vodka beer wine whisky bourbon)
1125
+ prompt.multi_select("Select drinks?", choices, max: 3)
1126
+ # =>
1127
+ # Select drinks? (max. 3) vodka, beer, whisky
1128
+ # ⬢ vodka
1129
+ # ⬢ beer
1130
+ # ⬡ wine
1131
+ # ⬢ whisky
1132
+ # ‣ ⬡ bourbon
1133
+ ```
1134
+
974
1135
  ### 2.6.4 enum_select
975
1136
 
976
1137
  In order to ask for standard selection from indexed list you can use `enum_select` and pass question together with possible choices:
977
1138
 
978
1139
  ```ruby
979
1140
  choices = %w(emacs nano vim)
980
- prompt.enum_select("Select an editor?")
1141
+ prompt.enum_select("Select an editor?", choices)
981
1142
  # =>
982
1143
  #
983
1144
  # Select an editor?
@@ -992,9 +1153,9 @@ Similar to `select` and `multi_select`, you can provide question options through
992
1153
  ```ruby
993
1154
  choices = %w(nano vim emacs)
994
1155
  prompt.enum_select("Select an editor?") do |menu|
995
- menu.choice :nano, '/bin/nano'
996
- menu.choice :vim, '/usr/bin/vim'
997
- menu.choice :emacs, '/usr/bin/emacs'
1156
+ menu.choice :nano, "/bin/nano"
1157
+ menu.choice :vim, "/usr/bin/vim"
1158
+ menu.choice :emacs, "/usr/bin/emacs"
998
1159
  end
999
1160
  # =>
1000
1161
  #
@@ -1007,17 +1168,18 @@ end
1007
1168
  # Select an editor? /bin/nano
1008
1169
  ```
1009
1170
 
1010
- You can change the indexed numbers by passing `enum` option and the default option by using `default` like so
1171
+ You can change the indexed numbers formatting by passing `enum` option. The `default` option lets you specify which choice to mark as selected by default. It accepts an index of the choice starting from `1` or a choice name:
1011
1172
 
1012
1173
  ```ruby
1013
1174
  choices = %w(nano vim emacs)
1014
1175
  prompt.enum_select("Select an editor?") do |menu|
1015
1176
  menu.default 2
1016
- menu.enum '.'
1177
+ # or menu.defualt "/usr/bin/vim"
1178
+ menu.enum "."
1017
1179
 
1018
- menu.choice :nano, '/bin/nano'
1019
- menu.choice :vim, '/usr/bin/vim'
1020
- menu.choice :emacs, '/usr/bin/emacs'
1180
+ menu.choice :nano, "/bin/nano"
1181
+ menu.choice :vim, "/usr/bin/vim"
1182
+ menu.choice :emacs, "/usr/bin/emacs"
1021
1183
  end
1022
1184
  # =>
1023
1185
  #
@@ -1030,10 +1192,12 @@ end
1030
1192
  # Select an editor? /usr/bin/vim
1031
1193
  ```
1032
1194
 
1195
+ #### 2.6.4.1 `:per_page`
1196
+
1033
1197
  By default the menu is paginated if selection grows beyond `6` items. To change this setting use `:per_page` configuration.
1034
1198
 
1035
1199
  ```ruby
1036
- letters = ('A'..'Z').to_a
1200
+ letters = ("A".."Z").to_a
1037
1201
  prompt.enum_select("Choose your letter?", letters, per_page: 4)
1038
1202
  # =>
1039
1203
  # Which letter?
@@ -1045,25 +1209,56 @@ prompt.enum_select("Choose your letter?", letters, per_page: 4)
1045
1209
  # (Press tab/right or left to reveal more choices)
1046
1210
  ```
1047
1211
 
1212
+ #### 2.6.4.2 `:disabled`
1213
+
1214
+ To make a choice unavailable use the `:disabled` option and, if you wish, as value provide a reason:
1215
+
1216
+ ```ruby
1217
+ choices = [
1218
+ {name: "Emacs", disabled: "(not installed)"},
1219
+ "Atom",
1220
+ "GNU nano",
1221
+ {name: "Notepad++", disabled: "(not installed)"},
1222
+ "Sublime",
1223
+ "Vim"
1224
+ ]
1225
+ ```
1226
+
1227
+ The disabled choice will be displayed with a cross ✘ character next to it and followed by an explanation:
1228
+
1229
+
1230
+ ```ruby
1231
+ prompt.enum_select("Select an editor", choices)
1232
+ # =>
1233
+ # Select an editor
1234
+ # ✘ 1) Emacs (not installed)
1235
+ # 2) Atom
1236
+ # 3) GNU nano
1237
+ # ✘ 4) Notepad++ (not installed)
1238
+ # 5) Sublime
1239
+ # 6) Vim
1240
+ # Choose 1-6 [2]:
1241
+ ```
1242
+
1048
1243
  ### 2.7 expand
1049
1244
 
1050
1245
  The `expand` provides a compact way to ask a question with many options.
1051
1246
 
1052
- As first argument `expand` takes the message to display and as a second an array of choices. Compared to the `select`, `multi_select` and `enum_select`, the choices need to be objects that include `:key`, `:name` and `:value` keys. The `:key` must be a single character. The help choice is added automatically as the last option and the key `h`.
1247
+ As first argument `expand` takes the message to display and as a second an array of choices. Compared to the `select`, `multi_select` and `enum_select`, the choices need to be objects that include `:key`, `:name` and `:value` keys. The `:key` must be a single character. The help choice is added automatically as the last option under the key `h`.
1053
1248
 
1054
1249
  ```ruby
1055
1250
  choices = [
1056
1251
  {
1057
- key: 'y',
1058
- name: 'overwrite this file',
1252
+ key: "y",
1253
+ name: "overwrite this file",
1059
1254
  value: :yes
1060
1255
  }, {
1061
- key: 'n',
1062
- name: 'do not overwrite this file',
1256
+ key: "n",
1257
+ name: "do not overwrite this file",
1063
1258
  value: :no
1064
1259
  }, {
1065
- key: 'q',
1066
- name: 'quit; do not overwrite this file ',
1260
+ key: "q",
1261
+ name: "quit; do not overwrite this file ",
1067
1262
  value: :quit
1068
1263
  }
1069
1264
  ]
@@ -1072,19 +1267,19 @@ choices = [
1072
1267
  The choices can also be provided through DSL using the `choice` method. The `:value` can be a primitive value or `Proc` instance that gets executed and whose value is used as returned type. For example:
1073
1268
 
1074
1269
  ```ruby
1075
- prompt.expand('Overwrite Gemfile?') do |q|
1076
- q.choice key: 'y', name: 'Overwrite' do :ok end
1077
- q.choice key: 'n', name: 'Skip', value: :no
1078
- q.choice key: 'a', name: 'Overwrite all', value: :all
1079
- q.choice key: 'd', name: 'Show diff', value: :diff
1080
- q.choice key: 'q', name: 'Quit', value: :quit
1270
+ prompt.expand("Overwrite Gemfile?") do |q|
1271
+ q.choice key: "y", name: "Overwrite" do :ok end
1272
+ q.choice key: "n", name: "Skip", value: :no
1273
+ q.choice key: "a", name: "Overwrite all", value: :all
1274
+ q.choice key: "d", name: "Show diff", value: :diff
1275
+ q.choice key: "q", name: "Quit", value: :quit
1081
1276
  end
1082
1277
  ```
1083
1278
 
1084
1279
  The first element in the array of choices or provided via `choice` DSL will be the default choice, you can change that by passing `default` option.
1085
1280
 
1086
1281
  ```ruby
1087
- prompt.expand('Overwrite Gemfile?', choices)
1282
+ prompt.expand("Overwrite Gemfile?", choices)
1088
1283
  # =>
1089
1284
  # Overwrite Gemfile? (enter "h" for help) [y,n,q,h]
1090
1285
  ```
@@ -1109,6 +1304,17 @@ If user types `h` and presses enter, an expanded view will be shown which furthe
1109
1304
 
1110
1305
  Run `examples/expand.rb` to see the prompt in action.
1111
1306
 
1307
+ #### 2.7.1 `:auto_hint`
1308
+
1309
+ To show hint by default use `:auto_hint` option:
1310
+
1311
+ ```ruby
1312
+ prompt.expand("Overwrite Gemfile?", choices, auto_hint: true)
1313
+ # =>
1314
+ # Overwrite Gemfile? (enter "h" for help) [y,n,q,h]
1315
+ # >> overwrite this file
1316
+ ```
1317
+
1112
1318
  ### 2.8 collect
1113
1319
 
1114
1320
  In order to collect more than one answer use `collect` method. Using the `key` you can describe the answers key name. All the methods for asking user input such as `ask`, `mask`, `select` can be directly invoked on the key. The key composition is very flexible by allowing nested keys. If you want the value to be automatically converted to required type use [convert](#221-convert).
@@ -1117,14 +1323,14 @@ For example to gather some contact information do:
1117
1323
 
1118
1324
  ```ruby
1119
1325
  prompt.collect do
1120
- key(:name).ask('Name?')
1326
+ key(:name).ask("Name?")
1121
1327
 
1122
- key(:age).ask('Age?', convert: :int)
1328
+ key(:age).ask("Age?", convert: :int)
1123
1329
 
1124
1330
  key(:address) do
1125
- key(:street).ask('Street?', required: true)
1126
- key(:city).ask('City?')
1127
- key(:zip).ask('Zip?', validate: /\A\d{3}\Z/)
1331
+ key(:street).ask("Street?", required: true)
1332
+ key(:city).ask("City?")
1333
+ key(:zip).ask("Zip?", validate: /\A\d{3}\Z/)
1128
1334
  end
1129
1335
  end
1130
1336
  # =>
@@ -1133,17 +1339,17 @@ end
1133
1339
 
1134
1340
  In order to collect _mutliple values_ for a given key in a loop, chain `values` onto the `key` desired:
1135
1341
 
1136
- ```rb
1342
+ ```ruby
1137
1343
  result = prompt.collect do
1138
- key(:name).ask('Name?')
1344
+ key(:name).ask("Name?")
1139
1345
 
1140
- key(:age).ask('Age?', convert: :int)
1346
+ key(:age).ask("Age?", convert: :int)
1141
1347
 
1142
1348
  while prompt.yes?("continue?")
1143
1349
  key(:addresses).values do
1144
- key(:street).ask('Street?', required: true)
1145
- key(:city).ask('City?')
1146
- key(:zip).ask('Zip?', validate: /\A\d{3}\Z/)
1350
+ key(:street).ask("Street?", required: true)
1351
+ key(:city).ask("City?")
1352
+ key(:zip).ask("Zip?", validate: /\A\d{3}\Z/)
1147
1353
  end
1148
1354
  end
1149
1355
  end
@@ -1163,7 +1369,7 @@ end
1163
1369
  To suggest possible matches for the user input use `suggest` method like so:
1164
1370
 
1165
1371
  ```ruby
1166
- prompt.suggest('sta', ['stage', 'stash', 'commit', 'branch'])
1372
+ prompt.suggest("sta", ["stage", "stash", "commit", "branch"])
1167
1373
  # =>
1168
1374
  # Did you mean one of these?
1169
1375
  # stage
@@ -1174,7 +1380,7 @@ To customize query text presented pass `:single_text` and `:plural_text` options
1174
1380
 
1175
1381
  ```ruby
1176
1382
  possible = %w(status stage stash commit branch blame)
1177
- prompt.suggest('b', possible, indent: 4, single_text: 'Perhaps you meant?')
1383
+ prompt.suggest("b", possible, indent: 4, single_text: "Perhaps you meant?")
1178
1384
  # =>
1179
1385
  # Perhaps you meant?
1180
1386
  # blame
@@ -1182,33 +1388,51 @@ prompt.suggest('b', possible, indent: 4, single_text: 'Perhaps you meant?')
1182
1388
 
1183
1389
  ### 2.10 slider
1184
1390
 
1185
- If you have constrained range of numbers for user to choose from you may consider using `slider`.
1391
+ If you'd rather not display all possible values in a vertical list, you may consider using `slider`. The slider provides easy visual way of picking a value marked by `●` symbol.
1186
1392
 
1187
- The slider provides easy visual way of picking a value marked by `O` marker. You can set `:min`(defaults to 0), `:max` and `:step`(defaults to 1) options to configure slider range:
1393
+ For integers, you can set `:min`(defaults to 0), `:max` and `:step`(defaults to 1) options to configure slider range:
1188
1394
 
1189
1395
  ```ruby
1190
- prompt.slider('Volume', max: 100, step: 5)
1396
+ prompt.slider("Volume", min: 0, max: 100, step: 5)
1191
1397
  # =>
1192
- # Volume ──────────O────────── 50
1193
- # (Use arrow keys, press Enter to select)
1398
+ # Volume ──────────●────────── 50
1399
+ # (Use ←/→ arrow keys, press Enter to select)
1400
+ ```
1401
+
1402
+ For everything else, you can provide an array of your desired choices:
1403
+
1404
+ ```ruby
1405
+ prompt.slider("Letter", ('a'..'z').to_a)
1406
+ # =>
1407
+ # Letter ────────────●───────────── m
1408
+ # (Use ←/→ arrow keys, press Enter to select)
1194
1409
  ```
1195
1410
 
1196
1411
  By default the slider is configured to pick middle of the range as a start value, you can change this by using the `:default` option:
1197
1412
 
1198
1413
  ```ruby
1199
- prompt.slider('Volume', max: 100, step: 5, default: 75)
1414
+ prompt.slider("Volume", max: 100, step: 5, default: 75)
1415
+ # =>
1416
+ # Volume ───────────────●────── 75
1417
+ # (Use ←/→ arrow keys, press Enter to select)
1418
+ ```
1419
+
1420
+ You can also select the default value by name:
1421
+
1422
+ ```ruby
1423
+ prompt.slider("Letter", ('a'..'z').to_a, default: 'q')
1200
1424
  # =>
1201
- # Volume ───────────────O───── 75
1202
- # (Use arrow keys, press Enter to select)
1425
+ # Letter ──────────────────●─────── q
1426
+ # (Use ←/→ arrow keys, press Enter to select)
1203
1427
  ```
1204
1428
 
1205
- You can also change the default slider formatting using the `:format`. The value must contain the `:slider` token for placing the actual animation and any `sprintf` compatible flag for number display, in our case `%d`:
1429
+ You can also change the default slider formatting using the `:format`. The value must contain the `:slider` token to show current value and any `sprintf` compatible flag for number display, in our case `%d`:
1206
1430
 
1207
1431
  ```ruby
1208
- prompt.slider('Volume', max: 100, step: 5, default: 75, format: "|:slider| %d%")
1432
+ prompt.slider("Volume", max: 100, step: 5, default: 75, format: "|:slider| %d%%")
1209
1433
  # =>
1210
- # Volume |───────────────O─────| 75%
1211
- # (Use arrow keys, press Enter to select)
1434
+ # Volume |───────────────●──────| 75%
1435
+ # (Use ←/→ arrow keys, press Enter to select)
1212
1436
  ```
1213
1437
 
1214
1438
  You can also specify slider range with decimal numbers. For example, to have a step of `0.5` and display each value with a single decimal place use `%f` as format:
@@ -1216,27 +1440,67 @@ You can also specify slider range with decimal numbers. For example, to have a s
1216
1440
  ```ruby
1217
1441
  prompt.slider("Volume", max: 10, step: 0.5, default: 5, format: "|:slider| %.1f")
1218
1442
  # =>
1219
- # Volume |───────────────O─────| 7.5
1220
- # (Use arrow keys, press Enter to select)
1443
+ # Volume |───────────────●──────| 7.5
1444
+ # (Use ←/→ arrow keys, press Enter to select)
1445
+ ```
1446
+
1447
+ You can alternatively provide a proc/lambda to customize your formatting even further:
1448
+
1449
+ ```ruby
1450
+ slider_format = -> (slider, value) { "|#{slider}| #{value.zero? ? "muted" : "%.1f"}" % value }
1451
+ prompt.slider("Volume", max: 10, step: 0.5, default: 0, format: slider_format)
1452
+ # =>
1453
+ # Volume |●─────────────────────| muted
1454
+ # (Use ←/→ arrow keys, press Enter to select)
1455
+ ```
1456
+
1457
+ If you wish to change the slider handle and the slider range display use `:symbols` option:
1458
+
1459
+ ```ruby
1460
+ prompt.slider("Volume", max: 100, step: 5, default: 75, symbols: {bullet: "x", line: "_"})
1461
+ # =>
1462
+ # Volume _______________x______ 75%
1463
+ # (Use ←/→ arrow keys, press Enter to select)
1464
+ ```
1465
+
1466
+ You can configure help message with `:help` and when to display with `:show_help` options. The help can be displayed on `start`, `never` or `always`:
1467
+
1468
+ ```ruby
1469
+ prompt.slider("Volume", max: 10, default: 7, help: "(Move arrows left and right to set value)", show_help: :always)
1470
+ # =>
1471
+ # Volume ───────────────●────── 7
1472
+ # (Move arrows left and right to set value)
1221
1473
  ```
1222
1474
 
1223
1475
  Slider can be configured through DSL as well:
1224
1476
 
1225
1477
  ```ruby
1226
- prompt.slider('What size?') do |range|
1478
+ prompt.slider("What size?") do |range|
1227
1479
  range.max 100
1228
1480
  range.step 5
1229
1481
  range.default 75
1230
- range.format "|:slider| %d%"
1482
+ range.format "|:slider| %d%%"
1483
+ end
1484
+ # =>
1485
+ # Volume |───────────────●──────| 75%
1486
+ # (Use ←/→ arrow keys, press Enter to select)
1487
+ ```
1488
+
1489
+ ```ruby
1490
+ prompt.slider("What letter?") do |range|
1491
+ range.choices ('a'..'z').to_a
1492
+ range.format "|:slider| %s"
1493
+ range.default 'q'
1231
1494
  end
1232
1495
  # =>
1233
- # Volume |───────────────O─────| 75%
1234
- # (Use arrow keys, press Enter to select)
1496
+ # What letter? |──────────────────●───────| q
1497
+ # (Use ←/→ arrow keys, press Enter to select)
1235
1498
  ```
1236
1499
 
1500
+
1237
1501
  ### 2.11 say
1238
1502
 
1239
- To simply print message out to stdout use `say` like so:
1503
+ To simply print message out to standard output use `say` like so:
1240
1504
 
1241
1505
  ```ruby
1242
1506
  prompt.say(...)
@@ -1289,11 +1553,11 @@ For example, to add vim like key navigation to `select` prompt one would do the
1289
1553
 
1290
1554
  ```ruby
1291
1555
  prompt.on(:keypress) do |event|
1292
- if event.value == 'j'
1556
+ if event.value == "j"
1293
1557
  prompt.trigger(:keydown)
1294
1558
  end
1295
1559
 
1296
- if event.value == 'k'
1560
+ if event.value == "k"
1297
1561
  prompt.trigger(:keyup)
1298
1562
  end
1299
1563
  end
@@ -1324,50 +1588,117 @@ The available events are:
1324
1588
 
1325
1589
  ## 3 settings
1326
1590
 
1327
- ### 3.1 active_color
1591
+ ### 3.1. `:symbols`
1328
1592
 
1329
- All prompt types support `:active_color` option. In case of `select`, `multi_select`, `enum_select` or `expand` this color is used to highlight the currently selected choice. All the resulted inputs provided by user that are read in by the prompt as answer are highlighted with this color. This option can be applied either globally for all prompts or individually.
1593
+ Many prompts use symbols to display information. You can overwrite the default symbols for all the prompts using the `:symbols` key and hash of symbol names as value:
1594
+
1595
+ ```ruby
1596
+ prompt = TTY::Prompt.new(symbols: {marker: ">"})
1597
+ ```
1598
+
1599
+ The following symbols can be overwritten:
1600
+
1601
+ | Symbols | Unicode | ASCII |
1602
+ | ----------- |:-------:|:-----:|
1603
+ | tick | `✓` | `√` |
1604
+ | cross | `✘` | `x` |
1605
+ | marker | `‣` | `>` |
1606
+ | dot | `•` | `.` |
1607
+ | bullet | `●` | `O` |
1608
+ | line | `─` | `-` |
1609
+ | radio_on | `⬢` | `(*)` |
1610
+ | radio_off | `⬡` | `( )` |
1611
+ | arrow_up | `↑` | `↑` |
1612
+ | arrow_down | `↓` | `↓` |
1613
+ | arrow_left | `←` | `←` |
1614
+ | arrow_right| `→` | `→` |
1615
+
1616
+ ### 3.2 `:active_color`
1617
+
1618
+ All prompt types support `:active_color` option. By default it's set to `:green` value.
1619
+
1620
+ The `select`, `multi_select`, `enum_select` and `expand` prompts use the active color to highlight the currently selected choice.
1621
+
1622
+ The answer provided by the user is also highlighted with the active color.
1623
+
1624
+ This `:active_color` as value accepts either a color symbol or callable object.
1625
+
1626
+ For example, to change all prompts active color to `:cyan` do:
1330
1627
 
1331
1628
  ```ruby
1332
1629
  prompt = TTY::Prompt.new(active_color: :cyan)
1333
1630
  ```
1334
1631
 
1335
- or per individual input do:
1632
+ You could also use `pastel`:
1336
1633
 
1337
1634
  ```ruby
1338
- prompt.select('What size?', %w(Large Medium Small), active_color: :cyan)
1635
+ notice = Pastel.new.cyan.on_blue.detach
1636
+ prompt = TTY::Prompt.new(active_color: notice)
1637
+ ````
1638
+
1639
+ Or use coloring of your own choice:
1640
+
1641
+ ```
1642
+ prompt = TTY::Prompt.new(active_color: ->(str) { my-color-gem(str) })
1643
+ ```
1644
+
1645
+ This option can be applied either globally for all prompts or individually:
1646
+
1647
+ ```ruby
1648
+ prompt.select("What size?", %w(Large Medium Small), active_color: :cyan)
1339
1649
  ```
1340
1650
 
1341
1651
  Please [see pastel](https://github.com/piotrmurach/pastel#3-supported-colors) for all supported colors.
1342
1652
 
1343
- ### 3.2 enable_color
1653
+ ### 3.3 `:enable_color`
1344
1654
 
1345
1655
  If you wish to disable coloring for a prompt simply pass `:enable_color` option
1346
1656
 
1347
1657
  ```ruby
1348
- prompt = TTY::Prompt.new(enable_color: true)
1658
+ prompt = TTY::Prompt.new(enable_color: false)
1349
1659
  ```
1350
1660
 
1351
- ### 3.3 help_color
1661
+ ### 3.4 `:help_color`
1352
1662
 
1353
- Prompts such as `select`, `multi_select`, `expand` support `:help_color` which is used to customize the help text. This option can be applied either globally for all prompts or individually.
1663
+ The `:help_color` option is used to customize the display color for all the help text. By default it's set to `:bright_black` value.
1664
+
1665
+ Prompts such as `select`, `multi_select`, `expand` support `:help_color`. This option can be applied either globally for all prompts or individually.
1666
+
1667
+ The `:help_color` option as value accepts either a color symbol or callable object.
1668
+
1669
+ For example, to change all prompts help color to `:cyan` do:
1354
1670
 
1355
1671
  ```ruby
1356
1672
  prompt = TTY::Prompt.new(help_color: :cyan)
1357
1673
  ```
1358
1674
 
1359
- or per individual input do:
1675
+ You could also use `pastel`:
1676
+
1677
+ ```ruby
1678
+ notice = Pastel.new.cyan.on_blue.detach
1679
+ prompt = TTY::Prompt.new(help_color: notice)
1680
+ ````
1681
+
1682
+ Or use coloring of your own choice:
1683
+
1684
+ ```ruby
1685
+ prompt = TTY::Prompt.new(help_color: ->(str) { my-color-gem(str) })
1686
+ ```
1687
+
1688
+ Or configure `:help_color` for an individual prompt:
1360
1689
 
1361
1690
  ```ruby
1362
- prompt.select('What size?', %w(Large Medium Small), help_color: :cyan)
1691
+ prompt.select("What size?", %w(Large Medium Small), help_color: :cyan)
1363
1692
  ```
1364
1693
 
1365
- ### 3.4 interrupt
1694
+ Please [see pastel](https://github.com/piotrmurach/pastel#3-supported-colors) for all supported colors.
1695
+
1696
+ ### 3.5 `:interrupt`
1366
1697
 
1367
1698
  By default `InputInterrupt` error will be raised when the user hits the interrupt key(Control-C). However, you can customise this behaviour by passing the `:interrupt` option. The available options are:
1368
1699
 
1369
1700
  * `:signal` - sends interrupt signal
1370
- * `:exit` - exists with status code
1701
+ * `:exit` - exits with status code
1371
1702
  * `:noop` - skips handler
1372
1703
  * custom proc
1373
1704
 
@@ -1377,15 +1708,26 @@ For example, to send interrupt signal do:
1377
1708
  prompt = TTY::Prompt.new(interrupt: :signal)
1378
1709
  ```
1379
1710
 
1380
- ### 3.5 prefix
1711
+ ### 3.6 `:prefix`
1381
1712
 
1382
1713
  You can prefix each question asked using the `:prefix` option. This option can be applied either globally for all prompts or individual for each one:
1383
1714
 
1384
1715
  ```ruby
1385
- prompt = TTY::Prompt.new(prefix: '[?] ')
1716
+ prompt = TTY::Prompt.new(prefix: "[?] ")
1386
1717
  ```
1387
1718
 
1388
- ### 3.6 track_history
1719
+ ### 3.7 `:quiet`
1720
+
1721
+ Prompts such as `select`, `multi_select`, `expand`, `slider` support `:quiet` which is used to disable re-echoing of the question and answer after selection is done. This option can be applied either globally for all prompts or individually.
1722
+
1723
+ ```ruby
1724
+ # global
1725
+ prompt = TTY::Prompt.new(quiet: true)
1726
+ # single prompt
1727
+ prompt.select("What is your favorite color?", %w(blue yellow orange))
1728
+ ````
1729
+
1730
+ ### 3.8 `:track_history`
1389
1731
 
1390
1732
  The prompts that accept line input such as `multiline` or `ask` provide history buffer that tracks all the lines entered during `TTY::Prompt.new` interactions. The history buffer provides previous or next lines when user presses up/down arrows respectively. However, if you wish to disable this behaviour use `:track_history` option like so:
1391
1733