tty-prompt 0.21.0 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'English'
3
+ require "English"
4
4
 
5
- require_relative 'choices'
6
- require_relative 'block_paginator'
7
- require_relative 'paginator'
5
+ require_relative "choices"
6
+ require_relative "block_paginator"
7
+ require_relative "paginator"
8
8
 
9
9
  module TTY
10
10
  class Prompt
@@ -13,7 +13,7 @@ module TTY
13
13
  #
14
14
  # @api private
15
15
  class EnumList
16
- PAGE_HELP = '(Press tab/right or left to reveal more choices)'
16
+ PAGE_HELP = "(Press tab/right or left to reveal more choices)"
17
17
 
18
18
  # Create instance of EnumList menu.
19
19
  #
@@ -21,12 +21,13 @@ module TTY
21
21
  def initialize(prompt, **options)
22
22
  @prompt = prompt
23
23
  @prefix = options.fetch(:prefix) { @prompt.prefix }
24
- @enum = options.fetch(:enum) { ')' }
24
+ @enum = options.fetch(:enum) { ")" }
25
25
  @default = options.fetch(:default) { -1 }
26
26
  @active_color = options.fetch(:active_color) { @prompt.active_color }
27
27
  @help_color = options.fetch(:help_color) { @prompt.help_color }
28
28
  @error_color = options.fetch(:error_color) { @prompt.error_color }
29
29
  @cycle = options.fetch(:cycle) { false }
30
+ @quiet = options.fetch(:quiet) { @prompt.quiet }
30
31
  @symbols = @prompt.symbols.merge(options.fetch(:symbols, {}))
31
32
  @input = nil
32
33
  @done = false
@@ -101,6 +102,13 @@ module TTY
101
102
  @enum = value
102
103
  end
103
104
 
105
+ # Set quiet mode
106
+ #
107
+ # @api public
108
+ def quiet(value)
109
+ @quiet = value
110
+ end
111
+
104
112
  # Add a single choice
105
113
  #
106
114
  # @api public
@@ -162,7 +170,7 @@ module TTY
162
170
  if choice_in_range && !choice_disabled || @input.empty?
163
171
  @done = true
164
172
  else
165
- @input = ''
173
+ @input = ""
166
174
  @failure = true
167
175
  end
168
176
  end
@@ -241,7 +249,7 @@ module TTY
241
249
  #
242
250
  # @api private
243
251
  def render
244
- @input = ''
252
+ @input = ""
245
253
  until @done
246
254
  question = render_question
247
255
  @prompt.print(question)
@@ -253,7 +261,7 @@ module TTY
253
261
  question_lines = question.split($INPUT_RECORD_SEPARATOR, -1)
254
262
  @prompt.print(refresh(question_lines_count(question_lines)))
255
263
  end
256
- @prompt.print(render_question)
264
+ @prompt.print(render_question) unless @quiet
257
265
  answer
258
266
  end
259
267
 
@@ -308,8 +316,8 @@ module TTY
308
316
  #
309
317
  # @api private
310
318
  def error_message
311
- error = 'Please enter a valid number'
312
- "\n" + @prompt.decorate('>>', @error_color) + ' ' + error
319
+ error = "Please enter a valid number"
320
+ "\n" + @prompt.decorate(">>", @error_color) + " " + error
313
321
  end
314
322
 
315
323
  # Render error message and return cursor to position of input
@@ -332,8 +340,8 @@ module TTY
332
340
  #
333
341
  # @api private
334
342
  def render_header
335
- return '' unless @done
336
- return '' unless @active
343
+ return "" unless @done
344
+ return "" unless @active
337
345
  selected_item = @choices[@active - 1].name.to_s
338
346
  @prompt.decorate(selected_item, @active_color)
339
347
  end
@@ -353,7 +361,7 @@ module TTY
353
361
  #
354
362
  # @api private
355
363
  def page_help_message
356
- return '' unless paginated?
364
+ return "" unless paginated?
357
365
  "\n" + @prompt.decorate(@page_help, @help_color)
358
366
  end
359
367
 
@@ -380,15 +388,15 @@ module TTY
380
388
  output = []
381
389
 
382
390
  @paginator.paginate(@choices, @page_active, @per_page) do |choice, index|
383
- num = (index + 1).to_s + @enum + ' '
391
+ num = (index + 1).to_s + @enum + " "
384
392
  selected = num.to_s + choice.name.to_s
385
393
  output << if index + 1 == @active && !choice.disabled?
386
- (' ' * 2) + @prompt.decorate(selected, @active_color)
394
+ (" " * 2) + @prompt.decorate(selected, @active_color)
387
395
  elsif choice.disabled?
388
- @prompt.decorate(@symbols[:cross], :red) + ' ' +
389
- selected + ' ' + choice.disabled.to_s
396
+ @prompt.decorate(@symbols[:cross], :red) + " " +
397
+ selected + " " + choice.disabled.to_s
390
398
  else
391
- (' ' * 2) + selected
399
+ (" " * 2) + selected
392
400
  end
393
401
  output << "\n"
394
402
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TTY
4
+ class Prompt
5
+ Error = Class.new(StandardError)
6
+
7
+ # Raised when wrong parameter is used to configure prompt
8
+ ConfigurationError = Class.new(Error)
9
+
10
+ # Raised when type conversion cannot be performed
11
+ ConversionError = Class.new(Error)
12
+
13
+ # Raised when the passed in validation argument is of wrong type
14
+ ValidationCoercion = Class.new(Error)
15
+
16
+ # Raised when the required argument is not supplied
17
+ ArgumentRequired = Class.new(Error)
18
+
19
+ # Raised when the argument validation fails
20
+ ArgumentValidation = Class.new(Error)
21
+
22
+ # Raised when the argument is not expected
23
+ InvalidArgument = Class.new(Error)
24
+
25
+ # Raised when overriding already defined conversion
26
+ ConversionAlreadyDefined = Class.new(Error)
27
+
28
+ # Raised when conversion type isn't registered
29
+ UnsupportedConversion = Class.new(Error)
30
+ end # Prompt
31
+ end # TTY
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'result'
3
+ require_relative "result"
4
4
 
5
5
  module TTY
6
6
  class Prompt
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'choices'
3
+ require_relative "choices"
4
4
 
5
5
  module TTY
6
6
  class Prompt
@@ -10,8 +10,8 @@ module TTY
10
10
  # @api private
11
11
  class Expander
12
12
  HELP_CHOICE = {
13
- key: 'h',
14
- name: 'print help',
13
+ key: "h",
14
+ name: "print help",
15
15
  value: :help
16
16
  }.freeze
17
17
 
@@ -25,6 +25,7 @@ module TTY
25
25
  @auto_hint = options.fetch(:auto_hint) { false }
26
26
  @active_color = options.fetch(:active_color) { @prompt.active_color }
27
27
  @help_color = options.fetch(:help_color) { @prompt.help_color }
28
+ @quiet = options.fetch(:quiet) { @prompt.quiet }
28
29
  @choices = Choices.new
29
30
  @selected = nil
30
31
  @done = false
@@ -56,16 +57,16 @@ module TTY
56
57
 
57
58
  selected = select_choice(@input)
58
59
 
59
- if selected && selected.key.to_s == 'h'
60
+ if selected && selected.key.to_s == "h"
60
61
  expand
61
62
  @selected = nil
62
- @input = ''
63
+ @input = ""
63
64
  elsif selected
64
65
  @done = true
65
66
  @selected = selected
66
67
  @hint = nil
67
68
  else
68
- @input = ''
69
+ @input = ""
69
70
  end
70
71
  end
71
72
  alias keyreturn keyenter
@@ -103,6 +104,13 @@ module TTY
103
104
  @default = value
104
105
  end
105
106
 
107
+ # Set quiet mode.
108
+ #
109
+ # @api public
110
+ def quiet(value)
111
+ @quiet = value
112
+ end
113
+
106
114
  # Add a single choice
107
115
  #
108
116
  # @api public
@@ -154,19 +162,19 @@ module TTY
154
162
  elsif @input.to_s.empty? && default_key
155
163
  keys[@default - 1] = @prompt.decorate(default_key, @active_color)
156
164
  end
157
- keys.join(',')
165
+ keys.join(",")
158
166
  end
159
167
 
160
168
  # @api private
161
169
  def render
162
- @input = ''
170
+ @input = ""
163
171
  until @done
164
172
  question = render_question
165
173
  @prompt.print(question)
166
174
  read_input
167
175
  @prompt.print(refresh(question.lines.count))
168
176
  end
169
- @prompt.print(render_question)
177
+ @prompt.print(render_question) unless @quiet
170
178
  answer
171
179
  end
172
180
 
@@ -199,7 +207,7 @@ module TTY
199
207
  #
200
208
  # @api private
201
209
  def render_hint
202
- "\n" + @prompt.decorate('>> ', @active_color) +
210
+ "\n" + @prompt.decorate(">> ", @active_color) +
203
211
  @hint +
204
212
  @prompt.cursor.prev_line +
205
213
  @prompt.cursor.forward(@prompt.strip(render_header).size)
@@ -274,7 +282,7 @@ module TTY
274
282
  if @selected && @selected.key == choice.key
275
283
  chosen = @prompt.decorate(chosen, @active_color)
276
284
  end
277
- output << ' ' + chosen + "\n"
285
+ output << " " + chosen + "\n"
278
286
  end
279
287
  output.join
280
288
  end
@@ -294,7 +302,7 @@ module TTY
294
302
  if choice.key.length != 1
295
303
  errors << "Choice key `#{choice.key}` is more than one character long."
296
304
  end
297
- if choice.key.to_s == 'h'
305
+ if choice.key.to_s == "h"
298
306
  errors << "Choice key `#{choice.key}` is reserved for help menu."
299
307
  end
300
308
  if keys.include?(choice.key)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'question'
4
- require_relative 'timer'
3
+ require_relative "question"
4
+ require_relative "timer"
5
5
 
6
6
  module TTY
7
7
  class Prompt
@@ -20,7 +20,7 @@ module TTY
20
20
  @interval = options.fetch(:interval) {
21
21
  (@timeout != UndefinedSetting && @timeout < 1) ? @timeout : 1
22
22
  }
23
- @decimals = (@interval.to_s.split('.')[1] || []).size
23
+ @decimals = (@interval.to_s.split(".")[1] || []).size
24
24
  @countdown = @timeout
25
25
  time = timeout? ? Float(@timeout) : nil
26
26
  @timer = Timer.new(time, Float(@interval))
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'English'
3
+ require "English"
4
4
 
5
- require_relative 'choices'
6
- require_relative 'paginator'
7
- require_relative 'block_paginator'
5
+ require_relative "choices"
6
+ require_relative "paginator"
7
+ require_relative "block_paginator"
8
8
 
9
9
  module TTY
10
10
  class Prompt
@@ -13,8 +13,6 @@ module TTY
13
13
  #
14
14
  # @api private
15
15
  class List
16
- HELP = '(Use %s arrow%s keys, press Enter to select%s)'
17
-
18
16
  # Allowed keys for filter, along with backspace and canc.
19
17
  FILTER_KEYS_MATCHER = /\A([[:alnum:]]|[[:punct:]])\Z/.freeze
20
18
 
@@ -45,9 +43,11 @@ module TTY
45
43
  @cycle = options.fetch(:cycle) { false }
46
44
  @filterable = options.fetch(:filter) { false }
47
45
  @symbols = @prompt.symbols.merge(options.fetch(:symbols, {}))
46
+ @quiet = options.fetch(:quiet) { @prompt.quiet }
48
47
  @filter = []
49
48
  @filter_cache = {}
50
49
  @help = options[:help]
50
+ @show_help = options.fetch(:show_help) { :start }
51
51
  @first_render = true
52
52
  @done = false
53
53
  @per_page = options[:per_page]
@@ -135,6 +135,15 @@ module TTY
135
135
  @help = (@help.nil? && !not_set) ? value : default_help
136
136
  end
137
137
 
138
+ # Change when help is displayed
139
+ #
140
+ # @api public
141
+ def show_help(value = (not_set = true))
142
+ return @show_ehlp if not_set
143
+
144
+ @show_help = value
145
+ end
146
+
138
147
  # Information about arrow keys
139
148
  #
140
149
  # @return [String]
@@ -145,25 +154,27 @@ module TTY
145
154
  left_right = @symbols[:arrow_left] + "/" + @symbols[:arrow_right]
146
155
 
147
156
  arrows = [up_down]
148
- arrows << " and " if paginated?
157
+ arrows << "/" if paginated?
149
158
  arrows << left_right if paginated?
150
159
  arrows.join
151
160
  end
152
161
 
153
162
  # Default help text
154
163
  #
155
- # @api public
164
+ # Note that enumeration and filter are mutually exclusive
165
+ #
166
+ # @a public
156
167
  def default_help
157
- # Note that enumeration and filter are mutually exclusive
158
- tokens = if enumerate?
159
- [" or number (1-#{choices.size})", '']
160
- elsif filterable?
161
- ['', ', and letter keys to filter']
162
- else
163
- ['', '']
164
- end
165
-
166
- format(self.class::HELP, arrows_help, *tokens)
168
+ str = []
169
+ str << "(Press "
170
+ str << "#{arrows_help} arrow"
171
+ str << " or 1-#{choices.size} number" if enumerate?
172
+ str << " to move"
173
+ str << (filterable? ? "," : " and")
174
+ str << " Enter to select"
175
+ str << " and letters to filter" if filterable?
176
+ str << ")"
177
+ str.join
167
178
  end
168
179
 
169
180
  # Set selecting active index using number pad
@@ -173,6 +184,13 @@ module TTY
173
184
  @enum = value
174
185
  end
175
186
 
187
+ # Set whether selected answers are echoed
188
+ #
189
+ # @api public
190
+ def quiet(value)
191
+ @quiet = value
192
+ end
193
+
176
194
  # Add a single choice
177
195
  #
178
196
  # @api public
@@ -198,9 +216,8 @@ module TTY
198
216
  @choices
199
217
  else
200
218
  filter_value = @filter.join.downcase
201
- @filter_cache[filter_value] ||= @choices.select do |choice|
202
- !choice.disabled? &&
203
- choice.name.downcase.include?(filter_value)
219
+ @filter_cache[filter_value] ||= @choices.enabled.select do |choice|
220
+ choice.name.to_s.downcase.include?(filter_value)
204
221
  end
205
222
  end
206
223
  else
@@ -411,7 +428,7 @@ module TTY
411
428
 
412
429
  @prompt.print(refresh(question_lines_count(question_lines)))
413
430
  end
414
- @prompt.print(render_question)
431
+ @prompt.print(render_question) unless @quiet
415
432
  answer
416
433
  ensure
417
434
  @prompt.print(@prompt.show)
@@ -478,6 +495,20 @@ module TTY
478
495
  "(Filter: #{@filter.join.inspect})"
479
496
  end
480
497
 
498
+ # Check if help is shown only on start
499
+ #
500
+ # @api private
501
+ def help_start?
502
+ @show_help =~ /start/i
503
+ end
504
+
505
+ # Check if help is always displayed
506
+ #
507
+ # @api private
508
+ def help_always?
509
+ @show_help =~ /always/i
510
+ end
511
+
481
512
  # Render initial help and selected choice
482
513
  #
483
514
  # @return [String]
@@ -487,7 +518,8 @@ module TTY
487
518
  if @done
488
519
  selected_item = choices[@active - 1].name
489
520
  @prompt.decorate(selected_item.to_s, @active_color)
490
- elsif @first_render
521
+ elsif (@first_render && (help_start? || help_always?)) ||
522
+ (help_always? && !@filter.any?)
491
523
  @prompt.decorate(help, @help_color)
492
524
  elsif filterable? && @filter.any?
493
525
  @prompt.decorate(filter_help, @help_color)
@@ -504,7 +536,7 @@ module TTY
504
536
 
505
537
  sync_paginators if @paging_changed
506
538
  paginator.paginate(choices, @active, @per_page) do |choice, index|
507
- num = enumerate? ? (index + 1).to_s + @enum + ' ' : ''
539
+ num = enumerate? ? (index + 1).to_s + @enum + " " : ""
508
540
  message = if index + 1 == @active && !choice.disabled?
509
541
  selected = "#{@symbols[:marker]} #{num}#{choice.name}"
510
542
  @prompt.decorate(selected.to_s, @active_color)
@@ -515,7 +547,7 @@ module TTY
515
547
  " #{num}#{choice.name}"
516
548
  end
517
549
  end_index = paginated? ? paginator.end_index : choices.size - 1
518
- newline = (index == end_index) ? '' : "\n"
550
+ newline = (index == end_index) ? "" : "\n"
519
551
  output << (message + newline)
520
552
  end
521
553