highline 2.0.0.pre.develop.9 → 2.0.0.pre.develop.11
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/.rubocop.yml +59 -5
- data/.travis.yml +9 -4
- data/Changelog.md +11 -0
- data/Gemfile +12 -19
- data/Rakefile +5 -11
- data/examples/ansi_colors.rb +6 -11
- data/examples/asking_for_arrays.rb +4 -3
- data/examples/basic_usage.rb +29 -22
- data/examples/color_scheme.rb +11 -10
- data/examples/get_character.rb +6 -5
- data/examples/limit.rb +2 -1
- data/examples/menus.rb +11 -11
- data/examples/overwrite.rb +7 -6
- data/examples/page_and_wrap.rb +5 -4
- data/examples/password.rb +2 -1
- data/examples/repeat_entry.rb +7 -5
- data/examples/trapping_eof.rb +2 -1
- data/examples/using_readline.rb +2 -1
- data/highline.gemspec +25 -25
- data/lib/highline.rb +103 -111
- data/lib/highline/builtin_styles.rb +45 -41
- data/lib/highline/color_scheme.rb +32 -28
- data/lib/highline/compatibility.rb +3 -3
- data/lib/highline/custom_errors.rb +2 -1
- data/lib/highline/import.rb +8 -11
- data/lib/highline/list.rb +4 -8
- data/lib/highline/list_renderer.rb +207 -201
- data/lib/highline/menu.rb +75 -63
- data/lib/highline/menu/item.rb +2 -0
- data/lib/highline/paginator.rb +5 -6
- data/lib/highline/question.rb +38 -36
- data/lib/highline/question/answer_converter.rb +2 -2
- data/lib/highline/question_asker.rb +15 -17
- data/lib/highline/simulate.rb +11 -13
- data/lib/highline/statement.rb +12 -10
- data/lib/highline/string.rb +9 -8
- data/lib/highline/string_extensions.rb +30 -14
- data/lib/highline/style.rb +68 -45
- data/lib/highline/template_renderer.rb +5 -5
- data/lib/highline/terminal.rb +24 -31
- data/lib/highline/terminal/io_console.rb +2 -2
- data/lib/highline/terminal/ncurses.rb +4 -3
- data/lib/highline/terminal/unix_stty.rb +12 -9
- data/lib/highline/version.rb +1 -1
- data/lib/highline/wrapper.rb +12 -11
- metadata +34 -43
- data/test/acceptance/acceptance.rb +0 -62
- data/test/acceptance/acceptance_test.rb +0 -69
- data/test/acceptance/at_color_output_using_erb_templates.rb +0 -17
- data/test/acceptance/at_echo_false.rb +0 -23
- data/test/acceptance/at_readline.rb +0 -37
- data/test/io_console_compatible.rb +0 -37
- data/test/string_methods.rb +0 -35
- data/test/test_answer_converter.rb +0 -26
- data/test/test_color_scheme.rb +0 -94
- data/test/test_helper.rb +0 -22
- data/test/test_highline.rb +0 -1627
- data/test/test_import.rb +0 -55
- data/test/test_list.rb +0 -60
- data/test/test_menu.rb +0 -749
- data/test/test_paginator.rb +0 -73
- data/test/test_question_asker.rb +0 -20
- data/test/test_simulator.rb +0 -24
- data/test/test_string_extension.rb +0 -72
- data/test/test_string_highline.rb +0 -42
- data/test/test_style.rb +0 -613
- data/test/test_wrapper.rb +0 -188
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
class HighLine
|
2
4
|
# Deals with the task of "asking" a question
|
3
5
|
class QuestionAsker
|
@@ -31,13 +33,12 @@ class HighLine
|
|
31
33
|
question.convert
|
32
34
|
|
33
35
|
if question.confirm
|
34
|
-
|
36
|
+
confirmation = @highline.send(:confirm, question)
|
37
|
+
raise NoConfirmationQuestionError unless confirmation
|
35
38
|
end
|
36
|
-
|
37
39
|
rescue ExplainableError => e
|
38
40
|
explain_error(e.explanation_key)
|
39
41
|
retry
|
40
|
-
|
41
42
|
rescue ArgumentError => error
|
42
43
|
case error.message
|
43
44
|
when /ambiguous/
|
@@ -65,29 +66,27 @@ class HighLine
|
|
65
66
|
#
|
66
67
|
# @return [Array, Hash] answers
|
67
68
|
def gather_answers
|
68
|
-
original_question_template = question.template
|
69
69
|
verify_match = question.verify_match
|
70
|
+
answers = []
|
70
71
|
|
71
|
-
|
72
|
-
|
73
|
-
|
72
|
+
# when verify_match is set this loop will repeat until unique_answers == 1
|
73
|
+
loop do
|
74
74
|
answers = gather_answers_based_on_type
|
75
75
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end while verify_match
|
76
|
+
break unless verify_match &&
|
77
|
+
(@highline.send(:unique_answers, answers).size > 1)
|
78
|
+
|
79
|
+
explain_error(:mismatch)
|
80
|
+
end
|
82
81
|
|
83
|
-
|
82
|
+
verify_match ? @highline.send(:last_answer, answers) : answers
|
84
83
|
end
|
85
84
|
|
86
85
|
# Gather multiple integer values based on {Question#gather} count
|
87
86
|
# @return [Array] answers
|
88
87
|
def gather_integer
|
89
88
|
gather_with_array do |answers|
|
90
|
-
(question.gather-1).times { answers << ask_once }
|
89
|
+
(question.gather - 1).times { answers << ask_once }
|
91
90
|
end
|
92
91
|
end
|
93
92
|
|
@@ -112,7 +111,6 @@ class HighLine
|
|
112
111
|
end
|
113
112
|
end
|
114
113
|
|
115
|
-
|
116
114
|
private
|
117
115
|
|
118
116
|
## Delegate to Highline
|
@@ -133,7 +131,7 @@ class HighLine
|
|
133
131
|
def answer_matches_regex(answer)
|
134
132
|
if question.gather.is_a?(::String) || question.gather.is_a?(Symbol)
|
135
133
|
answer.to_s == question.gather.to_s
|
136
|
-
|
134
|
+
elsif question.gather.is_a?(Regexp)
|
137
135
|
answer.to_s =~ question.gather
|
138
136
|
end
|
139
137
|
end
|
data/lib/highline/simulate.rb
CHANGED
@@ -10,12 +10,9 @@
|
|
10
10
|
#
|
11
11
|
# adapted from https://gist.github.com/194554
|
12
12
|
|
13
|
-
|
14
13
|
class HighLine
|
15
|
-
|
16
14
|
# Simulates Highline input for use in tests.
|
17
15
|
class Simulate
|
18
|
-
|
19
16
|
# Creates a simulator with an array of Strings as a script
|
20
17
|
# @param strings [Array<String>] preloaded string to be used
|
21
18
|
# as input buffer when simulating.
|
@@ -28,14 +25,15 @@ class HighLine
|
|
28
25
|
@strings.shift
|
29
26
|
end
|
30
27
|
|
31
|
-
# Simulate StringIO#getbyte by shifting a single character off of
|
28
|
+
# Simulate StringIO#getbyte by shifting a single character off of
|
29
|
+
# the next line of the script
|
32
30
|
def getbyte
|
33
31
|
line = gets
|
34
|
-
if line.
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
32
|
+
return if line.empty?
|
33
|
+
|
34
|
+
char = line.slice! 0
|
35
|
+
@strings.unshift line
|
36
|
+
char
|
39
37
|
end
|
40
38
|
|
41
39
|
# The simulator handles its own EOF
|
@@ -44,18 +42,18 @@ class HighLine
|
|
44
42
|
end
|
45
43
|
|
46
44
|
# A wrapper method that temporarily replaces the Highline
|
47
|
-
# instance in
|
45
|
+
# instance in HighLine.default_instance with an instance of this object
|
48
46
|
# for the duration of the block
|
49
47
|
#
|
50
48
|
# @param strings [String] preloaded string buffer that
|
51
49
|
# will feed the input operations when simulating.
|
52
50
|
|
53
51
|
def self.with(*strings)
|
54
|
-
@input =
|
55
|
-
|
52
|
+
@input = HighLine.default_instance.instance_variable_get :@input
|
53
|
+
HighLine.default_instance.instance_variable_set :@input, new(strings)
|
56
54
|
yield
|
57
55
|
ensure
|
58
|
-
|
56
|
+
HighLine.default_instance.instance_variable_set :@input, @input
|
59
57
|
end
|
60
58
|
end
|
61
59
|
end
|
data/lib/highline/statement.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "highline/wrapper"
|
4
|
+
require "highline/paginator"
|
5
|
+
require "highline/template_renderer"
|
6
6
|
|
7
7
|
class HighLine
|
8
8
|
# This class handles proper formatting based
|
@@ -45,6 +45,10 @@ class HighLine
|
|
45
45
|
statement
|
46
46
|
end
|
47
47
|
|
48
|
+
def self.const_missing(constant)
|
49
|
+
HighLine.const_get(constant)
|
50
|
+
end
|
51
|
+
|
48
52
|
private
|
49
53
|
|
50
54
|
def stringfy(template_string)
|
@@ -52,14 +56,16 @@ class HighLine
|
|
52
56
|
end
|
53
57
|
|
54
58
|
def format_statement
|
55
|
-
return template_string
|
59
|
+
return template_string if template_string.empty?
|
56
60
|
|
57
61
|
statement = render_template
|
58
62
|
|
59
63
|
statement = HighLine::Wrapper.wrap(statement, highline.wrap_at)
|
60
64
|
statement = HighLine::Paginator.new(highline).page_print(statement)
|
61
65
|
|
62
|
-
statement = statement.gsub(/\n(?!$)/,"\n#{highline.indentation}") if
|
66
|
+
statement = statement.gsub(/\n(?!$)/, "\n#{highline.indentation}") if
|
67
|
+
highline.multi_indent
|
68
|
+
|
63
69
|
statement
|
64
70
|
end
|
65
71
|
|
@@ -74,9 +80,5 @@ class HighLine
|
|
74
80
|
def template
|
75
81
|
@template ||= ERB.new(template_string, nil, "%")
|
76
82
|
end
|
77
|
-
|
78
|
-
def self.const_missing(constant)
|
79
|
-
HighLine.const_get(constant)
|
80
|
-
end
|
81
83
|
end
|
82
|
-
end
|
84
|
+
end
|
data/lib/highline/string.rb
CHANGED
@@ -3,12 +3,13 @@
|
|
3
3
|
require "highline/string_extensions"
|
4
4
|
|
5
5
|
class HighLine
|
6
|
-
|
7
6
|
#
|
8
|
-
# HighLine::String is a subclass of String with convenience methods added
|
7
|
+
# HighLine::String is a subclass of String with convenience methods added
|
8
|
+
# for colorization.
|
9
9
|
#
|
10
10
|
# Available convenience methods include:
|
11
|
-
# * 'color' method e.g. highline_string.color(:bright_blue,
|
11
|
+
# * 'color' method e.g. highline_string.color(:bright_blue,
|
12
|
+
# :underline)
|
12
13
|
# * colors e.g. highline_string.magenta
|
13
14
|
# * RGB colors e.g. highline_string.rgb_ff6000
|
14
15
|
# or highline_string.rgb(255,96,0)
|
@@ -17,19 +18,19 @@ class HighLine
|
|
17
18
|
# or highline_string.on_rgb(255,96,0)
|
18
19
|
# * styles e.g. highline_string.underline
|
19
20
|
#
|
20
|
-
# Additionally, convenience methods can be chained, for instance the
|
21
|
+
# Additionally, convenience methods can be chained, for instance the
|
22
|
+
# following are equivalent:
|
21
23
|
# highline_string.bright_blue.blink.underline
|
22
24
|
# highline_string.color(:bright_blue, :blink, :underline)
|
23
25
|
# HighLine.color(highline_string, :bright_blue, :blink, :underline)
|
24
26
|
#
|
25
|
-
# For those less squeamish about possible conflicts, the same convenience
|
26
|
-
# added to the built-in String class, as follows:
|
27
|
+
# For those less squeamish about possible conflicts, the same convenience
|
28
|
+
# methods can be added to the built-in String class, as follows:
|
27
29
|
#
|
28
30
|
# require 'highline'
|
29
31
|
# Highline.colorize_strings
|
30
32
|
#
|
31
|
-
|
32
33
|
class String < ::String
|
33
34
|
include StringExtensions
|
34
35
|
end
|
35
|
-
end
|
36
|
+
end
|
@@ -1,16 +1,18 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
class HighLine
|
3
|
+
class HighLine #:nodoc:
|
4
4
|
# Returns a HighLine::String from any given String.
|
5
5
|
# @param s [String]
|
6
6
|
# @return [HighLine::String] from the given string.
|
7
|
-
def self.String(s)
|
7
|
+
def self.String(s) # rubocop:disable Naming/MethodName
|
8
8
|
HighLine::String.new(s)
|
9
9
|
end
|
10
10
|
|
11
11
|
# HighLine extensions for String class.
|
12
12
|
# Included by HighLine::String.
|
13
13
|
module StringExtensions
|
14
|
+
STYLE_METHOD_NAME_PATTERN = /^(on_)?rgb_([0-9a-fA-F]{6})$/
|
15
|
+
|
14
16
|
# Included hook. Actions to take when being included.
|
15
17
|
# @param base [Class, Module] base class
|
16
18
|
def self.included(base)
|
@@ -35,7 +37,7 @@ class HighLine
|
|
35
37
|
|
36
38
|
undef :on if method_defined? :on
|
37
39
|
def on(arg)
|
38
|
-
color((
|
40
|
+
color(("on_" + arg.to_s).to_sym)
|
39
41
|
end
|
40
42
|
|
41
43
|
undef :uncolor if method_defined? :uncolor
|
@@ -57,19 +59,33 @@ class HighLine
|
|
57
59
|
|
58
60
|
# @todo Chain existing method_missing?
|
59
61
|
undef :method_missing if method_defined? :method_missing
|
60
|
-
def method_missing(method, *
|
61
|
-
if method.to_s =~
|
62
|
+
def method_missing(method, *_args)
|
63
|
+
if method.to_s =~ STYLE_METHOD_NAME_PATTERN
|
62
64
|
color(method)
|
63
65
|
else
|
64
|
-
|
66
|
+
super
|
65
67
|
end
|
66
68
|
end
|
67
69
|
|
70
|
+
undef :respond_to_missing if method_defined? :respond_to_missing
|
71
|
+
def respond_to_missing?(method_name, include_private = false)
|
72
|
+
method_name.to_s =~ STYLE_METHOD_NAME_PATTERN || super
|
73
|
+
end
|
74
|
+
|
68
75
|
private
|
69
76
|
|
70
77
|
def setup_color_code(*colors)
|
71
|
-
color_code = colors.map
|
72
|
-
|
78
|
+
color_code = colors.map do |color|
|
79
|
+
if color.is_a?(Numeric)
|
80
|
+
format("%02x", color)
|
81
|
+
else
|
82
|
+
color.to_s
|
83
|
+
end
|
84
|
+
end.join
|
85
|
+
|
86
|
+
raise "Bad RGB color #{colors.inspect}" unless
|
87
|
+
color_code =~ /^[a-fA-F0-9]{6}/
|
88
|
+
|
73
89
|
color_code
|
74
90
|
end
|
75
91
|
end
|
@@ -80,28 +96,28 @@ class HighLine
|
|
80
96
|
def self.define_builtin_style_methods(base)
|
81
97
|
HighLine::COLORS.each do |color|
|
82
98
|
color = color.downcase
|
83
|
-
base.class_eval <<-
|
99
|
+
base.class_eval <<-METHOD_DEFINITION
|
84
100
|
undef :#{color} if method_defined? :#{color}
|
85
101
|
def #{color}
|
86
102
|
color(:#{color})
|
87
103
|
end
|
88
|
-
|
104
|
+
METHOD_DEFINITION
|
89
105
|
|
90
|
-
base.class_eval <<-
|
106
|
+
base.class_eval <<-METHOD_DEFINITION
|
91
107
|
undef :on_#{color} if method_defined? :on_#{color}
|
92
108
|
def on_#{color}
|
93
109
|
on(:#{color})
|
94
110
|
end
|
95
|
-
|
111
|
+
METHOD_DEFINITION
|
96
112
|
|
97
113
|
HighLine::STYLES.each do |style|
|
98
114
|
style = style.downcase
|
99
|
-
base.class_eval <<-
|
115
|
+
base.class_eval <<-METHOD_DEFINITION
|
100
116
|
undef :#{style} if method_defined? :#{style}
|
101
117
|
def #{style}
|
102
118
|
color(:#{style})
|
103
119
|
end
|
104
|
-
|
120
|
+
METHOD_DEFINITION
|
105
121
|
end
|
106
122
|
end
|
107
123
|
end
|
data/lib/highline/style.rb
CHANGED
@@ -8,16 +8,14 @@
|
|
8
8
|
#
|
9
9
|
# This is Free Software. See LICENSE and COPYING for details
|
10
10
|
|
11
|
-
|
12
|
-
class HighLine
|
13
|
-
|
11
|
+
class HighLine #:nodoc:
|
14
12
|
# Creates a style using {.find_or_create_style} or
|
15
13
|
# {.find_or_create_style_list}
|
16
14
|
# @param args [Array<Style, Hash, String>] style properties
|
17
15
|
# @return [Style]
|
18
16
|
def self.Style(*args)
|
19
17
|
args = args.compact.flatten
|
20
|
-
if args.size==1
|
18
|
+
if args.size == 1
|
21
19
|
find_or_create_style(args.first)
|
22
20
|
else
|
23
21
|
find_or_create_style_list(*args)
|
@@ -33,21 +31,22 @@ class HighLine
|
|
33
31
|
if arg.is_a?(Style)
|
34
32
|
Style.list[arg.name] || Style.index(arg)
|
35
33
|
elsif arg.is_a?(::String) && arg =~ /^\e\[/ # arg is a code
|
36
|
-
|
34
|
+
styles = Style.code_index[arg]
|
35
|
+
if styles
|
37
36
|
styles.first
|
38
37
|
else
|
39
|
-
Style.new(:
|
38
|
+
Style.new(code: arg)
|
40
39
|
end
|
41
|
-
elsif
|
42
|
-
|
40
|
+
elsif Style.list[arg]
|
41
|
+
Style.list[arg]
|
43
42
|
elsif HighLine.color_scheme && HighLine.color_scheme[arg]
|
44
43
|
HighLine.color_scheme[arg]
|
45
44
|
elsif arg.is_a?(Hash)
|
46
45
|
Style.new(arg)
|
47
46
|
elsif arg.to_s.downcase =~ /^rgb_([a-f0-9]{6})$/
|
48
|
-
Style.rgb(
|
47
|
+
Style.rgb(Regexp.last_match(1))
|
49
48
|
elsif arg.to_s.downcase =~ /^on_rgb_([a-f0-9]{6})$/
|
50
|
-
Style.rgb(
|
49
|
+
Style.rgb(Regexp.last_match(1)).on
|
51
50
|
else
|
52
51
|
raise NameError, "#{arg.inspect} is not a defined Style"
|
53
52
|
end
|
@@ -62,12 +61,11 @@ class HighLine
|
|
62
61
|
|
63
62
|
def self.find_or_create_style_list(*args)
|
64
63
|
name = args
|
65
|
-
Style.list[name] || Style.new(:
|
64
|
+
Style.list[name] || Style.new(list: args)
|
66
65
|
end
|
67
66
|
|
68
67
|
# ANSI styles to be used by HighLine.
|
69
68
|
class Style
|
70
|
-
|
71
69
|
# Index the given style.
|
72
70
|
# Uses @code_index (Hash) as repository.
|
73
71
|
# @param style [Style]
|
@@ -77,10 +75,12 @@ class HighLine
|
|
77
75
|
@styles ||= {}
|
78
76
|
@styles[style.name] = style
|
79
77
|
end
|
80
|
-
|
78
|
+
unless style.list
|
81
79
|
@code_index ||= {}
|
82
80
|
@code_index[style.code] ||= []
|
83
|
-
@code_index[style.code].reject!
|
81
|
+
@code_index[style.code].reject! do |indexed_style|
|
82
|
+
indexed_style.name == style.name
|
83
|
+
end
|
84
84
|
@code_index[style.code] << style
|
85
85
|
end
|
86
86
|
style
|
@@ -91,9 +91,9 @@ class HighLine
|
|
91
91
|
# @return [void]
|
92
92
|
def self.clear_index
|
93
93
|
# reset to builtin only styles
|
94
|
-
@styles = list.select { |
|
94
|
+
@styles = list.select { |_name, style| style.builtin }
|
95
95
|
@code_index = {}
|
96
|
-
@styles.
|
96
|
+
@styles.each_value { |style| index(style) }
|
97
97
|
end
|
98
98
|
|
99
99
|
# Converts all given color codes to hexadecimal and
|
@@ -106,7 +106,7 @@ class HighLine
|
|
106
106
|
# HighLine::Style.rgb_hex(9, 10, "11") # => "090a11"
|
107
107
|
def self.rgb_hex(*colors)
|
108
108
|
colors.map do |color|
|
109
|
-
color.is_a?(Numeric) ?
|
109
|
+
color.is_a?(Numeric) ? format("%02x", color) : color.to_s
|
110
110
|
end.join
|
111
111
|
end
|
112
112
|
|
@@ -117,7 +117,7 @@ class HighLine
|
|
117
117
|
# HighLine::Style.rgb_parts("090A0B") # => [9, 10, 11]
|
118
118
|
|
119
119
|
def self.rgb_parts(hex)
|
120
|
-
hex.scan(/../).map{|part| part.to_i(16)}
|
120
|
+
hex.scan(/../).map { |part| part.to_i(16) }
|
121
121
|
end
|
122
122
|
|
123
123
|
# Search for or create a new Style from the colors provided.
|
@@ -132,29 +132,37 @@ class HighLine
|
|
132
132
|
#
|
133
133
|
def self.rgb(*colors)
|
134
134
|
hex = rgb_hex(*colors)
|
135
|
-
name = (
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
end
|
135
|
+
name = ("rgb_" + hex).to_sym
|
136
|
+
style = list[name]
|
137
|
+
return style if style
|
138
|
+
|
139
|
+
parts = rgb_parts(hex)
|
140
|
+
new(name: name, code: "\e[38;5;#{rgb_number(parts)}m", rgb: parts)
|
142
141
|
end
|
143
142
|
|
144
143
|
# Returns the rgb number to be used as escape code on ANSI terminals.
|
145
|
-
# @param parts [Array<Numeric>] three numerical codes for red, green
|
144
|
+
# @param parts [Array<Numeric>] three numerical codes for red, green
|
145
|
+
# and blue
|
146
146
|
# @return [Numeric] to be used as escape code on ANSI terminals
|
147
147
|
def self.rgb_number(*parts)
|
148
148
|
parts = parts.flatten
|
149
|
-
16 + parts.
|
149
|
+
16 + parts.reduce(0) do |kode, part|
|
150
|
+
kode * 6 + (part / 256.0 * 6.0).floor
|
151
|
+
end
|
150
152
|
end
|
151
153
|
|
152
154
|
# From an ANSI number (color escape code), craft an 'rgb_hex' code of it
|
153
155
|
# @param ansi_number [Integer] ANSI escape code
|
154
156
|
# @return [String] all color codes joined as {.rgb_hex}
|
155
157
|
def self.ansi_rgb_to_hex(ansi_number)
|
156
|
-
raise "Invalid ANSI rgb code #{ansi_number}" unless
|
157
|
-
|
158
|
+
raise "Invalid ANSI rgb code #{ansi_number}" unless
|
159
|
+
(16..231).cover?(ansi_number)
|
160
|
+
parts = (ansi_number - 16).
|
161
|
+
to_s(6).
|
162
|
+
rjust(3, "0").
|
163
|
+
scan(/./).
|
164
|
+
map { |d| (d.to_i * 255.0 / 6.0).ceil }
|
165
|
+
|
158
166
|
rgb_hex(*parts)
|
159
167
|
end
|
160
168
|
|
@@ -170,9 +178,9 @@ class HighLine
|
|
170
178
|
|
171
179
|
# Remove any ANSI color escape sequence of the given String.
|
172
180
|
# @param string [String]
|
173
|
-
# @return [String]
|
181
|
+
# @return [String]
|
174
182
|
def self.uncolor(string)
|
175
|
-
string.gsub(/\e\[\d+(;\d+)*m/,
|
183
|
+
string.gsub(/\e\[\d+(;\d+)*m/, "")
|
176
184
|
end
|
177
185
|
|
178
186
|
# Style name
|
@@ -202,7 +210,7 @@ class HighLine
|
|
202
210
|
@builtin = defn[:builtin]
|
203
211
|
if @rgb
|
204
212
|
hex = self.class.rgb_hex(@rgb)
|
205
|
-
@name ||=
|
213
|
+
@name ||= "rgb_" + hex
|
206
214
|
elsif @list
|
207
215
|
@name ||= @list
|
208
216
|
end
|
@@ -228,11 +236,12 @@ class HighLine
|
|
228
236
|
code + string + HighLine::CLEAR
|
229
237
|
end
|
230
238
|
|
231
|
-
# @return [String] all codes of the Style list joined together
|
239
|
+
# @return [String] all codes of the Style list joined together
|
240
|
+
# (if a Style list)
|
232
241
|
# @return [String] the Style code
|
233
242
|
def code
|
234
243
|
if @list
|
235
|
-
@list.map{|element| HighLine.Style(element).code}.join
|
244
|
+
@list.map { |element| HighLine.Style(element).code }.join
|
236
245
|
else
|
237
246
|
@code
|
238
247
|
end
|
@@ -257,22 +266,30 @@ class HighLine
|
|
257
266
|
# @param new_name [Symbol]
|
258
267
|
# @param options [Hash] Style attributes to be changed
|
259
268
|
# @return [Style] new Style with changed attributes
|
260
|
-
def variant(new_name, options={})
|
269
|
+
def variant(new_name, options = {})
|
261
270
|
raise "Cannot create a variant of a style list (#{inspect})" if @list
|
262
271
|
new_code = options[:code] || code
|
263
272
|
if options[:increment]
|
264
|
-
raise "Unexpected code in #{inspect}" unless
|
265
|
-
|
273
|
+
raise "Unexpected code in #{inspect}" unless
|
274
|
+
new_code =~ /^(.*?)(\d+)(.*)/
|
275
|
+
|
276
|
+
new_code =
|
277
|
+
Regexp.last_match(1) +
|
278
|
+
(Regexp.last_match(2).to_i +
|
279
|
+
options[:increment]).to_s +
|
280
|
+
Regexp.last_match(3)
|
266
281
|
end
|
267
282
|
new_rgb = options[:rgb] || @rgb
|
268
|
-
self.class.new(
|
283
|
+
self.class.new(to_hash.merge(name: new_name,
|
284
|
+
code: new_code,
|
285
|
+
rgb: new_rgb))
|
269
286
|
end
|
270
287
|
|
271
288
|
# Uses the color as background and return a new style.
|
272
289
|
# @return [Style]
|
273
290
|
def on
|
274
|
-
new_name = (
|
275
|
-
self.class.list[new_name] ||= variant(new_name, :
|
291
|
+
new_name = ("on_" + @name.to_s).to_sym
|
292
|
+
self.class.list[new_name] ||= variant(new_name, increment: 10)
|
276
293
|
end
|
277
294
|
|
278
295
|
# @return [Style] a brighter version of this Style
|
@@ -288,11 +305,17 @@ class HighLine
|
|
288
305
|
private
|
289
306
|
|
290
307
|
def create_bright_variant(variant_name)
|
291
|
-
raise "Cannot create a #{name} variant of a style list (#{inspect})" if
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
308
|
+
raise "Cannot create a #{name} variant of a style list (#{inspect})" if
|
309
|
+
@list
|
310
|
+
new_name = ("#{variant_name}_" + @name.to_s).to_sym
|
311
|
+
new_rgb =
|
312
|
+
if @rgb == [0, 0, 0]
|
313
|
+
[128, 128, 128]
|
314
|
+
else
|
315
|
+
@rgb.map { |color| color.zero? ? 0 : [color + 128, 255].min }
|
316
|
+
end
|
317
|
+
|
318
|
+
find_style(new_name) || variant(new_name, increment: 60, rgb: new_rgb)
|
296
319
|
end
|
297
320
|
|
298
321
|
def find_style(name)
|