inquirer.rb 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9d0c59415e69c915f7f8e20f566a096e2218d5b9
4
- data.tar.gz: c702cf48d146f65dd677b39b10eba81b176bc1f9
3
+ metadata.gz: 2660e6433f7e913796819045ad9a22920a626bde
4
+ data.tar.gz: 409454f61b1bbc915e5f8684f0cd0136c918a9c6
5
5
  SHA512:
6
- metadata.gz: 27fef9a176a7c1d0f7359c0a4381831f70f8b552db4a8a7bba90d7af4f7f44435b9eb81560fdb415f69e5c9b20cee0c43cd9b9fd011c440e8306dba33772b16f
7
- data.tar.gz: 82c9bdffd2f961f23a7b924cffc2e8311799a13db1dc1d64fde751ddea4d1d96de359bc91d42cf2bd94fc7e2117ce8944538b986c8d5f03ea74d08426eed7168
6
+ metadata.gz: b4c143a8915d1ff0ccc20d310fd5311ec448ee421e1f4f70e1f418273daef0eb887b4d0600a24ba4f06d67f6579d88653e2a56d31edaf149fe9deb06fa8a3663
7
+ data.tar.gz: 0267f36718cacf9eb9e2272a40fcab8190377c27c4b5ec6f6df4c792d2829c2cfcf41f9ffde4be46af9c40b46537f99cab01e7e8b7cb4e341b3a6e84f0ffd49e
@@ -1,9 +1,11 @@
1
1
  require 'inquirer/version'
2
2
  require 'inquirer/utils/iohelper'
3
3
  require 'inquirer/prompts/checkbox'
4
+ require 'inquirer/prompts/checkbox_filterable'
4
5
  require 'inquirer/prompts/confirm'
5
6
  require 'inquirer/prompts/input'
6
7
  require 'inquirer/prompts/list'
8
+ require 'inquirer/prompts/list_filterable'
7
9
  require 'inquirer/prompts/password'
8
10
 
9
11
  module Inquirer
@@ -52,7 +54,7 @@ module Inquirer
52
54
  repeat_counter: repeat_counter,
53
55
  )
54
56
 
55
- object = Kernel.const_get(prompt[:type].to_s.capitalize)
57
+ object = Kernel.const_get(prompt[:type].to_s.split('_').collect(&:capitalize).join)
56
58
  answer = object.prompt(type_parameter)
57
59
 
58
60
  if prompt[:filter] && prompt[:filter].is_a?(Proc)
@@ -90,11 +90,7 @@ module Checkbox
90
90
  render_prompt
91
91
 
92
92
  # we are done if the user hits return
93
- if @error_message or key != 'return'
94
- true
95
- else
96
- false
97
- end
93
+ @error_message || key != 'return'
98
94
  end
99
95
  end
100
96
 
@@ -0,0 +1,255 @@
1
+ require 'inquirer/utils/paginator'
2
+ require 'inquirer/utils/iochar'
3
+ require 'inquirer/utils/iohelper'
4
+ require 'inquirer/style/checkbox_filterable'
5
+
6
+ module CheckboxFilterable
7
+
8
+ extend self
9
+
10
+ def prompt opts = {}
11
+
12
+ # finish if there's nothing to do
13
+ return opts[:default] if Array(opts[:choices]).empty?
14
+
15
+ @question = opts[:message]
16
+ @position = 0
17
+ @paginator = Paginator.new
18
+ @choices = []
19
+ opts[:choices].each { |choice|
20
+
21
+ if choice[:when].is_a?(Proc)
22
+
23
+ when_parameter = opts.merge(
24
+ choice: choice,
25
+ )
26
+
27
+ ask_choice = choice[:when].call( when_parameter )
28
+
29
+ next if !ask_choice
30
+ elsif [true, false].include? choice[:when]
31
+ next if !choice[:when]
32
+ end
33
+
34
+ choice[:value] ||= choice[:name]
35
+
36
+ if !choice[:checked] && opts[:default].is_a?(Array)
37
+ choice[:checked] = opts[:default].include?( choice[:value] )
38
+ end
39
+
40
+ @choices.push(choice)
41
+ }
42
+
43
+ question_backup = @question
44
+ @question += ' '
45
+ @question += Inquirer::Style::CheckboxFilterable.selection_help
46
+
47
+ @filter = ''
48
+ cursor_position = 0
49
+ @choices_filtered = @choices
50
+ @question = question_backup
51
+
52
+ render_prompt
53
+
54
+ # loop through user input
55
+ IOHelper.read_char do |char|
56
+
57
+ key = IOChar.char_to_key(char)
58
+
59
+ if @error_message
60
+ @error_message = nil
61
+ end
62
+
63
+ case key
64
+ when 'up'
65
+ if !@choices_filtered.empty?
66
+ @position = (@position - 1) % @choices_filtered.length
67
+ else
68
+ check_no_match
69
+ end
70
+ when 'down'
71
+ if !@choices_filtered.empty?
72
+ @position = (@position + 1) % @choices_filtered.length
73
+ else
74
+ check_no_match
75
+ end
76
+ when 'space'
77
+ if !@choices_filtered.empty?
78
+ @choices_filtered[@position][:checked] = !@choices_filtered[@position][:checked]
79
+
80
+ choice = @choices_filtered[@position]
81
+
82
+ @choices.map! {|possible_choice|
83
+
84
+ if choice[:name] == possible_choice[:name]
85
+ possible_choice = choice
86
+ end
87
+
88
+ possible_choice
89
+ }
90
+ end
91
+ when 'return'
92
+ if opts[:validate] and opts[:validate].is_a?(Proc)
93
+
94
+ value = @choices.reject { |choice|
95
+ !choice[:checked]
96
+ }.collect { |choice|
97
+ choice[:value]
98
+ }
99
+
100
+ validation_result = opts[:validate].call( value )
101
+
102
+ if !validation_result
103
+ @error_message = Inquirer::Style::CheckboxFilterable.error_message_invalid_value
104
+ elsif validation_result && validation_result.is_a?(String)
105
+ @error_message = validation_result
106
+ end
107
+ end
108
+
109
+ if !@error_message
110
+ check_no_match
111
+ end
112
+ when 'backspace'
113
+
114
+ index = @filter.size - cursor_position - 1
115
+
116
+ if index >= 0
117
+ # remove char at current index
118
+ @filter[index] = ''
119
+ end
120
+
121
+ filter_choices
122
+ when 'left'
123
+ if cursor_position < @filter.length
124
+ cursor_position += 1
125
+ end
126
+
127
+ check_no_match
128
+ when 'right'
129
+ if cursor_position > 0
130
+ cursor_position -= 1
131
+ end
132
+
133
+ check_no_match
134
+ else
135
+ @filter = @filter.insert(@filter.length - cursor_position, char)
136
+
137
+ filter_choices
138
+ end
139
+
140
+ IOHelper.clear
141
+
142
+ render_prompt
143
+
144
+ update_cursor_position(cursor_position)
145
+
146
+ # we are done if the user hits return
147
+ @error_message || key != 'return'
148
+ end
149
+
150
+ render_result
151
+
152
+ @choices.reject { |choice|
153
+ !choice[:checked]
154
+ }.collect { |choice|
155
+ choice[:value]
156
+ }
157
+ end
158
+
159
+ def render_prompt
160
+ # start with the question prefix
161
+ prompt = Inquirer::Style.question_prefix
162
+
163
+ # render the question
164
+ prompt += Inquirer::Style::CheckboxFilterable.question % @question
165
+
166
+ prompt += IOChar.newline
167
+
168
+ # render the list
169
+ prompt += @choices_filtered.map.with_index(0) do |choice, position|
170
+
171
+ choice_prompt = ''
172
+
173
+ if position == @position
174
+ choice_prompt += Inquirer::Style::CheckboxFilterable.selector
175
+ else
176
+ choice_prompt += ' '
177
+ end
178
+
179
+ if choice[:checked]
180
+ choice_prompt += Inquirer::Style::CheckboxFilterable.checkbox_on
181
+ choice_prompt += ' '
182
+ choice_prompt += Inquirer::Style::CheckboxFilterable.checked_item % choice[:name]
183
+ else
184
+ choice_prompt += Inquirer::Style::CheckboxFilterable.checkbox_off
185
+ choice_prompt += ' '
186
+ choice_prompt += Inquirer::Style::CheckboxFilterable.item % choice[:name]
187
+ end
188
+
189
+ choice_prompt
190
+ end.join('')
191
+
192
+ paginated_prompt = @paginator.paginate(prompt, @position)
193
+
194
+ # render error message
195
+ if @error_message
196
+ paginated_prompt += Inquirer::Style::CheckboxFilterable.error_message % @error_message
197
+ end
198
+
199
+ paginated_prompt += IOChar.newline
200
+
201
+ paginated_prompt += Inquirer::Style::CheckboxFilterable.filter_prefix
202
+
203
+ paginated_prompt += Inquirer::Style::CheckboxFilterable.filter % @filter
204
+
205
+ IOHelper.render( paginated_prompt )
206
+ end
207
+
208
+ def render_result
209
+ # start with the question prefix
210
+ result = Inquirer::Style.question_prefix
211
+
212
+ # render the question
213
+ result += Inquirer::Style::CheckboxFilterable.question % @question
214
+
215
+ selected_choices = @choices.reject { |choice|
216
+ !choice[:checked]
217
+ }.collect { |choice|
218
+ choice[:short] || choice[:name]
219
+ }.join(', ')
220
+
221
+ if !selected_choices.empty?
222
+ result += Inquirer::Style::CheckboxFilterable.response % selected_choices
223
+ end
224
+
225
+ result += IOChar.newline
226
+
227
+ IOHelper.clear
228
+
229
+ IOHelper.render( result )
230
+ end
231
+
232
+ def update_cursor_position(cursor_position)
233
+ print IOChar.cursor_left * cursor_position
234
+ end
235
+
236
+ def filter_choices
237
+ @position = 0
238
+ @choices_filtered = []
239
+
240
+ @choices.each { |choice|
241
+
242
+ next if !choice[:name].gsub(/\s/, '').downcase.index(@filter.gsub(/\s/, '').downcase)
243
+
244
+ @choices_filtered.push(choice)
245
+ }
246
+
247
+ check_no_match
248
+ end
249
+
250
+ def check_no_match
251
+ return if !@choices_filtered.empty?
252
+
253
+ @error_message = 'No matching choice found'
254
+ end
255
+ end
@@ -23,7 +23,7 @@ module Confirm
23
23
  elsif key.casecmp( Inquirer::Style::Confirm.option_false[0] ) == 0
24
24
  @value = false
25
25
  false
26
- elsif key == 'return' and !@default.nil?
26
+ elsif key == 'return' && !@default.nil?
27
27
  @value = @default
28
28
  false
29
29
  else
@@ -64,19 +64,21 @@ module Confirm
64
64
 
65
65
  def render_result
66
66
 
67
- response = nil
68
- if @value
69
- response = Inquirer::Style::Confirm.option_true
70
- else
71
- response = Inquirer::Style::Confirm.option_false
72
- end
73
-
74
67
  # start with the question prefix
75
68
  result = Inquirer::Style.question_prefix
76
69
 
77
70
  result += Inquirer::Style::Confirm.question % @question
78
71
 
79
- result += Inquirer::Style::Confirm.response % response
72
+ response = nil
73
+ if !@value.nil?
74
+ if @value
75
+ response = Inquirer::Style::Confirm.option_true
76
+ else
77
+ response = Inquirer::Style::Confirm.option_false
78
+ end
79
+
80
+ result += Inquirer::Style::Confirm.response % response
81
+ end
80
82
 
81
83
  result += IOChar.newline
82
84
 
@@ -0,0 +1,209 @@
1
+ require 'inquirer/utils/iochar'
2
+ require 'inquirer/utils/iohelper'
3
+ require 'inquirer/utils/paginator'
4
+ require 'inquirer/style/list_filterable'
5
+
6
+ module ListFilterable
7
+
8
+ extend self
9
+
10
+ def prompt opts = {}
11
+ @question = opts[:message]
12
+ default = opts[:default] || 0
13
+
14
+ @position = 0
15
+ @paginator = Paginator.new
16
+
17
+ @choices = []
18
+ opts[:choices].each { |choice|
19
+
20
+ if choice[:when].is_a?(Proc)
21
+
22
+ when_parameter = opts.merge(
23
+ choice: choice,
24
+ )
25
+
26
+ ask_choice = choice[:when].call( when_parameter )
27
+
28
+ next if !ask_choice
29
+ elsif [true, false].include? choice[:when]
30
+ next if !choice[:when]
31
+ end
32
+
33
+ choice[:value] ||= choice[:name]
34
+
35
+ @choices.push(choice)
36
+ }
37
+
38
+ return nil if Array(@choices).empty?
39
+
40
+ return @choices[0][:value] if @choices.size == 1
41
+
42
+ if default.is_a?(String) || default.is_a?(Symbol)
43
+ @position = @choices.find_index { |choice| choice[:value] == default }
44
+ @position ||= 0
45
+ elsif default.is_a?(Integer) && default < @choices.size
46
+ @position = default
47
+ else
48
+ @position = 0
49
+ end
50
+
51
+
52
+ question_backup = @question
53
+ @question += ' '
54
+ @question += Inquirer::Style::ListFilterable.selection_help
55
+
56
+ @filter = ''
57
+ cursor_position = 0
58
+ @choices_filtered = @choices
59
+ @question = question_backup
60
+
61
+ render_prompt
62
+
63
+ IOHelper.read_char do |char|
64
+
65
+ key = IOChar.char_to_key(char)
66
+
67
+ if @error_message
68
+ @error_message = nil
69
+ end
70
+
71
+ case key
72
+ when 'up'
73
+ if !@choices_filtered.empty?
74
+ @position = (@position - 1) % @choices_filtered.length
75
+ else
76
+ check_no_match
77
+ end
78
+ when 'down'
79
+ if !@choices_filtered.empty?
80
+ @position = (@position + 1) % @choices_filtered.length
81
+ else
82
+ check_no_match
83
+ end
84
+ when 'backspace'
85
+
86
+ index = @filter.size - cursor_position - 1
87
+
88
+ if index >= 0
89
+ # remove char at current index
90
+ @filter[index] = ''
91
+ end
92
+
93
+ filter_choices
94
+ when 'left'
95
+ if cursor_position < @filter.length
96
+ cursor_position += 1
97
+ end
98
+
99
+ check_no_match
100
+ when 'right'
101
+ if cursor_position > 0
102
+ cursor_position -= 1
103
+ end
104
+
105
+ check_no_match
106
+ else
107
+
108
+ if !['return'].include?(key)
109
+ @filter = @filter.insert(@filter.length - cursor_position, char)
110
+ filter_choices
111
+ end
112
+ end
113
+
114
+ IOHelper.clear
115
+
116
+ render_prompt
117
+
118
+ update_cursor_position(cursor_position)
119
+
120
+ key != 'return' || @choices_filtered.empty?
121
+ end
122
+
123
+ IOHelper.clear
124
+
125
+ render_result
126
+
127
+ @choices_filtered[@position][:value]
128
+ end
129
+
130
+ def render_prompt
131
+ # start with the question prefix
132
+ prompt = Inquirer::Style.question_prefix
133
+
134
+ prompt += Inquirer::Style::ListFilterable.question % @question
135
+
136
+ prompt += IOChar.newline
137
+
138
+ prompt += @choices_filtered.map.with_index(0) do |choice, position|
139
+
140
+ choice_prompt = ''
141
+
142
+ if position == @position
143
+ choice_prompt += Inquirer::Style::ListFilterable.selector
144
+ choice_prompt += ' '
145
+ choice_prompt += Inquirer::Style::ListFilterable.selected_item % choice[:name]
146
+ else
147
+ choice_prompt += ' '
148
+ choice_prompt += Inquirer::Style::ListFilterable.item % choice[:name]
149
+ end
150
+
151
+ choice_prompt
152
+ end.join('')
153
+
154
+ paginated_prompt = @paginator.paginate(prompt, @position)
155
+
156
+ # render error message
157
+ if @error_message
158
+ paginated_prompt += Inquirer::Style::ListFilterable.error_message % @error_message
159
+ end
160
+
161
+ paginated_prompt += IOChar.newline
162
+
163
+ paginated_prompt += Inquirer::Style::ListFilterable.filter_prefix
164
+
165
+ paginated_prompt += Inquirer::Style::ListFilterable.filter % @filter
166
+
167
+ IOHelper.render( paginated_prompt )
168
+ end
169
+
170
+ def render_result
171
+
172
+ # start with the question prefix
173
+ result = Inquirer::Style.question_prefix
174
+
175
+ result += Inquirer::Style::ListFilterable.question % @question
176
+
177
+ display_value = @choices_filtered[@position][:short] || @choices_filtered[@position][:name]
178
+
179
+ result += Inquirer::Style::ListFilterable.response % display_value
180
+
181
+ result += IOChar.newline
182
+
183
+ IOHelper.render( result )
184
+ end
185
+
186
+ def update_cursor_position(cursor_position)
187
+ print IOChar.cursor_left * cursor_position
188
+ end
189
+
190
+ def filter_choices
191
+ @position = 0
192
+ @choices_filtered = []
193
+
194
+ @choices.each { |choice|
195
+
196
+ next if !choice[:name].gsub(/\s/, '').downcase.index(@filter.gsub(/\s/, '').downcase)
197
+
198
+ @choices_filtered.push(choice)
199
+ }
200
+
201
+ check_no_match
202
+ end
203
+
204
+ def check_no_match
205
+ return if !@choices_filtered.empty?
206
+
207
+ @error_message = 'No matching choice found'
208
+ end
209
+ end