highline 1.7.10 → 2.0.0.pre.develop.2
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 +4 -4
- data/.gitignore +2 -0
- data/.simplecov +5 -0
- data/.travis.yml +11 -6
- data/Changelog.md +112 -20
- data/Gemfile +8 -7
- data/README.rdoc +3 -0
- data/Rakefile +7 -2
- data/appveyor.yml +19 -0
- data/examples/asking_for_arrays.rb +3 -0
- data/examples/basic_usage.rb +3 -0
- data/examples/get_character.rb +3 -0
- data/examples/limit.rb +3 -0
- data/examples/menus.rb +3 -0
- data/examples/overwrite.rb +3 -0
- data/examples/password.rb +3 -0
- data/examples/repeat_entry.rb +4 -1
- data/lib/highline.rb +182 -704
- data/lib/highline/builtin_styles.rb +109 -0
- data/lib/highline/color_scheme.rb +4 -1
- data/lib/highline/compatibility.rb +2 -0
- data/lib/highline/custom_errors.rb +19 -0
- data/lib/highline/import.rb +4 -2
- data/lib/highline/list.rb +93 -0
- data/lib/highline/list_renderer.rb +232 -0
- data/lib/highline/menu.rb +20 -20
- data/lib/highline/paginator.rb +43 -0
- data/lib/highline/question.rb +157 -97
- data/lib/highline/question/answer_converter.rb +84 -0
- data/lib/highline/question_asker.rb +147 -0
- data/lib/highline/simulate.rb +5 -1
- data/lib/highline/statement.rb +58 -0
- data/lib/highline/string.rb +34 -0
- data/lib/highline/string_extensions.rb +3 -28
- data/lib/highline/style.rb +18 -8
- data/lib/highline/template_renderer.rb +38 -0
- data/lib/highline/terminal.rb +78 -0
- data/lib/highline/terminal/io_console.rb +98 -0
- data/lib/highline/terminal/ncurses.rb +38 -0
- data/lib/highline/terminal/unix_stty.rb +94 -0
- data/lib/highline/version.rb +3 -1
- data/lib/highline/wrapper.rb +43 -0
- data/test/acceptance/acceptance.rb +62 -0
- data/test/acceptance/acceptance_test.rb +69 -0
- data/test/acceptance/at_color_output_using_erb_templates.rb +17 -0
- data/test/acceptance/at_echo_false.rb +23 -0
- data/test/acceptance/at_readline.rb +37 -0
- data/test/io_console_compatible.rb +37 -0
- data/test/string_methods.rb +3 -0
- data/test/test_answer_converter.rb +26 -0
- data/test/{tc_color_scheme.rb → test_color_scheme.rb} +7 -9
- data/test/test_helper.rb +26 -0
- data/test/{tc_highline.rb → test_highline.rb} +193 -136
- data/test/{tc_import.rb → test_import.rb} +5 -2
- data/test/test_list.rb +60 -0
- data/test/{tc_menu.rb → test_menu.rb} +6 -3
- data/test/test_paginator.rb +73 -0
- data/test/test_question_asker.rb +20 -0
- data/test/test_simulator.rb +24 -0
- data/test/test_string_extension.rb +72 -0
- data/test/{tc_string_highline.rb → test_string_highline.rb} +7 -3
- data/test/{tc_style.rb → test_style.rb} +70 -35
- data/test/test_wrapper.rb +188 -0
- metadata +57 -22
- data/lib/highline/system_extensions.rb +0 -254
- data/test/tc_simulator.rb +0 -33
- data/test/tc_string_extension.rb +0 -33
data/lib/highline/menu.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#--
|
1
4
|
# menu.rb
|
2
5
|
#
|
3
6
|
# Created by Gregory Thomas Brown on 2005-05-10.
|
@@ -136,7 +139,7 @@ class HighLine
|
|
136
139
|
def choice( name, help = nil, &action )
|
137
140
|
@items << [name, action]
|
138
141
|
|
139
|
-
@help[name.to_s.downcase] = help
|
142
|
+
@help[name.to_s.downcase] = help if help
|
140
143
|
update_responses # rebuild responses based on our settings
|
141
144
|
end
|
142
145
|
|
@@ -154,7 +157,7 @@ class HighLine
|
|
154
157
|
def hidden( name, help = nil, &action )
|
155
158
|
@hidden_items << [name, action]
|
156
159
|
|
157
|
-
@help[name.to_s.downcase] = help
|
160
|
+
@help[name.to_s.downcase] = help if help
|
158
161
|
end
|
159
162
|
|
160
163
|
#
|
@@ -235,11 +238,10 @@ class HighLine
|
|
235
238
|
# <tt>:menu_only</tt>:: Just the menu items, followed up by a likely
|
236
239
|
# short _prompt_.
|
237
240
|
# <i>any ERb String</i>:: Will be taken as the literal _layout_. This
|
238
|
-
# String can access <tt
|
239
|
-
# <tt
|
240
|
-
# otherwise evaluated in the
|
241
|
-
# context
|
242
|
-
# HighLine.list() primarily.
|
241
|
+
# String can access <tt>header</tt>,
|
242
|
+
# <tt>menu</tt> and <tt>prompt</tt>, but is
|
243
|
+
# otherwise evaluated in the TemplateRenderer
|
244
|
+
# context so each method is properly delegated.
|
243
245
|
#
|
244
246
|
# If set to either <tt>:one_line</tt>, or <tt>:menu_only</tt>, _index_
|
245
247
|
# will default to <tt>:none</tt> and _flow_ will default to
|
@@ -304,7 +306,7 @@ class HighLine
|
|
304
306
|
end
|
305
307
|
|
306
308
|
# Run or return it.
|
307
|
-
if
|
309
|
+
if action
|
308
310
|
@highline = highline_context
|
309
311
|
if @shell
|
310
312
|
result = action.call(name, details)
|
@@ -312,10 +314,8 @@ class HighLine
|
|
312
314
|
result = action.call(name)
|
313
315
|
end
|
314
316
|
@nil_on_handled ? nil : result
|
315
|
-
elsif action.nil?
|
316
|
-
name
|
317
317
|
else
|
318
|
-
|
318
|
+
name
|
319
319
|
end
|
320
320
|
ensure
|
321
321
|
# make sure the hidden items are removed, before we return
|
@@ -348,19 +348,19 @@ class HighLine
|
|
348
348
|
def to_s( )
|
349
349
|
case @layout
|
350
350
|
when :list
|
351
|
-
|
352
|
-
"<%= list(
|
351
|
+
%(<%= header ? "#{header}:\n" : '' %>) +
|
352
|
+
"<%= list( menu, #{@flow.inspect},
|
353
353
|
#{@list_option.inspect} ) %>" +
|
354
|
-
"<%=
|
354
|
+
"<%= prompt %>"
|
355
355
|
when :one_line
|
356
|
-
|
357
|
-
"<%=
|
358
|
-
"(<%= list(
|
356
|
+
%(<%= header ? "#{header}: " : '' %>) +
|
357
|
+
"<%= prompt %>" +
|
358
|
+
"(<%= list( menu, #{@flow.inspect},
|
359
359
|
#{@list_option.inspect} ) %>)" +
|
360
|
-
"<%=
|
360
|
+
"<%= prompt[/\s*$/] %>"
|
361
361
|
when :menu_only
|
362
|
-
"<%= list(
|
363
|
-
#{@list_option.inspect} ) %><%=
|
362
|
+
"<%= list( menu, #{@flow.inspect},
|
363
|
+
#{@list_option.inspect} ) %><%= prompt %>"
|
364
364
|
else
|
365
365
|
@layout
|
366
366
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
class HighLine
|
4
|
+
class Paginator
|
5
|
+
attr_reader :highline
|
6
|
+
|
7
|
+
def initialize(highline)
|
8
|
+
@highline = highline
|
9
|
+
end
|
10
|
+
|
11
|
+
#
|
12
|
+
# Page print a series of at most _page_at_ lines for _output_. After each
|
13
|
+
# page is printed, HighLine will pause until the user presses enter/return
|
14
|
+
# then display the next page of data.
|
15
|
+
#
|
16
|
+
# Note that the final page of _output_ is *not* printed, but returned
|
17
|
+
# instead. This is to support any special handling for the final sequence.
|
18
|
+
#
|
19
|
+
def page_print(text)
|
20
|
+
return text unless highline.page_at
|
21
|
+
|
22
|
+
lines = text.lines.to_a
|
23
|
+
while lines.size > highline.page_at
|
24
|
+
highline.puts lines.slice!(0...highline.page_at).join
|
25
|
+
highline.puts
|
26
|
+
# Return last line if user wants to abort paging
|
27
|
+
return "...\n#{lines.last}" unless continue_paging?
|
28
|
+
end
|
29
|
+
return lines.join
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# Ask user if they wish to continue paging output. Allows them to type "q" to
|
34
|
+
# cancel the paging process.
|
35
|
+
#
|
36
|
+
def continue_paging?
|
37
|
+
command = highline.new_scope.ask(
|
38
|
+
"-- press enter/return to continue or q to stop -- "
|
39
|
+
) { |q| q.character = true }
|
40
|
+
command !~ /\A[qQ]\Z/ # Only continue paging if Q was not hit.
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/highline/question.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#--
|
1
4
|
# question.rb
|
2
5
|
#
|
3
6
|
# Created by James Edward Gray II on 2005-04-26.
|
@@ -8,6 +11,7 @@
|
|
8
11
|
require "optparse"
|
9
12
|
require "date"
|
10
13
|
require "pathname"
|
14
|
+
require "highline/question/answer_converter"
|
11
15
|
|
12
16
|
class HighLine
|
13
17
|
#
|
@@ -17,23 +21,32 @@ class HighLine
|
|
17
21
|
# process is handled according to the users wishes.
|
18
22
|
#
|
19
23
|
class Question
|
20
|
-
|
21
|
-
|
22
|
-
|
24
|
+
include CustomErrors
|
25
|
+
|
26
|
+
#
|
27
|
+
# If _template_or_question_ is already a Question object just return it.
|
28
|
+
# If not, build it.
|
29
|
+
#
|
30
|
+
def self.build(template_or_question, answer_type = nil, &details)
|
31
|
+
if template_or_question.is_a? Question
|
32
|
+
template_or_question
|
33
|
+
else
|
34
|
+
Question.new(template_or_question, answer_type, &details)
|
35
|
+
end
|
23
36
|
end
|
24
37
|
|
25
38
|
#
|
26
|
-
# Create an instance of HighLine::Question. Expects a
|
39
|
+
# Create an instance of HighLine::Question. Expects a _template_ to ask
|
27
40
|
# (can be <tt>""</tt>) and an _answer_type_ to convert the answer to.
|
28
41
|
# The _answer_type_ parameter must be a type recognized by
|
29
42
|
# Question.convert(). If given, a block is yielded the new Question
|
30
43
|
# object to allow custom initialization.
|
31
44
|
#
|
32
|
-
def initialize(
|
45
|
+
def initialize(template, answer_type)
|
33
46
|
# initialize instance data
|
34
|
-
@
|
47
|
+
@template = template.dup
|
35
48
|
@answer_type = answer_type
|
36
|
-
@completion
|
49
|
+
@completion = @answer_type
|
37
50
|
|
38
51
|
@character = nil
|
39
52
|
@limit = nil
|
@@ -63,7 +76,11 @@ class HighLine
|
|
63
76
|
end
|
64
77
|
|
65
78
|
# The ERb template of the question to be asked.
|
66
|
-
attr_accessor :
|
79
|
+
attr_accessor :template
|
80
|
+
|
81
|
+
# The answer, set by HighLine#ask
|
82
|
+
attr_accessor :answer
|
83
|
+
|
67
84
|
# The type that will be used to convert this answer.
|
68
85
|
attr_accessor :answer_type
|
69
86
|
# For Auto-completion
|
@@ -214,12 +231,9 @@ class HighLine
|
|
214
231
|
# Returns the provided _answer_string_ or the default answer for this
|
215
232
|
# Question if a default was set and the answer is empty.
|
216
233
|
#
|
217
|
-
def answer_or_default(
|
218
|
-
if answer_string.
|
219
|
-
|
220
|
-
else
|
221
|
-
answer_string
|
222
|
-
end
|
234
|
+
def answer_or_default(answer_string)
|
235
|
+
return @default if answer_string.empty? && @default
|
236
|
+
answer_string
|
223
237
|
end
|
224
238
|
|
225
239
|
#
|
@@ -230,35 +244,28 @@ class HighLine
|
|
230
244
|
def build_responses(message_source = answer_type, new_hash_wins = false)
|
231
245
|
append_default if [::String, Symbol].include? default.class
|
232
246
|
|
233
|
-
choice_error_str_func = lambda do
|
234
|
-
message_source.is_a?(Array) \
|
235
|
-
? '[' + message_source.map { |s| "#{s}" }.join(', ') + ']' \
|
236
|
-
: message_source.inspect
|
237
|
-
end
|
238
|
-
|
239
247
|
old_hash = @responses
|
240
248
|
|
241
|
-
new_hash =
|
242
|
-
"Ambiguous choice. Please choose one of " +
|
243
|
-
choice_error_str_func.call + '.',
|
244
|
-
:ask_on_error =>
|
245
|
-
"? ",
|
246
|
-
:invalid_type =>
|
247
|
-
"You must enter a valid #{message_source}.",
|
248
|
-
:no_completion =>
|
249
|
-
"You must choose one of " + choice_error_str_func.call + '.',
|
250
|
-
:not_in_range =>
|
251
|
-
"Your answer isn't within the expected range " +
|
252
|
-
"(#{expected_range}).",
|
253
|
-
:mismatch =>
|
254
|
-
"Your entries didn't match.",
|
255
|
-
:not_valid =>
|
256
|
-
"Your answer isn't valid (must match " +
|
257
|
-
"#{@validate.inspect})." }
|
249
|
+
new_hash = build_responses_new_hash(message_source)
|
258
250
|
|
259
251
|
@responses = new_hash_wins ? old_hash.merge(new_hash) : new_hash.merge(old_hash)
|
260
252
|
end
|
261
253
|
|
254
|
+
def build_responses_new_hash(message_source)
|
255
|
+
{ :ambiguous_completion => "Ambiguous choice. Please choose one of " +
|
256
|
+
choice_error_str(message_source) + '.',
|
257
|
+
:ask_on_error => "? ",
|
258
|
+
:invalid_type => "You must enter a valid #{message_source}.",
|
259
|
+
:no_completion => "You must choose one of " +
|
260
|
+
choice_error_str(message_source) + '.',
|
261
|
+
:not_in_range => "Your answer isn't within the expected range " +
|
262
|
+
"(#{expected_range}).",
|
263
|
+
:mismatch => "Your entries didn't match.",
|
264
|
+
:not_valid => "Your answer isn't valid (must match " +
|
265
|
+
"#{@validate.inspect})." }
|
266
|
+
end
|
267
|
+
|
268
|
+
|
262
269
|
#
|
263
270
|
# Returns the provided _answer_string_ after changing character case by
|
264
271
|
# the rules of this Question. Valid settings for whitespace are:
|
@@ -273,7 +280,7 @@ class HighLine
|
|
273
280
|
#
|
274
281
|
# An unrecognized choice (like <tt>:none</tt>) is treated as +nil+.
|
275
282
|
#
|
276
|
-
def change_case(
|
283
|
+
def change_case(answer_string)
|
277
284
|
if [:up, :upcase].include?(@case)
|
278
285
|
answer_string.upcase
|
279
286
|
elsif [:down, :downcase].include?(@case)
|
@@ -314,46 +321,30 @@ class HighLine
|
|
314
321
|
# This method throws ArgumentError, if the conversion cannot be
|
315
322
|
# completed for any reason.
|
316
323
|
#
|
317
|
-
def convert
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
answer = choices.complete(answer_string)
|
333
|
-
if answer.nil?
|
334
|
-
raise NoAutoCompleteMatch
|
335
|
-
end
|
336
|
-
if @answer_type.is_a?(Array)
|
337
|
-
answer.last
|
338
|
-
elsif @answer_type == File
|
339
|
-
File.open(File.join(@directory.to_s, answer.last))
|
340
|
-
else
|
341
|
-
Pathname.new(File.join(@directory.to_s, answer.last))
|
342
|
-
end
|
343
|
-
elsif [Date, DateTime].include?(@answer_type) or @answer_type.is_a?(Class)
|
344
|
-
@answer_type.parse(answer_string)
|
345
|
-
elsif @answer_type.is_a?(Proc)
|
346
|
-
@answer_type[answer_string]
|
347
|
-
end
|
324
|
+
def convert
|
325
|
+
AnswerConverter.new(self).convert
|
326
|
+
end
|
327
|
+
|
328
|
+
def check_range
|
329
|
+
raise NotInRangeQuestionError unless in_range?
|
330
|
+
end
|
331
|
+
|
332
|
+
def choices_complete(answer_string)
|
333
|
+
# cheating, using OptionParser's Completion module
|
334
|
+
choices = selection
|
335
|
+
choices.extend(OptionParser::Completion)
|
336
|
+
answer = choices.complete(answer_string)
|
337
|
+
raise NoAutoCompleteMatch unless answer
|
338
|
+
answer
|
348
339
|
end
|
349
340
|
|
350
341
|
# Returns an English explanation of the current range settings.
|
351
|
-
def expected_range
|
342
|
+
def expected_range
|
352
343
|
expected = [ ]
|
353
344
|
|
354
|
-
expected << "above #{@above}"
|
355
|
-
expected << "below #{@below}"
|
356
|
-
expected << "included in #{@in.inspect}"
|
345
|
+
expected << "above #{@above}" if @above
|
346
|
+
expected << "below #{@below}" if @below
|
347
|
+
expected << "included in #{@in.inspect}" if @in
|
357
348
|
|
358
349
|
case expected.size
|
359
350
|
when 0 then ""
|
@@ -364,15 +355,15 @@ class HighLine
|
|
364
355
|
end
|
365
356
|
|
366
357
|
# Returns _first_answer_, which will be unset following this call.
|
367
|
-
def first_answer
|
358
|
+
def first_answer
|
368
359
|
@first_answer
|
369
360
|
ensure
|
370
361
|
@first_answer = nil
|
371
362
|
end
|
372
363
|
|
373
364
|
# Returns true if _first_answer_ is set.
|
374
|
-
def first_answer?
|
375
|
-
|
365
|
+
def first_answer?
|
366
|
+
!!@first_answer
|
376
367
|
end
|
377
368
|
|
378
369
|
#
|
@@ -381,10 +372,10 @@ class HighLine
|
|
381
372
|
# _in_ attribute. Otherwise, +false+ is returned. Any +nil+ attributes
|
382
373
|
# are not checked.
|
383
374
|
#
|
384
|
-
def in_range?
|
385
|
-
(
|
386
|
-
(
|
387
|
-
(
|
375
|
+
def in_range?
|
376
|
+
(!@above or answer > @above) and
|
377
|
+
(!@below or answer < @below) and
|
378
|
+
(!@in or @in.include?(answer))
|
388
379
|
end
|
389
380
|
|
390
381
|
#
|
@@ -406,8 +397,8 @@ class HighLine
|
|
406
397
|
#
|
407
398
|
# This process is skipped for single character input.
|
408
399
|
#
|
409
|
-
def remove_whitespace(
|
410
|
-
if
|
400
|
+
def remove_whitespace(answer_string)
|
401
|
+
if !@whitespace
|
411
402
|
answer_string
|
412
403
|
elsif [:strip, :chomp].include?(@whitespace)
|
413
404
|
answer_string.send(@whitespace)
|
@@ -423,12 +414,18 @@ class HighLine
|
|
423
414
|
end
|
424
415
|
end
|
425
416
|
|
417
|
+
def format_answer(answer_string)
|
418
|
+
answer_string = String(answer_string)
|
419
|
+
answer_string = remove_whitespace(answer_string)
|
420
|
+
change_case(answer_string)
|
421
|
+
end
|
422
|
+
|
426
423
|
#
|
427
424
|
# Returns an Array of valid answers to this question. These answers are
|
428
425
|
# only known when _answer_type_ is set to an Array of choices, File, or
|
429
426
|
# Pathname. Any other time, this method will return an empty Array.
|
430
427
|
#
|
431
|
-
def selection
|
428
|
+
def selection
|
432
429
|
if @completion.is_a?(Array)
|
433
430
|
@completion
|
434
431
|
elsif [File, Pathname].include?(@completion)
|
@@ -440,9 +437,9 @@ class HighLine
|
|
440
437
|
end
|
441
438
|
end
|
442
439
|
|
443
|
-
# Stringifies the
|
440
|
+
# Stringifies the template to be asked.
|
444
441
|
def to_s
|
445
|
-
@
|
442
|
+
@template
|
446
443
|
end
|
447
444
|
|
448
445
|
#
|
@@ -452,10 +449,65 @@ class HighLine
|
|
452
449
|
# It's important to realize that an answer is validated after whitespace
|
453
450
|
# and case handling.
|
454
451
|
#
|
455
|
-
def valid_answer?
|
456
|
-
|
457
|
-
(@validate.is_a?(Regexp) and
|
458
|
-
(@validate.is_a?(Proc) and @validate[
|
452
|
+
def valid_answer?
|
453
|
+
!@validate or
|
454
|
+
(@validate.is_a?(Regexp) and answer =~ @validate) or
|
455
|
+
(@validate.is_a?(Proc) and @validate[answer])
|
456
|
+
end
|
457
|
+
|
458
|
+
#
|
459
|
+
# Return a line or character of input, as requested for this question.
|
460
|
+
# Character input will be returned as a single character String,
|
461
|
+
# not an Integer.
|
462
|
+
#
|
463
|
+
# This question's _first_answer_ will be returned instead of input, if set.
|
464
|
+
#
|
465
|
+
# Raises EOFError if input is exhausted.
|
466
|
+
#
|
467
|
+
def get_response(highline)
|
468
|
+
return first_answer if first_answer?
|
469
|
+
|
470
|
+
case character
|
471
|
+
when :getc
|
472
|
+
highline.get_response_getc_mode(self)
|
473
|
+
when true
|
474
|
+
highline.get_response_character_mode(self)
|
475
|
+
else
|
476
|
+
highline.get_response_line_mode(self)
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
def get_response_or_default(highline)
|
481
|
+
self.answer = answer_or_default(get_response(highline))
|
482
|
+
end
|
483
|
+
|
484
|
+
def confirm_question(highline)
|
485
|
+
if confirm == true
|
486
|
+
"Are you sure? "
|
487
|
+
else
|
488
|
+
# evaluate ERb under initial scope, so it will have
|
489
|
+
# access to question and answer
|
490
|
+
template = ERB.new(confirm, nil, "%")
|
491
|
+
template_renderer = TemplateRenderer.new(template, self, highline)
|
492
|
+
template_renderer.render
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
def ask_on_error_msg
|
497
|
+
if responses[:ask_on_error] == :question
|
498
|
+
self
|
499
|
+
elsif responses[:ask_on_error]
|
500
|
+
responses[:ask_on_error]
|
501
|
+
end
|
502
|
+
end
|
503
|
+
|
504
|
+
# readline() needs to handle its own output, but readline only supports
|
505
|
+
# full line reading. Therefore if question.echo is anything but true,
|
506
|
+
# the prompt will not be issued. And we have to account for that now.
|
507
|
+
# Also, JRuby-1.7's ConsoleReader.readLine() needs to be passed the prompt
|
508
|
+
# to handle line editing properly.
|
509
|
+
def show_question(highline)
|
510
|
+
highline.say(self) unless (@readline && (@echo == true && !@limit))
|
459
511
|
end
|
460
512
|
|
461
513
|
private
|
@@ -465,15 +517,23 @@ class HighLine
|
|
465
517
|
# Trailing whitespace is preserved so the function of HighLine.say() is
|
466
518
|
# not affected.
|
467
519
|
#
|
468
|
-
def append_default
|
469
|
-
if @
|
470
|
-
@
|
471
|
-
elsif @
|
472
|
-
@
|
473
|
-
elsif @
|
474
|
-
@
|
520
|
+
def append_default
|
521
|
+
if @template =~ /([\t ]+)\Z/
|
522
|
+
@template << "|#{@default}|#{$1}"
|
523
|
+
elsif @template == ""
|
524
|
+
@template << "|#{@default}| "
|
525
|
+
elsif @template[-1, 1] == "\n"
|
526
|
+
@template[-2, 0] = " |#{@default}|"
|
527
|
+
else
|
528
|
+
@template << " |#{@default}|"
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
532
|
+
def choice_error_str(message_source)
|
533
|
+
if message_source.is_a? Array
|
534
|
+
'[' + message_source.join(', ') + ']'
|
475
535
|
else
|
476
|
-
|
536
|
+
message_source.inspect
|
477
537
|
end
|
478
538
|
end
|
479
539
|
end
|