tty-prompt 0.18.0 → 0.22.0

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