tty-prompt 0.19.0 → 0.23.1

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.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +81 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +485 -233
  5. data/lib/tty-prompt.rb +1 -2
  6. data/lib/tty/prompt.rb +159 -147
  7. data/lib/tty/prompt/answers_collector.rb +5 -5
  8. data/lib/tty/prompt/block_paginator.rb +1 -1
  9. data/lib/tty/prompt/choice.rb +31 -13
  10. data/lib/tty/prompt/choices.rb +30 -12
  11. data/lib/tty/prompt/confirm_question.rb +42 -16
  12. data/lib/tty/prompt/const.rb +17 -0
  13. data/lib/tty/prompt/converter_dsl.rb +6 -7
  14. data/lib/tty/prompt/converter_registry.rb +31 -26
  15. data/lib/tty/prompt/converters.rb +139 -32
  16. data/lib/tty/prompt/enum_list.rb +58 -25
  17. data/lib/tty/prompt/errors.rb +31 -0
  18. data/lib/tty/prompt/evaluator.rb +2 -2
  19. data/lib/tty/prompt/expander.rb +27 -15
  20. data/lib/tty/prompt/keypress.rb +5 -3
  21. data/lib/tty/prompt/list.rb +101 -38
  22. data/lib/tty/prompt/mask_question.rb +9 -5
  23. data/lib/tty/prompt/multi_list.rb +108 -29
  24. data/lib/tty/prompt/multiline.rb +9 -7
  25. data/lib/tty/prompt/paginator.rb +1 -1
  26. data/lib/tty/prompt/question.rb +67 -36
  27. data/lib/tty/prompt/question/checks.rb +20 -2
  28. data/lib/tty/prompt/question/modifier.rb +4 -2
  29. data/lib/tty/prompt/question/validation.rb +3 -3
  30. data/lib/tty/prompt/selected_choices.rb +77 -0
  31. data/lib/tty/prompt/slider.rb +110 -23
  32. data/lib/tty/prompt/statement.rb +3 -3
  33. data/lib/tty/prompt/suggestion.rb +7 -6
  34. data/lib/tty/prompt/symbols.rb +58 -58
  35. data/lib/tty/prompt/test.rb +36 -0
  36. data/lib/tty/prompt/utils.rb +1 -3
  37. data/lib/tty/prompt/version.rb +1 -1
  38. metadata +27 -196
  39. data/Rakefile +0 -8
  40. data/examples/ask.rb +0 -7
  41. data/examples/ask_blank.rb +0 -9
  42. data/examples/ask_valid.rb +0 -12
  43. data/examples/collect.rb +0 -21
  44. data/examples/echo.rb +0 -11
  45. data/examples/enum_select.rb +0 -7
  46. data/examples/enum_select_disabled.rb +0 -16
  47. data/examples/enum_select_paged.rb +0 -9
  48. data/examples/enum_select_wrapped.rb +0 -15
  49. data/examples/expand.rb +0 -29
  50. data/examples/expand_auto.rb +0 -29
  51. data/examples/in.rb +0 -9
  52. data/examples/inputs.rb +0 -10
  53. data/examples/key_events.rb +0 -15
  54. data/examples/keypress.rb +0 -9
  55. data/examples/mask.rb +0 -13
  56. data/examples/multi_select.rb +0 -8
  57. data/examples/multi_select_disabled.rb +0 -17
  58. data/examples/multi_select_disabled_paged.rb +0 -22
  59. data/examples/multi_select_paged.rb +0 -9
  60. data/examples/multi_select_wrapped.rb +0 -15
  61. data/examples/multiline.rb +0 -9
  62. data/examples/pause.rb +0 -9
  63. data/examples/select.rb +0 -24
  64. data/examples/select_disabled.rb +0 -18
  65. data/examples/select_disabled_paged.rb +0 -22
  66. data/examples/select_enum.rb +0 -8
  67. data/examples/select_filtered.rb +0 -11
  68. data/examples/select_paginated.rb +0 -11
  69. data/examples/select_wrapped.rb +0 -15
  70. data/examples/slider.rb +0 -6
  71. data/examples/validation.rb +0 -9
  72. data/examples/yes_no.rb +0 -7
  73. data/lib/tty/prompt/messages.rb +0 -49
  74. data/lib/tty/test_prompt.rb +0 -20
  75. data/spec/spec_helper.rb +0 -61
  76. data/spec/unit/ask_spec.rb +0 -173
  77. data/spec/unit/block_paginator_spec.rb +0 -84
  78. data/spec/unit/choice/eql_spec.rb +0 -22
  79. data/spec/unit/choice/from_spec.rb +0 -112
  80. data/spec/unit/choices/add_spec.rb +0 -12
  81. data/spec/unit/choices/each_spec.rb +0 -13
  82. data/spec/unit/choices/find_by_spec.rb +0 -10
  83. data/spec/unit/choices/new_spec.rb +0 -10
  84. data/spec/unit/choices/pluck_spec.rb +0 -9
  85. data/spec/unit/collect_spec.rb +0 -96
  86. data/spec/unit/converters/convert_bool_spec.rb +0 -58
  87. data/spec/unit/converters/convert_char_spec.rb +0 -11
  88. data/spec/unit/converters/convert_custom_spec.rb +0 -14
  89. data/spec/unit/converters/convert_date_spec.rb +0 -34
  90. data/spec/unit/converters/convert_file_spec.rb +0 -18
  91. data/spec/unit/converters/convert_number_spec.rb +0 -39
  92. data/spec/unit/converters/convert_path_spec.rb +0 -15
  93. data/spec/unit/converters/convert_range_spec.rb +0 -22
  94. data/spec/unit/converters/convert_regex_spec.rb +0 -12
  95. data/spec/unit/converters/convert_string_spec.rb +0 -21
  96. data/spec/unit/converters/on_error_spec.rb +0 -9
  97. data/spec/unit/distance/distance_spec.rb +0 -73
  98. data/spec/unit/enum_select_spec.rb +0 -518
  99. data/spec/unit/error_spec.rb +0 -20
  100. data/spec/unit/evaluator_spec.rb +0 -67
  101. data/spec/unit/expand_spec.rb +0 -290
  102. data/spec/unit/keypress_spec.rb +0 -66
  103. data/spec/unit/mask_spec.rb +0 -140
  104. data/spec/unit/multi_select_spec.rb +0 -741
  105. data/spec/unit/multiline_spec.rb +0 -77
  106. data/spec/unit/new_spec.rb +0 -20
  107. data/spec/unit/ok_spec.rb +0 -10
  108. data/spec/unit/paginator_spec.rb +0 -92
  109. data/spec/unit/question/checks_spec.rb +0 -97
  110. data/spec/unit/question/default_spec.rb +0 -31
  111. data/spec/unit/question/echo_spec.rb +0 -38
  112. data/spec/unit/question/in_spec.rb +0 -115
  113. data/spec/unit/question/initialize_spec.rb +0 -12
  114. data/spec/unit/question/modifier/apply_to_spec.rb +0 -24
  115. data/spec/unit/question/modifier/letter_case_spec.rb +0 -41
  116. data/spec/unit/question/modifier/whitespace_spec.rb +0 -51
  117. data/spec/unit/question/modify_spec.rb +0 -41
  118. data/spec/unit/question/required_spec.rb +0 -92
  119. data/spec/unit/question/validate_spec.rb +0 -115
  120. data/spec/unit/question/validation/call_spec.rb +0 -31
  121. data/spec/unit/question/validation/coerce_spec.rb +0 -30
  122. data/spec/unit/result_spec.rb +0 -40
  123. data/spec/unit/say_spec.rb +0 -67
  124. data/spec/unit/select_spec.rb +0 -942
  125. data/spec/unit/slider_spec.rb +0 -142
  126. data/spec/unit/statement/initialize_spec.rb +0 -15
  127. data/spec/unit/subscribe_spec.rb +0 -22
  128. data/spec/unit/suggest_spec.rb +0 -28
  129. data/spec/unit/timer_spec.rb +0 -29
  130. data/spec/unit/warn_spec.rb +0 -21
  131. data/spec/unit/yes_no_spec.rb +0 -251
  132. data/tasks/console.rake +0 -11
  133. data/tasks/coverage.rake +0 -11
  134. data/tasks/spec.rake +0 -29
  135. data/tty-prompt.gemspec +0 -31
@@ -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
@@ -23,7 +23,7 @@ module TTY
23
23
  def check(proc = nil, &block)
24
24
  results << (proc || block)
25
25
  end
26
- alias_method :<<, :check
26
+ alias << check
27
27
  end # Evaluator
28
28
  end # Prompt
29
29
  end # TTY
@@ -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,21 +10,25 @@ 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
 
18
+ # Names for delete keys
19
+ DELETE_KEYS = %i[backspace delete].freeze
20
+
18
21
  # Create instance of Expander
19
22
  #
20
23
  # @api public
21
24
  def initialize(prompt, options = {})
22
25
  @prompt = prompt
23
26
  @prefix = options.fetch(:prefix) { @prompt.prefix }
24
- @default = options.fetch(:default) { 1 }
25
- @auto_hint = options.fetch(:auto_hint) { false }
27
+ @default = options.fetch(:default, 1)
28
+ @auto_hint = options.fetch(:auto_hint, false)
26
29
  @active_color = options.fetch(:active_color) { @prompt.active_color }
27
30
  @help_color = options.fetch(:help_color) { @prompt.help_color }
31
+ @quiet = options.fetch(:quiet) { @prompt.quiet }
28
32
  @choices = Choices.new
29
33
  @selected = nil
30
34
  @done = false
@@ -56,16 +60,16 @@ module TTY
56
60
 
57
61
  selected = select_choice(@input)
58
62
 
59
- if selected && selected.key.to_s == 'h'
63
+ if selected && selected.key.to_s == "h"
60
64
  expand
61
65
  @selected = nil
62
- @input = ''
66
+ @input = ""
63
67
  elsif selected
64
68
  @done = true
65
69
  @selected = selected
66
70
  @hint = nil
67
71
  else
68
- @input = ''
72
+ @input = ""
69
73
  end
70
74
  end
71
75
  alias keyreturn keyenter
@@ -74,7 +78,7 @@ module TTY
74
78
  #
75
79
  # @api public
76
80
  def keypress(event)
77
- if [:backspace, :delete].include?(event.key.name)
81
+ if DELETE_KEYS.include?(event.key.name)
78
82
  @input.chop! unless @input.empty?
79
83
  elsif event.value =~ /^[^\e\n\r]/
80
84
  @input += event.value
@@ -100,9 +104,17 @@ module TTY
100
104
  # @api public
101
105
  def default(value = (not_set = true))
102
106
  return @default if not_set
107
+
103
108
  @default = value
104
109
  end
105
110
 
111
+ # Set quiet mode.
112
+ #
113
+ # @api public
114
+ def quiet(value)
115
+ @quiet = value
116
+ end
117
+
106
118
  # Add a single choice
107
119
  #
108
120
  # @api public
@@ -154,19 +166,19 @@ module TTY
154
166
  elsif @input.to_s.empty? && default_key
155
167
  keys[@default - 1] = @prompt.decorate(default_key, @active_color)
156
168
  end
157
- keys.join(',')
169
+ keys.join(",")
158
170
  end
159
171
 
160
172
  # @api private
161
173
  def render
162
- @input = ''
174
+ @input = ""
163
175
  until @done
164
176
  question = render_question
165
177
  @prompt.print(question)
166
178
  read_input
167
179
  @prompt.print(refresh(question.lines.count))
168
180
  end
169
- @prompt.print(render_question)
181
+ @prompt.print(render_question) unless @quiet
170
182
  answer
171
183
  end
172
184
 
@@ -199,7 +211,7 @@ module TTY
199
211
  #
200
212
  # @api private
201
213
  def render_hint
202
- "\n" + @prompt.decorate('>> ', @active_color) +
214
+ "\n" + @prompt.decorate(">> ", @active_color) +
203
215
  @hint +
204
216
  @prompt.cursor.prev_line +
205
217
  @prompt.cursor.forward(@prompt.strip(render_header).size)
@@ -274,7 +286,7 @@ module TTY
274
286
  if @selected && @selected.key == choice.key
275
287
  chosen = @prompt.decorate(chosen, @active_color)
276
288
  end
277
- output << ' ' + chosen + "\n"
289
+ output << " " + chosen + "\n"
278
290
  end
279
291
  output.join
280
292
  end
@@ -294,7 +306,7 @@ module TTY
294
306
  if choice.key.length != 1
295
307
  errors << "Choice key `#{choice.key}` is more than one character long."
296
308
  end
297
- if choice.key.to_s == 'h'
309
+ if choice.key.to_s == "h"
298
310
  errors << "Choice key `#{choice.key}` is reserved for help menu."
299
311
  end
300
312
  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))
@@ -30,6 +30,7 @@ module TTY
30
30
 
31
31
  def countdown(value = (not_set = true))
32
32
  return @countdown if not_set
33
+
33
34
  @countdown = value
34
35
  end
35
36
 
@@ -81,6 +82,7 @@ module TTY
81
82
 
82
83
  @timer.while_remaining do |remaining|
83
84
  break if @done
85
+
84
86
  @input = @prompt.read_keypress(nonblock: true)
85
87
  end
86
88
  countdown(0) unless @done
@@ -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,11 +13,12 @@ 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
 
19
+ # Checks type of default parameter to be integer
20
+ INTEGER_MATCHER = /\A\d+\Z/.freeze
21
+
21
22
  # Create instance of TTY::Prompt::List menu.
22
23
  #
23
24
  # @param Hash options
@@ -45,9 +46,11 @@ module TTY
45
46
  @cycle = options.fetch(:cycle) { false }
46
47
  @filterable = options.fetch(:filter) { false }
47
48
  @symbols = @prompt.symbols.merge(options.fetch(:symbols, {}))
49
+ @quiet = options.fetch(:quiet) { @prompt.quiet }
48
50
  @filter = []
49
51
  @filter_cache = {}
50
52
  @help = options[:help]
53
+ @show_help = options.fetch(:show_help) { :start }
51
54
  @first_render = true
52
55
  @done = false
53
56
  @per_page = options[:per_page]
@@ -65,6 +68,7 @@ module TTY
65
68
  # @api public
66
69
  def symbols(new_symbols = (not_set = true))
67
70
  return @symbols if not_set
71
+
68
72
  @symbols.merge!(new_symbols)
69
73
  end
70
74
 
@@ -135,6 +139,15 @@ module TTY
135
139
  @help = (@help.nil? && !not_set) ? value : default_help
136
140
  end
137
141
 
142
+ # Change when help is displayed
143
+ #
144
+ # @api public
145
+ def show_help(value = (not_set = true))
146
+ return @show_ehlp if not_set
147
+
148
+ @show_help = value
149
+ end
150
+
138
151
  # Information about arrow keys
139
152
  #
140
153
  # @return [String]
@@ -145,25 +158,27 @@ module TTY
145
158
  left_right = @symbols[:arrow_left] + "/" + @symbols[:arrow_right]
146
159
 
147
160
  arrows = [up_down]
148
- arrows << " and " if paginated?
161
+ arrows << "/" if paginated?
149
162
  arrows << left_right if paginated?
150
163
  arrows.join
151
164
  end
152
165
 
153
166
  # Default help text
154
167
  #
155
- # @api public
168
+ # Note that enumeration and filter are mutually exclusive
169
+ #
170
+ # @a public
156
171
  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)
172
+ str = []
173
+ str << "(Press "
174
+ str << "#{arrows_help} arrow"
175
+ str << " or 1-#{choices.size} number" if enumerate?
176
+ str << " to move"
177
+ str << (filterable? ? "," : " and")
178
+ str << " Enter to select"
179
+ str << " and letters to filter" if filterable?
180
+ str << ")"
181
+ str.join
167
182
  end
168
183
 
169
184
  # Set selecting active index using number pad
@@ -173,6 +188,13 @@ module TTY
173
188
  @enum = value
174
189
  end
175
190
 
191
+ # Set whether selected answers are echoed
192
+ #
193
+ # @api public
194
+ def quiet(value)
195
+ @quiet = value
196
+ end
197
+
176
198
  # Add a single choice
177
199
  #
178
200
  # @api public
@@ -198,9 +220,8 @@ module TTY
198
220
  @choices
199
221
  else
200
222
  filter_value = @filter.join.downcase
201
- @filter_cache[filter_value] ||= @choices.select do |choice|
202
- !choice.disabled? &&
203
- choice.name.downcase.include?(filter_value)
223
+ @filter_cache[filter_value] ||= @choices.enabled.select do |choice|
224
+ choice.name.to_s.downcase.include?(filter_value)
204
225
  end
205
226
  end
206
227
  else
@@ -238,6 +259,7 @@ module TTY
238
259
  value = event.value.to_i
239
260
  return unless (1..choices.count).cover?(value)
240
261
  return if choices[value - 1].disabled?
262
+
241
263
  @active = value
242
264
  end
243
265
 
@@ -291,17 +313,19 @@ module TTY
291
313
  # When the choice on a page is outside of next page range then
292
314
  # adjust it to the last item, otherwise leave unchanged.
293
315
  def keyright(*)
294
- if (@active + page_size) <= @choices.size
295
- searchable = ((@active + page_size)..choices.length)
316
+ choices_size = choices.size
317
+ if (@active + page_size) <= choices_size
318
+ searchable = ((@active + page_size)..choices_size)
296
319
  @active = search_choice_in(searchable)
297
- elsif @active <= @choices.size # last page shorter
320
+ elsif @active <= choices_size # last page shorter
298
321
  current = @active % page_size
299
- remaining = @choices.size % page_size
322
+ remaining = choices_size % page_size
323
+
300
324
  if current.zero? || (remaining > 0 && current > remaining)
301
- searchable = @choices.size.downto(0).to_a
325
+ searchable = choices_size.downto(0).to_a
302
326
  @active = search_choice_in(searchable)
303
327
  elsif @cycle
304
- searchable = ((current.zero? ? page_size : current)..choices.length)
328
+ searchable = ((current.zero? ? page_size : current)..choices_size)
305
329
  @active = search_choice_in(searchable)
306
330
  end
307
331
  end
@@ -313,10 +337,10 @@ module TTY
313
337
 
314
338
  def keyleft(*)
315
339
  if (@active - page_size) > 0
316
- searchable = ((@active - page_size)..choices.length)
340
+ searchable = ((@active - page_size)..choices.size)
317
341
  @active = search_choice_in(searchable)
318
342
  elsif @cycle
319
- searchable = @choices.size.downto(1).to_a
343
+ searchable = choices.size.downto(1).to_a
320
344
  @active = search_choice_in(searchable)
321
345
  end
322
346
  @paging_changed = !@by_page
@@ -358,14 +382,19 @@ module TTY
358
382
 
359
383
  # Setup default option and active selection
360
384
  #
385
+ # @return [Integer]
386
+ #
361
387
  # @api private
362
388
  def setup_defaults
363
389
  validate_defaults
364
390
 
365
- if !@default.empty?
391
+ if @default.empty?
392
+ # no default, pick the first non-disabled choice
393
+ @active = choices.index { |choice| !choice.disabled? } + 1
394
+ elsif @default.first.to_s =~ INTEGER_MATCHER
366
395
  @active = @default.first
367
- else
368
- @active = @choices.index { |choice| !choice.disabled? } + 1
396
+ elsif default_choice = choices.find_by(:name, @default.first)
397
+ @active = choices.index(default_choice) + 1
369
398
  end
370
399
  end
371
400
 
@@ -380,16 +409,35 @@ module TTY
380
409
  @default.each do |d|
381
410
  msg = if d.nil? || d.to_s.empty?
382
411
  "default index must be an integer in range (1 - #{choices.size})"
412
+ elsif d.to_s !~ INTEGER_MATCHER
413
+ validate_default_name(d)
383
414
  elsif d < 1 || d > choices.size
384
415
  "default index `#{d}` out of range (1 - #{choices.size})"
385
- elsif choices[d - 1] && choices[d - 1].disabled?
386
- "default index `#{d}` matches disabled choice item"
416
+ elsif (dflt_choice = choices[d - 1]) && dflt_choice.disabled?
417
+ "default index `#{d}` matches disabled choice"
387
418
  end
388
419
 
389
420
  raise(ConfigurationError, msg) if msg
390
421
  end
391
422
  end
392
423
 
424
+ # Validate default choice name
425
+ #
426
+ # @param [String] name
427
+ # the name to verify
428
+ #
429
+ # @return [String]
430
+ #
431
+ # @api private
432
+ def validate_default_name(name)
433
+ default_choice = choices.find_by(:name, name.to_s)
434
+ if default_choice.nil?
435
+ "no choice found for the default name: #{name.inspect}"
436
+ elsif default_choice.disabled?
437
+ "default name #{name.inspect} matches disabled choice"
438
+ end
439
+ end
440
+
393
441
  # Render a selection list.
394
442
  #
395
443
  # By default the result is printed out.
@@ -411,7 +459,7 @@ module TTY
411
459
 
412
460
  @prompt.print(refresh(question_lines_count(question_lines)))
413
461
  end
414
- @prompt.print(render_question)
462
+ @prompt.print(render_question) unless @quiet
415
463
  answer
416
464
  ensure
417
465
  @prompt.print(@prompt.show)
@@ -478,6 +526,20 @@ module TTY
478
526
  "(Filter: #{@filter.join.inspect})"
479
527
  end
480
528
 
529
+ # Check if help is shown only on start
530
+ #
531
+ # @api private
532
+ def help_start?
533
+ @show_help =~ /start/i
534
+ end
535
+
536
+ # Check if help is always displayed
537
+ #
538
+ # @api private
539
+ def help_always?
540
+ @show_help =~ /always/i
541
+ end
542
+
481
543
  # Render initial help and selected choice
482
544
  #
483
545
  # @return [String]
@@ -487,7 +549,8 @@ module TTY
487
549
  if @done
488
550
  selected_item = choices[@active - 1].name
489
551
  @prompt.decorate(selected_item.to_s, @active_color)
490
- elsif @first_render
552
+ elsif (@first_render && (help_start? || help_always?)) ||
553
+ (help_always? && !@filter.any?)
491
554
  @prompt.decorate(help, @help_color)
492
555
  elsif filterable? && @filter.any?
493
556
  @prompt.decorate(filter_help, @help_color)
@@ -504,7 +567,7 @@ module TTY
504
567
 
505
568
  sync_paginators if @paging_changed
506
569
  paginator.paginate(choices, @active, @per_page) do |choice, index|
507
- num = enumerate? ? (index + 1).to_s + @enum + ' ' : ''
570
+ num = enumerate? ? (index + 1).to_s + @enum + " " : ""
508
571
  message = if index + 1 == @active && !choice.disabled?
509
572
  selected = "#{@symbols[:marker]} #{num}#{choice.name}"
510
573
  @prompt.decorate(selected.to_s, @active_color)
@@ -515,7 +578,7 @@ module TTY
515
578
  " #{num}#{choice.name}"
516
579
  end
517
580
  end_index = paginated? ? paginator.end_index : choices.size - 1
518
- newline = (index == end_index) ? '' : "\n"
581
+ newline = (index == end_index) ? "" : "\n"
519
582
  output << (message + newline)
520
583
  end
521
584