tty-prompt 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -2
- data/CHANGELOG.md +12 -0
- data/README.md +223 -59
- data/lib/tty/prompt/choice.rb +83 -0
- data/lib/tty/prompt/choices.rb +92 -0
- data/lib/tty/prompt/codes.rb +32 -0
- data/lib/tty/prompt/cursor.rb +131 -0
- data/lib/tty/prompt/list.rb +209 -0
- data/lib/tty/prompt/mode/echo.rb +10 -9
- data/lib/tty/prompt/mode/raw.rb +10 -9
- data/lib/tty/prompt/multi_list.rb +105 -0
- data/lib/tty/prompt/question/validation.rb +12 -27
- data/lib/tty/prompt/question.rb +58 -107
- data/lib/tty/prompt/reader.rb +44 -11
- data/lib/tty/prompt/response.rb +31 -36
- data/lib/tty/prompt/response_delegation.rb +3 -2
- data/lib/tty/prompt/statement.rb +10 -10
- data/lib/tty/prompt/test.rb +15 -0
- data/lib/tty/prompt/version.rb +3 -3
- data/lib/tty/prompt.rb +72 -9
- data/lib/tty-prompt.rb +11 -0
- data/spec/unit/ask_spec.rb +32 -35
- data/spec/unit/choice/eql_spec.rb +24 -0
- data/spec/unit/choice/from_spec.rb +25 -0
- data/spec/unit/choices/add_spec.rb +14 -0
- data/spec/unit/choices/each_spec.rb +15 -0
- data/spec/unit/choices/new_spec.rb +12 -0
- data/spec/unit/choices/pluck_spec.rb +11 -0
- data/spec/unit/cursor/new_spec.rb +74 -0
- data/spec/unit/error_spec.rb +4 -8
- data/spec/unit/multi_select_spec.rb +163 -0
- data/spec/unit/question/character_spec.rb +5 -16
- data/spec/unit/question/default_spec.rb +4 -10
- data/spec/unit/question/in_spec.rb +15 -12
- data/spec/unit/question/initialize_spec.rb +1 -6
- data/spec/unit/question/modify_spec.rb +25 -24
- data/spec/unit/question/required_spec.rb +31 -0
- data/spec/unit/question/validate_spec.rb +25 -17
- data/spec/unit/question/validation/call_spec.rb +22 -0
- data/spec/unit/response/read_bool_spec.rb +38 -27
- data/spec/unit/response/read_char_spec.rb +5 -8
- data/spec/unit/response/read_date_spec.rb +8 -12
- data/spec/unit/response/read_email_spec.rb +25 -22
- data/spec/unit/response/read_multiple_spec.rb +11 -13
- data/spec/unit/response/read_number_spec.rb +12 -16
- data/spec/unit/response/read_range_spec.rb +10 -13
- data/spec/unit/response/read_spec.rb +39 -38
- data/spec/unit/response/read_string_spec.rb +7 -12
- data/spec/unit/say_spec.rb +10 -14
- data/spec/unit/select_spec.rb +192 -0
- data/spec/unit/statement/initialize_spec.rb +0 -4
- data/spec/unit/suggest_spec.rb +6 -9
- data/spec/unit/warn_spec.rb +4 -8
- metadata +32 -8
- data/spec/unit/question/argument_spec.rb +0 -30
- data/spec/unit/question/valid_spec.rb +0 -46
- data/spec/unit/question/validation/valid_value_spec.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e24965d09c08a3bf136438bad66551d05f25a0f
|
4
|
+
data.tar.gz: 476702a67dd13fe4796c888d089107f4b6f7f18d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0645bb40ca7b847976e69d0d3c65e4e0a9441f4e3bade6ef1e0d38e7d9ef28e66132645aa30740c7a258939fe262664ed93306968eb76969bee768029d19c406
|
7
|
+
data.tar.gz: 70c03c2eb72010d0efe7d8a125c285dc32ec34117e29e2a44b17839c645a8b1650dd14d1184b7b8a871dc92b2c44121ab1e727aa9f5ca41c893184b678171fc8
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
0.2.0 (Nov 23, 2015)
|
2
|
+
|
3
|
+
* Add ability to select choice form list #select
|
4
|
+
* Add ability to select multiple options #multi_select
|
5
|
+
* Change #ask api to be similar to #select and #multi_select behaviour
|
6
|
+
* Change #ask :argument option to be :required
|
7
|
+
* Add :read option to #ask for reading specific type input
|
8
|
+
* Remove :valid option from #ask as #select is a better solution
|
9
|
+
|
10
|
+
0.1.0 (Nov 1, 2015)
|
11
|
+
|
12
|
+
* Initial implementation and release
|
data/README.md
CHANGED
@@ -17,8 +17,8 @@
|
|
17
17
|
|
18
18
|
## Features
|
19
19
|
|
20
|
+
* Number of prompt types for gathering user input
|
20
21
|
* A robust API for getting and validating complex inputs
|
21
|
-
* Number of coercion methods for converting response into Ruby types
|
22
22
|
|
23
23
|
## Installation
|
24
24
|
|
@@ -41,10 +41,12 @@ Or install it yourself as:
|
|
41
41
|
* [1. Usage](#1-usage)
|
42
42
|
* [2. Interface](#2-interface)
|
43
43
|
* [2.1 ask](#21-ask)
|
44
|
-
|
45
|
-
|
46
|
-
* [2.
|
47
|
-
|
44
|
+
* [2.1.1 settings](#211-settings)
|
45
|
+
* [2.1.2 valid read keywords](#212-valid-read-keywords)
|
46
|
+
* [2.2 select](#22-select)
|
47
|
+
* [2.3 multi_select](#23-multi_select)
|
48
|
+
* [2.4 say](#25-say)
|
49
|
+
* [2.5 suggest](#26-suggest)
|
48
50
|
|
49
51
|
## 1. Usage
|
50
52
|
|
@@ -54,101 +56,263 @@ In order to start asking questions on the command line, create prompt:
|
|
54
56
|
prompt = TTY::Prompt.new
|
55
57
|
```
|
56
58
|
|
57
|
-
and then call `ask` with the question
|
59
|
+
and then call `ask` with the question for simple input:
|
58
60
|
|
59
61
|
```ruby
|
60
|
-
|
62
|
+
prompt.ask('Do you like Ruby?', type: :bool) # => true
|
61
63
|
```
|
62
64
|
|
63
|
-
|
65
|
+
Asking question with list of options couldn't be easier using `select` like so:
|
64
66
|
|
65
67
|
```ruby
|
66
|
-
|
68
|
+
prompt.select("Choose your destiny?", %w(Scorpion Kano Jax))
|
69
|
+
# =>
|
70
|
+
# Choose your destiny? (Use arrow keys, press Enter to select)
|
71
|
+
# ‣ Scorpion
|
72
|
+
# Kano
|
73
|
+
# Jax
|
74
|
+
```
|
75
|
+
|
76
|
+
Also, asking multiple choice questions is a breeze with `multi_select`:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
choices = %w(vodka beer wine whisky bourbon)
|
80
|
+
prompt.select("Select drinks?", choices)
|
81
|
+
# =>
|
82
|
+
#
|
83
|
+
# Select drinks? (Use arrow keys, press Space to select and Enter to finish)"
|
84
|
+
# ‣ ⬡ vodka
|
85
|
+
# ⬡ beer
|
86
|
+
# ⬡ wine
|
87
|
+
# ⬡ whisky
|
88
|
+
# ⬡ bourbon
|
67
89
|
```
|
68
90
|
|
69
91
|
## 2. Interface
|
70
92
|
|
71
93
|
### 2.1 ask
|
72
94
|
|
73
|
-
In order to ask a basic question
|
95
|
+
In order to ask a basic question with a string answer do:
|
74
96
|
|
75
97
|
```ruby
|
76
|
-
answer = prompt.ask("What is your name?")
|
98
|
+
answer = prompt.ask("What is your name?")
|
77
99
|
```
|
78
100
|
|
79
|
-
|
101
|
+
In order to prompt for more complex input you can use robust API by passing hash of properties or using block:
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
prompt.ask("What is your name?") do |q|
|
105
|
+
q.required true
|
106
|
+
q.validate /\A\w+\Z/
|
107
|
+
q.modify :capitalize
|
108
|
+
end
|
109
|
+
```
|
110
|
+
|
111
|
+
#### 2.1.1 settings
|
112
|
+
|
113
|
+
Below is a list of the settings that may be used for customizing `ask` method behaviour:
|
80
114
|
|
81
115
|
```ruby
|
82
|
-
argument # :required or :optional
|
83
116
|
char # turn character based input, otherwise line (default: false)
|
84
|
-
clean # reset question
|
85
117
|
default # default value used if none is provided
|
86
118
|
echo # turn echo on and off (default: true)
|
119
|
+
in # specify range '0-9', '0..9', '0...9' or negative '-1..-9'
|
87
120
|
mask # mask characters i.e '****' (default: false)
|
88
121
|
modify # apply answer modification :upcase, :downcase, :trim, :chomp etc..
|
89
|
-
|
90
|
-
|
91
|
-
|
122
|
+
read # Specifies the type of input such as :bool, :string [see](#211-valid-read-keywords)
|
123
|
+
required # If true, value entered must be non-empty (default: false)
|
124
|
+
validate # regex, proc against which stdin input is checked
|
92
125
|
```
|
93
126
|
|
94
|
-
|
127
|
+
Validate setting can take `Regex`, `Proc` like so:
|
95
128
|
|
96
129
|
```ruby
|
97
|
-
prompt.ask(
|
130
|
+
prompt.ask('What is your username?') { |q|
|
131
|
+
q.validate { |input| input =~ (/^[^\.]+\.[^\.]+/) }
|
132
|
+
}
|
133
|
+
```
|
134
|
+
|
135
|
+
For example, if we wanted to ask a user for a single digit in given range
|
98
136
|
|
99
|
-
|
100
|
-
|
101
|
-
default 'Piotr'
|
102
|
-
validate /\w+\s\w+/
|
103
|
-
valid ['Piotr', 'Piotrek']
|
104
|
-
modify :capitalize
|
105
|
-
end.read_string
|
137
|
+
```ruby
|
138
|
+
ask("Provide number in range: 0-9") { |q| q.in('0-9') }
|
106
139
|
```
|
107
140
|
|
108
|
-
|
141
|
+
#### 2.1.2 valid read keywords
|
109
142
|
|
110
|
-
|
143
|
+
The most common thing to do is to cast the answer to specific type. The `read` property is used for that. By default `:string` answer is assumed but this can be changed using one of the following custom readers:
|
111
144
|
|
112
145
|
```ruby
|
113
|
-
|
146
|
+
:bool # true or false for strings such as "Yes", "No"
|
147
|
+
:char # first character
|
148
|
+
:date # date type
|
149
|
+
:datetime # datetime type
|
150
|
+
:email # validate answer against email regex
|
151
|
+
:file # a File object
|
152
|
+
:float # decimal or error if cannot convert
|
153
|
+
:int # integer or error if cannot convert
|
154
|
+
:multiline # multiple line string
|
155
|
+
:password # string with echo turned off
|
156
|
+
:range # range type
|
157
|
+
:regex # regex expression
|
158
|
+
:string # string
|
159
|
+
:symbol # symbol
|
160
|
+
:text # multiline string
|
161
|
+
:keypress # the key pressed
|
114
162
|
```
|
115
163
|
|
116
|
-
|
164
|
+
For example, if you are interested in range type as answer do the following:
|
117
165
|
|
118
166
|
```ruby
|
119
|
-
|
120
|
-
read_char # return first character
|
121
|
-
read_date # return date type
|
122
|
-
read_datetime # return datetime type
|
123
|
-
read_email # validate answer against email regex
|
124
|
-
read_file # return a File object
|
125
|
-
read_float # return decimal or error if cannot convert
|
126
|
-
read_int # return integer or error if cannot convert
|
127
|
-
read_multiple # return multiple line string
|
128
|
-
read_password # return string with echo turned off
|
129
|
-
read_range # return range type
|
130
|
-
read_regex # return regex expression
|
131
|
-
read_string # return string
|
132
|
-
read_symbol # return symbol
|
133
|
-
read_text # return multiline string
|
134
|
-
read_keypress # return the key pressed
|
167
|
+
ask("Provide range of numbers?", read: :range)
|
135
168
|
```
|
136
169
|
|
137
|
-
|
170
|
+
### 2.2 select
|
171
|
+
|
172
|
+
For asking questions involving list of options use `select` method by passing the question and possible choices:
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
prompt.select("Choose your destiny?", %w(Scorpion Kano Jax))
|
176
|
+
# =>
|
177
|
+
# Choose your destiny? (Use arrow keys, press Enter to select)
|
178
|
+
# ‣ Scorpion
|
179
|
+
# Kano
|
180
|
+
# Jax
|
181
|
+
```
|
182
|
+
|
183
|
+
You can also provide options through DSL using the `choice` method for single entry and/or `choices` call for more than one choice:
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
prompt.select("Choose your destiny?") do |menu|
|
187
|
+
menu.choice 'Scorpion'
|
188
|
+
menu.choice 'Kano'
|
189
|
+
menu.choice 'Jax'
|
190
|
+
end
|
191
|
+
# =>
|
192
|
+
# Choose your destiny? (Use arrow keys, press Enter to select)
|
193
|
+
# ‣ Scorpion
|
194
|
+
# Kano
|
195
|
+
# Jax
|
196
|
+
```
|
197
|
+
|
198
|
+
By default the choice name is used as return value, but you can provide your custom values:
|
199
|
+
|
200
|
+
```ruby
|
201
|
+
prompt.select("Choose your destiny?") do |menu|
|
202
|
+
menu.choice 'Scorpion', 1
|
203
|
+
menu.choice 'Kano', 2
|
204
|
+
menu.choice 'Jax', 3
|
205
|
+
end
|
206
|
+
# =>
|
207
|
+
# Choose your destiny? (Use arrow keys, press Enter to select)
|
208
|
+
# ‣ Scorpion
|
209
|
+
# Kano
|
210
|
+
# Jax
|
211
|
+
```
|
212
|
+
|
213
|
+
If you wish you can also provide a simple hash to denote choice name and its value like so:
|
138
214
|
|
139
215
|
```ruby
|
140
|
-
|
141
|
-
|
142
|
-
|
216
|
+
choices = {'Scorpion' => 1, 'Kano' => 2, 'Jax' => 3}
|
217
|
+
prompt.select("Choose your destiny?", choices)
|
218
|
+
```
|
219
|
+
|
220
|
+
To mark particular answer as selected use `default` with index of the option starting from `1`:
|
221
|
+
|
222
|
+
```ruby
|
223
|
+
prompt.select("Choose your destiny?") do |menu|
|
224
|
+
menu.default 3
|
225
|
+
|
226
|
+
menu.choice 'Scorpion', 1
|
227
|
+
menu.choice 'Kano', 2
|
228
|
+
menu.choice 'Jax', 3
|
229
|
+
end
|
230
|
+
# =>
|
231
|
+
# Choose your destiny? (Use arrow keys, press Enter to select)
|
232
|
+
# Scorpion
|
233
|
+
# Kano
|
234
|
+
# ‣ Jax
|
235
|
+
```
|
236
|
+
|
237
|
+
You can configure help message, marker like so
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
choices = %w(Scorpion Kano Jax)
|
241
|
+
prompt.select("Choose your destiny?", choices, help: "(Bash keyboard)")
|
242
|
+
# =>
|
243
|
+
# Choose your destiny? (Bash keyboard)
|
244
|
+
# ‣ Scorpion
|
245
|
+
# Kano
|
246
|
+
# Jax
|
247
|
+
```
|
248
|
+
|
249
|
+
### 2.3 multi_select
|
250
|
+
|
251
|
+
For asking questions involving multiple selection list use `multi_select` method by passing the question and possible choices:
|
252
|
+
|
253
|
+
```ruby
|
254
|
+
choices = %w(vodka beer wine whisky bourbon)
|
255
|
+
prompt.select("Select drinks?", choices)
|
256
|
+
# =>
|
257
|
+
#
|
258
|
+
# Select drinks? (Use arrow keys, press Space to select and Enter to finish)"
|
259
|
+
# ‣ ⬡ vodka
|
260
|
+
# ⬡ beer
|
261
|
+
# ⬡ wine
|
262
|
+
# ⬡ whisky
|
263
|
+
# ⬡ bourbon
|
264
|
+
```
|
265
|
+
|
266
|
+
As a return value, the `multi_select` will always return an array by default populated with the names of the choices. If you wish to return custom values for the available choices do:
|
267
|
+
|
268
|
+
```ruby
|
269
|
+
choices = {vodka: 1, beer: 2, wine: 3, whisky: 4, bourbon: 5}
|
270
|
+
prompt.select("Select drinks?", choices)
|
271
|
+
|
272
|
+
# Provided that vodka and beer have been selected, the function will return
|
273
|
+
# => [1, 2]
|
274
|
+
```
|
275
|
+
|
276
|
+
Similar to `select` method, you can also provide options through DSL using the `choice` method for single entry and/or `choices` call for more than one choice:
|
277
|
+
|
278
|
+
```ruby
|
279
|
+
prompt.multi_select("Select drinks?") do |menu|
|
280
|
+
menu.choice :vodka, {score: 1}
|
281
|
+
menu.choice :beer, 2
|
282
|
+
menu.choice :wine, 3
|
283
|
+
menu.choices whisky: 4, bourbon: 5
|
284
|
+
end
|
285
|
+
```
|
286
|
+
|
287
|
+
To mark choice(s) as selected use the `default` option with index(s) of the option(s) starting from `1`:
|
288
|
+
|
289
|
+
```ruby
|
290
|
+
prompt.multi_select("Select drinks?") do |menu|
|
291
|
+
menu.default 2, 5
|
292
|
+
|
293
|
+
menu.choice :vodka, {score: 10}
|
294
|
+
menu.choice :beer, {score: 20}
|
295
|
+
menu.choice :wine, {score: 30}
|
296
|
+
menu.choice :whisky, {score: 40}
|
297
|
+
menu.choice :bourbon, {score: 50}
|
298
|
+
end
|
299
|
+
# =>
|
300
|
+
# Select drinks? beer, bourbon
|
301
|
+
# ⬡ vodka
|
302
|
+
# ⬢ beer
|
303
|
+
# ⬡ wine
|
304
|
+
# ⬡ whisky
|
305
|
+
# ‣ ⬢ bourbon
|
143
306
|
```
|
144
307
|
|
145
|
-
|
308
|
+
And when you press enter you will see the following selected:
|
146
309
|
|
147
310
|
```ruby
|
148
|
-
|
311
|
+
# Select drinks? beer, bourbon
|
312
|
+
# => [{score: 20}, {score: 50}]
|
149
313
|
```
|
150
314
|
|
151
|
-
### 2.
|
315
|
+
### 2.4 say
|
152
316
|
|
153
317
|
To simply print message out to stdout use `say` like so:
|
154
318
|
|
@@ -164,16 +328,16 @@ prompt.warn # print message(s) in yellow
|
|
164
328
|
prompt.error # print message(s) in red
|
165
329
|
```
|
166
330
|
|
167
|
-
### 2.
|
331
|
+
### 2.5 suggest
|
168
332
|
|
169
333
|
To suggest possible matches for the user input use `suggest` method like so:
|
170
334
|
|
171
335
|
```ruby
|
172
336
|
prompt.suggest('sta', ['stage', 'stash', 'commit', 'branch'])
|
173
337
|
# =>
|
174
|
-
Did you mean one of these?
|
175
|
-
|
176
|
-
|
338
|
+
# Did you mean one of these?
|
339
|
+
# stage
|
340
|
+
# stash
|
177
341
|
```
|
178
342
|
|
179
343
|
To cusomize query text presented pass `:single_text` and `:plural_text` options to respectively change the message when one match is found or many.
|
@@ -182,8 +346,8 @@ To cusomize query text presented pass `:single_text` and `:plural_text` options
|
|
182
346
|
possible = %w(status stage stash commit branch blame)
|
183
347
|
prompt.suggest('b', possible, indent: 4, single_text: 'Perhaps you meant?')
|
184
348
|
# =>
|
185
|
-
Perhaps you meant?
|
186
|
-
|
349
|
+
# Perhaps you meant?
|
350
|
+
# blame
|
187
351
|
```
|
188
352
|
|
189
353
|
## Contributing
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class Prompt
|
5
|
+
# A single choice option
|
6
|
+
#
|
7
|
+
# @api public
|
8
|
+
class Choice
|
9
|
+
# The label name
|
10
|
+
#
|
11
|
+
# @api public
|
12
|
+
attr_reader :name
|
13
|
+
|
14
|
+
# Create a Choice instance
|
15
|
+
#
|
16
|
+
# @api public
|
17
|
+
def initialize(name, value)
|
18
|
+
@name = name
|
19
|
+
@value = value
|
20
|
+
end
|
21
|
+
|
22
|
+
# Create choice from value
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
# Choice.from(:option_1)
|
26
|
+
# Choice.from([:option_1, 1])
|
27
|
+
#
|
28
|
+
# @param [Object] val
|
29
|
+
# the value to be converted
|
30
|
+
#
|
31
|
+
# @raise [ArgumentError]
|
32
|
+
#
|
33
|
+
# @return [Choice]
|
34
|
+
#
|
35
|
+
# @api public
|
36
|
+
def self.from(val)
|
37
|
+
case val
|
38
|
+
when Choice
|
39
|
+
return val
|
40
|
+
when String, Symbol
|
41
|
+
new(val, val)
|
42
|
+
when Array
|
43
|
+
new("#{val.first}", val.last)
|
44
|
+
when Hash
|
45
|
+
new("#{val.keys.first}", val.values.first)
|
46
|
+
else
|
47
|
+
raise ArgumentError, "#{val} cannot be coerced into Choice"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Read value and evaluate
|
52
|
+
#
|
53
|
+
# @api public
|
54
|
+
def value
|
55
|
+
case @value
|
56
|
+
when Proc
|
57
|
+
@value.call
|
58
|
+
else
|
59
|
+
@value
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Object equality comparison
|
64
|
+
#
|
65
|
+
# @return [Boolean]
|
66
|
+
#
|
67
|
+
# @api public
|
68
|
+
def ==(other)
|
69
|
+
return false unless other.is_a?(self.class)
|
70
|
+
name == other.name && value == other.value
|
71
|
+
end
|
72
|
+
|
73
|
+
# Object string representation
|
74
|
+
#
|
75
|
+
# @return [String]
|
76
|
+
#
|
77
|
+
# @api public
|
78
|
+
def to_s
|
79
|
+
"#{name}"
|
80
|
+
end
|
81
|
+
end # Choice
|
82
|
+
end # Prompt
|
83
|
+
end # TTY
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module TTY
|
6
|
+
class Prompt
|
7
|
+
# A class responsible for storing a collection of choices
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
class Choices
|
11
|
+
include Enumerable
|
12
|
+
extend Forwardable
|
13
|
+
|
14
|
+
# The actual collection choices
|
15
|
+
#
|
16
|
+
# @return [Array[Choice]]
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
attr_reader :choices
|
20
|
+
|
21
|
+
def_delegators :choices, :length, :size, :to_ary, :empty?, :values_at
|
22
|
+
|
23
|
+
# Convenience for creating choices
|
24
|
+
#
|
25
|
+
# @param [Array[Object]] choices
|
26
|
+
# the choice objects
|
27
|
+
#
|
28
|
+
# @return [Choices]
|
29
|
+
# the choices collection
|
30
|
+
#
|
31
|
+
# @api public
|
32
|
+
def self.[](*choices)
|
33
|
+
new(choices)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Create Choices collection
|
37
|
+
#
|
38
|
+
# @param [Array[Choice]] choices
|
39
|
+
# the choices to add to collection
|
40
|
+
#
|
41
|
+
# @api public
|
42
|
+
def initialize(choices = [])
|
43
|
+
@choices = choices.map do |choice|
|
44
|
+
Choice.from(choice)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Iterate over all choices in the collection
|
49
|
+
#
|
50
|
+
# @yield [Choice]
|
51
|
+
#
|
52
|
+
# @api public
|
53
|
+
def each(&block)
|
54
|
+
return to_enum unless block_given?
|
55
|
+
choices.each(&block)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Add choice to collection
|
59
|
+
#
|
60
|
+
# @param [Object] choice
|
61
|
+
# the choice to add
|
62
|
+
#
|
63
|
+
# @api public
|
64
|
+
def <<(choice)
|
65
|
+
choices << Choice.from(choice)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Access choice by index
|
69
|
+
#
|
70
|
+
# @param [Integer] index
|
71
|
+
#
|
72
|
+
# @return [Choice]
|
73
|
+
#
|
74
|
+
# @api public
|
75
|
+
def [](index)
|
76
|
+
@choices[index]
|
77
|
+
end
|
78
|
+
|
79
|
+
# Pluck a choice by its name from collection
|
80
|
+
#
|
81
|
+
# @param [String] name
|
82
|
+
# the label name for the choice
|
83
|
+
#
|
84
|
+
# @return [Choice]
|
85
|
+
#
|
86
|
+
# @api public
|
87
|
+
def pluck(name)
|
88
|
+
find { |choice| choice.name == name }
|
89
|
+
end
|
90
|
+
end # Choices
|
91
|
+
end # Prompt
|
92
|
+
end # TTY
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class Prompt
|
5
|
+
module Codes
|
6
|
+
BACKSPACE = "\177"
|
7
|
+
DELETE = "\004"
|
8
|
+
ESCAPE = "\e"
|
9
|
+
LINEFEED = "\n"
|
10
|
+
RETURN = "\r"
|
11
|
+
SPACE = " "
|
12
|
+
TAB = "\t"
|
13
|
+
|
14
|
+
KEY_UP = "\e[A"
|
15
|
+
KEY_DOWN = "\e[B"
|
16
|
+
KEY_RIGHT = "\e[C"
|
17
|
+
KEY_LEFT = "\e[D"
|
18
|
+
KEY_DELETE = "\e[3"
|
19
|
+
|
20
|
+
CTRL_J = "\x0A"
|
21
|
+
CTRL_N = "\x0E"
|
22
|
+
CTRL_K = "\x0B"
|
23
|
+
CTRL_P = "\x10"
|
24
|
+
SIGINT = "\x03"
|
25
|
+
|
26
|
+
ITEM_SECURE = "•"
|
27
|
+
ITEM_SELECTED = "‣"
|
28
|
+
RADIO_CHECKED = "⬢"
|
29
|
+
RADIO_UNCHECKED = "⬡"
|
30
|
+
end # Codes
|
31
|
+
end # Prompt
|
32
|
+
end # TTY
|