highline 1.6.2 → 1.6.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +24 -0
- data/Rakefile +4 -4
- data/lib/highline.rb +283 -130
- data/lib/highline/color_scheme.rb +20 -2
- data/lib/highline/menu.rb +1 -1
- data/lib/highline/question.rb +3 -0
- data/lib/highline/string_extensions.rb +98 -0
- data/lib/highline/style.rb +184 -0
- data/test/string_methods.rb +34 -0
- data/test/tc_color_scheme.rb +42 -0
- data/test/tc_highline.rb +133 -4
- data/test/tc_string_extension.rb +22 -0
- data/test/tc_string_highline.rb +40 -0
- data/test/tc_style.rb +569 -0
- data/test/ts_all.rb +3 -0
- metadata +32 -30
data/CHANGELOG
CHANGED
@@ -2,6 +2,30 @@
|
|
2
2
|
|
3
3
|
Below is a complete listing of changes for each revision of HighLine.
|
4
4
|
|
5
|
+
== 1.6.5
|
6
|
+
|
7
|
+
* HighLine#list() now correctly handles empty lists (fix by Lachlan Dowding).
|
8
|
+
* HighLine#list() now supports <tt>:uneven_columns_across</tt> and
|
9
|
+
<tt>:uneven_columns_down</tt> modes.
|
10
|
+
|
11
|
+
== 1.6.4
|
12
|
+
|
13
|
+
* Add introspection methods to color_scheme: definition, keys, to_hash.
|
14
|
+
* Add tests for new methods.
|
15
|
+
|
16
|
+
== 1.6.3
|
17
|
+
|
18
|
+
* Add color NONE.
|
19
|
+
* Add RGB color capability.
|
20
|
+
* Made 'color' available as a class or instance method of HighLine, for
|
21
|
+
instance: HighLine.color("foo", :blue)) or highline_obj.color("foo", :blue)
|
22
|
+
are now both possible and equivalent.
|
23
|
+
* Add HighLine::String class with convenience methods: #color (alias
|
24
|
+
#foreground), #on (alias #background), colors, and styles. See
|
25
|
+
lib/string_extensions.rb.
|
26
|
+
* Add (optional) ability to extend String with the same convenience methods from
|
27
|
+
HighLine::String, using Highline.colorize_strings.
|
28
|
+
|
5
29
|
== 1.6.2
|
6
30
|
|
7
31
|
* Correctly handle STDIN being closed before we receive any data (fix by
|
data/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require "
|
1
|
+
require "rdoc/task"
|
2
2
|
require "rake/testtask"
|
3
|
-
require "
|
3
|
+
require "rubygems/package_task"
|
4
4
|
|
5
5
|
require "rubygems"
|
6
6
|
|
@@ -12,7 +12,7 @@ task :default => [:test]
|
|
12
12
|
|
13
13
|
Rake::TestTask.new do |test|
|
14
14
|
test.libs << "test"
|
15
|
-
test.test_files = [ "test/ts_all.rb"
|
15
|
+
test.test_files = [ "test/ts_all.rb"]
|
16
16
|
test.verbose = true
|
17
17
|
end
|
18
18
|
|
@@ -63,7 +63,7 @@ minutes of work.
|
|
63
63
|
END_DESC
|
64
64
|
end
|
65
65
|
|
66
|
-
|
66
|
+
Gem::PackageTask.new(spec) do |pkg|
|
67
67
|
pkg.need_zip = true
|
68
68
|
pkg.need_tar = true
|
69
69
|
end
|
data/lib/highline.rb
CHANGED
@@ -17,6 +17,7 @@ require "highline/system_extensions"
|
|
17
17
|
require "highline/question"
|
18
18
|
require "highline/menu"
|
19
19
|
require "highline/color_scheme"
|
20
|
+
require "highline/style"
|
20
21
|
|
21
22
|
#
|
22
23
|
# A HighLine object is a "high-level line oriented" shell over an input and an
|
@@ -29,7 +30,7 @@ require "highline/color_scheme"
|
|
29
30
|
#
|
30
31
|
class HighLine
|
31
32
|
# The version of the installed library.
|
32
|
-
VERSION = "1.6.
|
33
|
+
VERSION = "1.6.5".freeze
|
33
34
|
|
34
35
|
# An internal HighLine error. User code does not need to trap this.
|
35
36
|
class QuestionError < StandardError
|
@@ -49,6 +50,13 @@ class HighLine
|
|
49
50
|
@@use_color
|
50
51
|
end
|
51
52
|
|
53
|
+
# For checking if the current version of HighLine supports RGB colors
|
54
|
+
# Usage: HighLine.supports_rgb_color? rescue false # rescue for compatibility with older versions
|
55
|
+
# Note: color usage also depends on HighLine.use_color being set
|
56
|
+
def self.supports_rgb_color?
|
57
|
+
true
|
58
|
+
end
|
59
|
+
|
52
60
|
# The setting used to disable EOF tracking.
|
53
61
|
@@track_eof = true
|
54
62
|
|
@@ -83,62 +91,85 @@ class HighLine
|
|
83
91
|
#
|
84
92
|
# Embed in a String to clear all previous ANSI sequences. This *MUST* be
|
85
93
|
# done before the program exits!
|
86
|
-
#
|
87
|
-
|
88
|
-
#
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
#
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
#
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
#
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
#
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
94
|
+
#
|
95
|
+
|
96
|
+
ERASE_LINE_STYLE = Style.new(:name=>:erase_line, :builtin=>true, :code=>"\e[K") # Erase the current line of terminal output
|
97
|
+
ERASE_CHAR_STYLE = Style.new(:name=>:erase_char, :builtin=>true, :code=>"\e[P") # Erase the character under the cursor.
|
98
|
+
CLEAR_STYLE = Style.new(:name=>:clear, :builtin=>true, :code=>"\e[0m") # Clear color settings
|
99
|
+
RESET_STYLE = Style.new(:name=>:reset, :builtin=>true, :code=>"\e[0m") # Alias for CLEAR.
|
100
|
+
BOLD_STYLE = Style.new(:name=>:bold, :builtin=>true, :code=>"\e[1m") # Bold; Note: bold + a color works as you'd expect,
|
101
|
+
# for example bold black. Bold without a color displays
|
102
|
+
# the system-defined bold color (e.g. red on Mac iTerm)
|
103
|
+
DARK_STYLE = Style.new(:name=>:dark, :builtin=>true, :code=>"\e[2m") # Dark; support uncommon
|
104
|
+
UNDERLINE_STYLE = Style.new(:name=>:underline, :builtin=>true, :code=>"\e[4m") # Underline
|
105
|
+
UNDERSCORE_STYLE = Style.new(:name=>:underscore, :builtin=>true, :code=>"\e[4m") # Alias for UNDERLINE
|
106
|
+
BLINK_STYLE = Style.new(:name=>:blink, :builtin=>true, :code=>"\e[5m") # Blink; support uncommon
|
107
|
+
REVERSE_STYLE = Style.new(:name=>:reverse, :builtin=>true, :code=>"\e[7m") # Reverse foreground and background
|
108
|
+
CONCEALED_STYLE = Style.new(:name=>:concealed, :builtin=>true, :code=>"\e[8m") # Concealed; support uncommon
|
109
|
+
|
110
|
+
STYLES = %w{CLEAR RESET BOLD DARK UNDERLINE UNDERSCORE BLINK REVERSE CONCEALED}
|
111
|
+
|
112
|
+
# These RGB colors are approximate; see http://en.wikipedia.org/wiki/ANSI_escape_code
|
113
|
+
BLACK_STYLE = Style.new(:name=>:black, :builtin=>true, :code=>"\e[30m", :rgb=>[ 0, 0, 0])
|
114
|
+
RED_STYLE = Style.new(:name=>:red, :builtin=>true, :code=>"\e[31m", :rgb=>[128, 0, 0])
|
115
|
+
GREEN_STYLE = Style.new(:name=>:green, :builtin=>true, :code=>"\e[32m", :rgb=>[ 0,128, 0])
|
116
|
+
BLUE_STYLE = Style.new(:name=>:blue, :builtin=>true, :code=>"\e[34m", :rgb=>[ 0, 0,128])
|
117
|
+
YELLOW_STYLE = Style.new(:name=>:yellow, :builtin=>true, :code=>"\e[33m", :rgb=>[128,128, 0])
|
118
|
+
MAGENTA_STYLE = Style.new(:name=>:magenta, :builtin=>true, :code=>"\e[35m", :rgb=>[128, 0,128])
|
119
|
+
CYAN_STYLE = Style.new(:name=>:cyan, :builtin=>true, :code=>"\e[36m", :rgb=>[ 0,128,128])
|
120
|
+
# On Mac OSX Terminal, white is actually gray
|
121
|
+
WHITE_STYLE = Style.new(:name=>:white, :builtin=>true, :code=>"\e[37m", :rgb=>[192,192,192])
|
122
|
+
# Alias for WHITE, since WHITE is actually a light gray on Macs
|
123
|
+
GRAY_STYLE = Style.new(:name=>:gray, :builtin=>true, :code=>"\e[37m", :rgb=>[192,192,192])
|
124
|
+
# On Mac OSX Terminal, this is black foreground, or bright white background.
|
125
|
+
# Also used as base for RGB colors, if available
|
126
|
+
NONE_STYLE = Style.new(:name=>:none, :builtin=>true, :code=>"\e[38m", :rgb=>[ 0, 0, 0])
|
127
|
+
|
128
|
+
BASIC_COLORS = %w{BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE GRAY NONE}
|
129
|
+
|
130
|
+
colors = BASIC_COLORS.dup
|
131
|
+
BASIC_COLORS.each do |color|
|
132
|
+
bright_color = "BRIGHT_#{color}"
|
133
|
+
colors << bright_color
|
134
|
+
const_set bright_color+'_STYLE', const_get(color + '_STYLE').bright
|
135
|
+
end
|
136
|
+
COLORS = colors
|
137
|
+
|
138
|
+
colors.each do |color|
|
139
|
+
const_set color, const_get("#{color}_STYLE").code
|
140
|
+
const_set "ON_#{color}_STYLE", const_get("#{color}_STYLE").on
|
141
|
+
const_set "ON_#{color}", const_get("ON_#{color}_STYLE").code
|
142
|
+
end
|
143
|
+
ON_NONE_STYLE.rgb = [255,255,255] # Override; white background
|
144
|
+
|
145
|
+
STYLES.each do |style|
|
146
|
+
const_set style, const_get("#{style}_STYLE").code
|
147
|
+
end
|
148
|
+
|
149
|
+
# For RGB colors:
|
150
|
+
def self.const_missing(name)
|
151
|
+
if name.to_s =~ /^(ON_)?(RGB_)([A-F0-9]{6})(_STYLE)?$/ # RGB color
|
152
|
+
on = $1
|
153
|
+
suffix = $4
|
154
|
+
if suffix
|
155
|
+
code_name = $1.to_s + $2 + $3
|
156
|
+
else
|
157
|
+
code_name = name.to_s
|
158
|
+
end
|
159
|
+
style_name = code_name + '_STYLE'
|
160
|
+
style = Style.rgb($3)
|
161
|
+
style = style.on if on
|
162
|
+
const_set(style_name, style)
|
163
|
+
const_set(code_name, style.code)
|
164
|
+
if suffix
|
165
|
+
style
|
166
|
+
else
|
167
|
+
style.code
|
168
|
+
end
|
169
|
+
else
|
170
|
+
raise NameError, "Bad color or uninitialized constant #{name}"
|
171
|
+
end
|
172
|
+
end
|
142
173
|
|
143
174
|
#
|
144
175
|
# Create an instance of HighLine, connected to the streams _input_
|
@@ -328,19 +359,34 @@ class HighLine
|
|
328
359
|
# This method returns the original _string_ unchanged if HighLine::use_color?
|
329
360
|
# is +false+.
|
330
361
|
#
|
331
|
-
def color( string, *colors )
|
332
|
-
return string unless self.
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
362
|
+
def self.color( string, *colors )
|
363
|
+
return string unless self.use_color?
|
364
|
+
Style(*colors).color(string)
|
365
|
+
end
|
366
|
+
|
367
|
+
# In case you just want the color code, without the embedding and the CLEAR
|
368
|
+
def self.color_code(*colors)
|
369
|
+
Style(*colors).code
|
370
|
+
end
|
371
|
+
|
372
|
+
# Works as an instance method, same as the class method
|
373
|
+
def color_code(*colors)
|
374
|
+
self.class.color_code(*colors)
|
375
|
+
end
|
376
|
+
|
377
|
+
# Works as an instance method, same as the class method
|
378
|
+
def color(*args)
|
379
|
+
self.class.color(*args)
|
380
|
+
end
|
381
|
+
|
382
|
+
# Remove color codes from a string
|
383
|
+
def self.uncolor(string)
|
384
|
+
Style.uncolor(string)
|
385
|
+
end
|
386
|
+
|
387
|
+
# Works as an instance method, same as the class method
|
388
|
+
def uncolor(string)
|
389
|
+
self.class.uncolor(string)
|
344
390
|
end
|
345
391
|
|
346
392
|
#
|
@@ -352,20 +398,25 @@ class HighLine
|
|
352
398
|
# to list. A specified _mode_ controls how that list is formed and _option_
|
353
399
|
# has different effects, depending on the _mode_. Recognized modes are:
|
354
400
|
#
|
355
|
-
# <tt>:columns_across</tt>::
|
356
|
-
#
|
357
|
-
#
|
358
|
-
#
|
359
|
-
#
|
360
|
-
#
|
361
|
-
#
|
362
|
-
#
|
363
|
-
#
|
364
|
-
#
|
365
|
-
#
|
366
|
-
#
|
367
|
-
#
|
368
|
-
#
|
401
|
+
# <tt>:columns_across</tt>:: _items_ will be placed in columns,
|
402
|
+
# flowing from left to right. If given,
|
403
|
+
# _option_ is the number of columns to be
|
404
|
+
# used. When absent, columns will be
|
405
|
+
# determined based on _wrap_at_ or a
|
406
|
+
# default of 80 characters.
|
407
|
+
# <tt>:columns_down</tt>:: Identical to <tt>:columns_across</tt>,
|
408
|
+
# save flow goes down.
|
409
|
+
# <tt>:uneven_columns_across</tt>:: Like <tt>:columns_across</tt> but each
|
410
|
+
# column is sized independently.
|
411
|
+
# <tt>:uneven_columns_down</tt>:: Like <tt>:columns_down</tt> but each
|
412
|
+
# column is sized independently.
|
413
|
+
# <tt>:inline</tt>:: All _items_ are placed on a single line.
|
414
|
+
# The last two _items_ are separated by
|
415
|
+
# _option_ or a default of " or ". All
|
416
|
+
# other _items_ are separated by ", ".
|
417
|
+
# <tt>:rows</tt>:: The default mode. Each of the _items_ is
|
418
|
+
# placed on it's own line. The _option_
|
419
|
+
# parameter is ignored in this mode.
|
369
420
|
#
|
370
421
|
# Each member of the _items_ Array is passed through ERb and thus can contain
|
371
422
|
# their own expansions. Color escape expansions do not contribute to the
|
@@ -376,58 +427,157 @@ class HighLine
|
|
376
427
|
ERB.new(item, nil, "%").result(binding)
|
377
428
|
end
|
378
429
|
|
379
|
-
|
380
|
-
|
381
|
-
|
430
|
+
if items.empty?
|
431
|
+
""
|
432
|
+
else
|
433
|
+
case mode
|
434
|
+
when :inline
|
435
|
+
option = " or " if option.nil?
|
436
|
+
|
437
|
+
if items.size == 1
|
438
|
+
items.first
|
439
|
+
else
|
440
|
+
items[0..-2].join(", ") + "#{option}#{items.last}"
|
441
|
+
end
|
442
|
+
when :columns_across, :columns_down
|
443
|
+
max_length = actual_length(
|
444
|
+
items.max { |a, b| actual_length(a) <=> actual_length(b) }
|
445
|
+
)
|
446
|
+
|
447
|
+
if option.nil?
|
448
|
+
limit = @wrap_at || 80
|
449
|
+
option = (limit + 2) / (max_length + 2)
|
450
|
+
end
|
451
|
+
|
452
|
+
items = items.map do |item|
|
453
|
+
pad = max_length + (item.length - actual_length(item))
|
454
|
+
"%-#{pad}s" % item
|
455
|
+
end
|
456
|
+
row_count = (items.size / option.to_f).ceil
|
382
457
|
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
when 2
|
389
|
-
"#{items.first}#{option}#{items.last}"
|
390
|
-
else
|
391
|
-
items[0..-2].join(", ") + "#{option}#{items.last}"
|
392
|
-
end
|
393
|
-
when :columns_across, :columns_down
|
394
|
-
max_length = actual_length(
|
395
|
-
items.max { |a, b| actual_length(a) <=> actual_length(b) }
|
396
|
-
)
|
397
|
-
|
398
|
-
if option.nil?
|
399
|
-
limit = @wrap_at || 80
|
400
|
-
option = (limit + 2) / (max_length + 2)
|
401
|
-
end
|
458
|
+
if mode == :columns_across
|
459
|
+
rows = Array.new(row_count) { Array.new }
|
460
|
+
items.each_with_index do |item, index|
|
461
|
+
rows[index / option] << item
|
462
|
+
end
|
402
463
|
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
464
|
+
rows.map { |row| row.join(" ") + "\n" }.join
|
465
|
+
else
|
466
|
+
columns = Array.new(option) { Array.new }
|
467
|
+
items.each_with_index do |item, index|
|
468
|
+
columns[index / row_count] << item
|
469
|
+
end
|
408
470
|
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
471
|
+
list = ""
|
472
|
+
columns.first.size.times do |index|
|
473
|
+
list << columns.map { |column| column[index] }.
|
474
|
+
compact.join(" ") + "\n"
|
475
|
+
end
|
476
|
+
list
|
413
477
|
end
|
478
|
+
when :uneven_columns_across
|
479
|
+
if option.nil?
|
480
|
+
limit = @wrap_at || 80
|
481
|
+
items.size.downto(1) do |column_count|
|
482
|
+
row_count = (items.size / column_count.to_f).ceil
|
483
|
+
rows = Array.new(row_count) { Array.new }
|
484
|
+
items.each_with_index do |item, index|
|
485
|
+
rows[index / column_count] << item
|
486
|
+
end
|
414
487
|
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
488
|
+
widths = Array.new(column_count, 0)
|
489
|
+
rows.each do |row|
|
490
|
+
row.each_with_index do |field, column|
|
491
|
+
size = field.size
|
492
|
+
widths[column] = size if size > widths[column]
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
if column_count == 1 or
|
497
|
+
widths.inject(0) { |sum, n| sum + n + 2 } <= limit + 2
|
498
|
+
return rows.map { |row|
|
499
|
+
row.zip(widths).map { |field, i| "%-#{i}s" % field }.
|
500
|
+
join(" ") + "\n"
|
501
|
+
}.join
|
502
|
+
end
|
503
|
+
end
|
504
|
+
else
|
505
|
+
row_count = (items.size / option.to_f).ceil
|
506
|
+
rows = Array.new(row_count) { Array.new }
|
507
|
+
items.each_with_index do |item, index|
|
508
|
+
rows[index / option] << item
|
509
|
+
end
|
510
|
+
|
511
|
+
widths = Array.new(option, 0)
|
512
|
+
rows.each do |row|
|
513
|
+
row.each_with_index do |field, column|
|
514
|
+
size = field.size
|
515
|
+
widths[column] = size if size > widths[column]
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
return rows.map { |row|
|
520
|
+
row.zip(widths).map { |field, i| "%-#{i}s" % field }.join(" ") +
|
521
|
+
"\n"
|
522
|
+
}.join
|
420
523
|
end
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
524
|
+
when :uneven_columns_down
|
525
|
+
if option.nil?
|
526
|
+
limit = @wrap_at || 80
|
527
|
+
items.size.downto(1) do |column_count|
|
528
|
+
row_count = (items.size / column_count.to_f).ceil
|
529
|
+
columns = Array.new(column_count) { Array.new }
|
530
|
+
items.each_with_index do |item, index|
|
531
|
+
columns[index / row_count] << item
|
532
|
+
end
|
533
|
+
|
534
|
+
widths = Array.new(column_count, 0)
|
535
|
+
columns.each_with_index do |column, i|
|
536
|
+
column.each do |field|
|
537
|
+
size = field.size
|
538
|
+
widths[i] = size if size > widths[i]
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
542
|
+
if column_count == 1 or
|
543
|
+
widths.inject(0) { |sum, n| sum + n + 2 } <= limit + 2
|
544
|
+
list = ""
|
545
|
+
columns.first.size.times do |index|
|
546
|
+
list << columns.zip(widths).
|
547
|
+
map { |column, width| "%-#{width}s" %
|
548
|
+
column[index] }.
|
549
|
+
compact.join(" ").strip + "\n"
|
550
|
+
end
|
551
|
+
return list
|
552
|
+
end
|
553
|
+
end
|
554
|
+
else
|
555
|
+
row_count = (items.size / option.to_f).ceil
|
556
|
+
columns = Array.new(option) { Array.new }
|
557
|
+
items.each_with_index do |item, index|
|
558
|
+
columns[index / row_count] << item
|
559
|
+
end
|
560
|
+
|
561
|
+
widths = Array.new(option, 0)
|
562
|
+
columns.each_with_index do |column, i|
|
563
|
+
column.each do |field|
|
564
|
+
size = field.size
|
565
|
+
widths[i] = size if size > widths[i]
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
list = ""
|
570
|
+
columns.first.size.times do |index|
|
571
|
+
list << columns.zip(widths).
|
572
|
+
map { |column, width| "%-#{width}s" %
|
573
|
+
column[index] }.
|
574
|
+
compact.join(" ").strip + "\n"
|
575
|
+
end
|
576
|
+
return list
|
426
577
|
end
|
427
|
-
|
578
|
+
else
|
579
|
+
items.map { |i| "#{i}\n" }.join
|
428
580
|
end
|
429
|
-
else
|
430
|
-
items.map { |i| "#{i}\n" }.join
|
431
581
|
end
|
432
582
|
end
|
433
583
|
|
@@ -540,11 +690,11 @@ class HighLine
|
|
540
690
|
@answers << ask(@question)
|
541
691
|
@gather -= 1
|
542
692
|
end
|
543
|
-
when String, Regexp
|
693
|
+
when ::String, Regexp
|
544
694
|
@answers << ask(@question)
|
545
695
|
|
546
696
|
original_question.question = ""
|
547
|
-
until (@gather.is_a?(String) and @answers.last.to_s == @gather) or
|
697
|
+
until (@gather.is_a?(::String) and @answers.last.to_s == @gather) or
|
548
698
|
(@gather.is_a?(Regexp) and @answers.last.to_s =~ @gather)
|
549
699
|
@question = original_question
|
550
700
|
@answers << ask(@question)
|
@@ -761,3 +911,6 @@ class HighLine
|
|
761
911
|
string_with_escapes.gsub(/\e\[\d{1,2}m/, "").length
|
762
912
|
end
|
763
913
|
end
|
914
|
+
|
915
|
+
require "highline/string_extensions"
|
916
|
+
|