tty-prompt 0.21.0 → 0.22.0

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.
@@ -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