inquirer.rb 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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