highline 2.0.0.pre.develop.9 → 2.0.0.pre.develop.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +59 -5
  3. data/.travis.yml +9 -4
  4. data/Changelog.md +11 -0
  5. data/Gemfile +12 -19
  6. data/Rakefile +5 -11
  7. data/examples/ansi_colors.rb +6 -11
  8. data/examples/asking_for_arrays.rb +4 -3
  9. data/examples/basic_usage.rb +29 -22
  10. data/examples/color_scheme.rb +11 -10
  11. data/examples/get_character.rb +6 -5
  12. data/examples/limit.rb +2 -1
  13. data/examples/menus.rb +11 -11
  14. data/examples/overwrite.rb +7 -6
  15. data/examples/page_and_wrap.rb +5 -4
  16. data/examples/password.rb +2 -1
  17. data/examples/repeat_entry.rb +7 -5
  18. data/examples/trapping_eof.rb +2 -1
  19. data/examples/using_readline.rb +2 -1
  20. data/highline.gemspec +25 -25
  21. data/lib/highline.rb +103 -111
  22. data/lib/highline/builtin_styles.rb +45 -41
  23. data/lib/highline/color_scheme.rb +32 -28
  24. data/lib/highline/compatibility.rb +3 -3
  25. data/lib/highline/custom_errors.rb +2 -1
  26. data/lib/highline/import.rb +8 -11
  27. data/lib/highline/list.rb +4 -8
  28. data/lib/highline/list_renderer.rb +207 -201
  29. data/lib/highline/menu.rb +75 -63
  30. data/lib/highline/menu/item.rb +2 -0
  31. data/lib/highline/paginator.rb +5 -6
  32. data/lib/highline/question.rb +38 -36
  33. data/lib/highline/question/answer_converter.rb +2 -2
  34. data/lib/highline/question_asker.rb +15 -17
  35. data/lib/highline/simulate.rb +11 -13
  36. data/lib/highline/statement.rb +12 -10
  37. data/lib/highline/string.rb +9 -8
  38. data/lib/highline/string_extensions.rb +30 -14
  39. data/lib/highline/style.rb +68 -45
  40. data/lib/highline/template_renderer.rb +5 -5
  41. data/lib/highline/terminal.rb +24 -31
  42. data/lib/highline/terminal/io_console.rb +2 -2
  43. data/lib/highline/terminal/ncurses.rb +4 -3
  44. data/lib/highline/terminal/unix_stty.rb +12 -9
  45. data/lib/highline/version.rb +1 -1
  46. data/lib/highline/wrapper.rb +12 -11
  47. metadata +34 -43
  48. data/test/acceptance/acceptance.rb +0 -62
  49. data/test/acceptance/acceptance_test.rb +0 -69
  50. data/test/acceptance/at_color_output_using_erb_templates.rb +0 -17
  51. data/test/acceptance/at_echo_false.rb +0 -23
  52. data/test/acceptance/at_readline.rb +0 -37
  53. data/test/io_console_compatible.rb +0 -37
  54. data/test/string_methods.rb +0 -35
  55. data/test/test_answer_converter.rb +0 -26
  56. data/test/test_color_scheme.rb +0 -94
  57. data/test/test_helper.rb +0 -22
  58. data/test/test_highline.rb +0 -1627
  59. data/test/test_import.rb +0 -55
  60. data/test/test_list.rb +0 -60
  61. data/test/test_menu.rb +0 -749
  62. data/test/test_paginator.rb +0 -73
  63. data/test/test_question_asker.rb +0 -20
  64. data/test/test_simulator.rb +0 -24
  65. data/test/test_string_extension.rb +0 -72
  66. data/test/test_string_highline.rb +0 -42
  67. data/test/test_style.rb +0 -613
  68. data/test/test_wrapper.rb +0 -188
@@ -1,4 +1,4 @@
1
- #coding: utf-8
1
+ # coding: utf-8
2
2
 
3
3
  class HighLine
4
4
  # Builtin Styles that are included at HighLine initialization.
@@ -23,17 +23,19 @@ class HighLine
23
23
  blink: "\e[5m",
24
24
  reverse: "\e[7m",
25
25
  concealed: "\e[8m"
26
- }
26
+ }.freeze
27
27
 
28
28
  STYLE_LIST.each do |style_name, code|
29
- style = String(style_name).upcase
29
+ style = String(style_name).upcase
30
30
 
31
- const_set style, code
32
- const_set style + "_STYLE", Style.new(name: style_name, code: code, builtin: true)
31
+ const_set style, code
32
+ const_set style + "_STYLE",
33
+ Style.new(name: style_name, code: code, builtin: true)
33
34
  end
34
35
 
35
36
  # Basic Style names like CLEAR, BOLD, UNDERLINE
36
- STYLES = %w{CLEAR RESET BOLD DARK UNDERLINE UNDERSCORE BLINK REVERSE CONCEALED}
37
+ STYLES = %w[CLEAR RESET BOLD DARK UNDERLINE
38
+ UNDERSCORE BLINK REVERSE CONCEALED].freeze
37
39
 
38
40
  # A Hash with the basic colors an their ANSI escape codes.
39
41
  COLOR_LIST = {
@@ -48,33 +50,35 @@ class HighLine
48
50
  gray: { code: "\e[37m", rgb: [192, 192, 192] },
49
51
  grey: { code: "\e[37m", rgb: [192, 192, 192] },
50
52
  none: { code: "\e[38m", rgb: [0, 0, 0] }
51
- }
53
+ }.freeze
52
54
 
53
55
  COLOR_LIST.each do |color_name, attributes|
54
- color = String(color_name).upcase
56
+ color = String(color_name).upcase
55
57
 
56
- style = Style.new(
57
- name: color_name,
58
- code: attributes[:code],
59
- rgb: attributes[:rgb],
60
- builtin: true
61
- )
58
+ style = Style.new(
59
+ name: color_name,
60
+ code: attributes[:code],
61
+ rgb: attributes[:rgb],
62
+ builtin: true
63
+ )
62
64
 
63
- const_set color + "_STYLE", style
65
+ const_set color + "_STYLE", style
64
66
  end
65
67
 
66
68
  # The builtin styles basic colors like black, red, green.
67
- BASIC_COLORS = %w{BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE GRAY GREY NONE}
69
+ BASIC_COLORS =
70
+ %w[BLACK RED GREEN YELLOW BLUE
71
+ MAGENTA CYAN WHITE GRAY GREY NONE].freeze
68
72
 
69
73
  colors = BASIC_COLORS.dup
70
74
  BASIC_COLORS.each do |color|
71
75
  bright_color = "BRIGHT_#{color}"
72
76
  colors << bright_color
73
- const_set bright_color + '_STYLE', const_get(color + '_STYLE').bright
77
+ const_set bright_color + "_STYLE", const_get(color + "_STYLE").bright
74
78
 
75
79
  light_color = "LIGHT_#{color}"
76
80
  colors << light_color
77
- const_set light_color + '_STYLE', const_get(color + '_STYLE').light
81
+ const_set light_color + "_STYLE", const_get(color + "_STYLE").light
78
82
  end
79
83
 
80
84
  # The builtin styles' colors like LIGHT_RED and BRIGHT_BLUE.
@@ -86,11 +90,10 @@ class HighLine
86
90
  const_set "ON_#{color}", const_get("ON_#{color}_STYLE").code
87
91
  end
88
92
 
89
- ON_NONE_STYLE.rgb = [255,255,255] # Override; white background
93
+ ON_NONE_STYLE.rgb = [255, 255, 255] # Override; white background
90
94
 
91
95
  # BuiltinStyles class methods to be extended.
92
96
  module ClassMethods
93
-
94
97
  # Regexp to match against RGB style constant names.
95
98
  RGB_COLOR_PATTERN = /^(ON_)?(RGB_)([A-F0-9]{6})(_STYLE)?$/
96
99
 
@@ -98,27 +101,28 @@ class HighLine
98
101
  # builtin constants (without explicitly defining them)
99
102
  # @param name [Symbol] missing constant name
100
103
  def const_missing(name)
101
- if name.to_s =~ RGB_COLOR_PATTERN
102
- on = $1
103
- suffix = $4
104
-
105
- if suffix
106
- code_name = $1.to_s + $2 + $3
107
- else
108
- code_name = name.to_s
109
- end
110
-
111
- style_name = code_name + '_STYLE'
112
- style = Style.rgb($3)
113
- style = style.on if on
114
-
115
- const_set(style_name, style)
116
- const_set(code_name, style.code)
117
-
118
- suffix ? style : style.code
119
- else
120
- raise NameError, "Bad color or uninitialized constant #{name}"
121
- end
104
+ raise NameError, "Bad color or uninitialized constant #{name}" unless
105
+ name.to_s =~ RGB_COLOR_PATTERN
106
+
107
+ on = Regexp.last_match(1)
108
+ suffix = Regexp.last_match(4)
109
+
110
+ code_name = if suffix
111
+ Regexp.last_match(1).to_s +
112
+ Regexp.last_match(2) +
113
+ Regexp.last_match(3)
114
+ else
115
+ name.to_s
116
+ end
117
+
118
+ style_name = code_name + "_STYLE"
119
+ style = Style.rgb(Regexp.last_match(3))
120
+ style = style.on if on
121
+
122
+ const_set(style_name, style)
123
+ const_set(code_name, style.code)
124
+
125
+ suffix ? style : style.code
122
126
  end
123
127
  end
124
128
  end
@@ -8,7 +8,6 @@
8
8
  #
9
9
  # This is Free Software. See LICENSE and COPYING for details
10
10
 
11
-
12
11
  class HighLine
13
12
  #
14
13
  # ColorScheme objects encapsulate a named set of colors to be used in the
@@ -19,7 +18,8 @@ class HighLine
19
18
  #
20
19
  # A ColorScheme contains named sets of HighLine color constants.
21
20
  #
22
- # @example Instantiating a color scheme, applying it to HighLine, and using it:
21
+ # @example Instantiating a color scheme, applying it to HighLine,
22
+ # and using it:
23
23
  # ft = HighLine::ColorScheme.new do |cs|
24
24
  # cs[:headline] = [ :bold, :yellow, :on_black ]
25
25
  # cs[:horizontal_line] = [ :bold, :white ]
@@ -49,15 +49,15 @@ class HighLine
49
49
  # constants.
50
50
  #
51
51
  # @param h [Hash]
52
- def initialize( h = nil )
53
- @scheme = Hash.new
52
+ def initialize(h = nil)
53
+ @scheme = {}
54
54
  load_from_hash(h) if h
55
55
  yield self if block_given?
56
56
  end
57
57
 
58
58
  # Load multiple colors from key/value pairs.
59
59
  # @param h [Hash]
60
- def load_from_hash( h )
60
+ def load_from_hash(h)
61
61
  h.each_pair do |color_tag, constants|
62
62
  self[color_tag] = constants
63
63
  end
@@ -66,20 +66,20 @@ class HighLine
66
66
  # Does this color scheme include the given tag name?
67
67
  # @param color_tag [#to_sym]
68
68
  # @return [Boolean]
69
- def include?( color_tag )
69
+ def include?(color_tag)
70
70
  @scheme.keys.include?(to_symbol(color_tag))
71
71
  end
72
72
 
73
73
  # Allow the scheme to be accessed like a Hash.
74
74
  # @param color_tag [#to_sym]
75
75
  # @return [Style]
76
- def []( color_tag )
76
+ def [](color_tag)
77
77
  @scheme[to_symbol(color_tag)]
78
78
  end
79
79
 
80
80
  # Retrieve the original form of the scheme
81
81
  # @param color_tag [#to_sym]
82
- def definition( color_tag )
82
+ def definition(color_tag)
83
83
  style = @scheme[to_symbol(color_tag)]
84
84
  style && style.list
85
85
  end
@@ -93,29 +93,33 @@ class HighLine
93
93
  # Allow the scheme to be set like a Hash.
94
94
  # @param color_tag [#to_sym]
95
95
  # @param constants [Array<Symbol>] Array of Style symbols
96
- def []=( color_tag, constants )
97
- @scheme[to_symbol(color_tag)] = HighLine::Style.new(:name=>color_tag.to_s.downcase.to_sym,
98
- :list=>constants, :no_index=>true)
96
+ def []=(color_tag, constants)
97
+ @scheme[to_symbol(color_tag)] =
98
+ HighLine::Style.new(name: color_tag.to_s.downcase.to_sym,
99
+ list: constants,
100
+ no_index: true)
99
101
  end
100
102
 
101
103
  # Retrieve the color scheme hash (in original definition format)
102
104
  # @return [Hash] scheme as Hash. It may be reused in a new ColorScheme.
103
105
  def to_hash
104
- @scheme.inject({}) { |hsh, pair| key, value = pair; hsh[key] = value.list; hsh }
106
+ @scheme.each_with_object({}) do |pair, hsh|
107
+ key, value = pair
108
+ hsh[key] = value.list
109
+ end
105
110
  end
106
111
 
107
-
108
112
  private
109
113
 
110
114
  # Return a normalized representation of a color name.
111
- def to_symbol( t )
115
+ def to_symbol(t)
112
116
  t.to_s.downcase
113
117
  end
114
118
 
115
119
  # Return a normalized representation of a color setting.
116
- def to_constant( v )
120
+ def to_constant(v)
117
121
  v = v.to_s if v.is_a?(Symbol)
118
- if v.is_a?(::String) then
122
+ if v.is_a?(::String)
119
123
  HighLine.const_get(v.upcase)
120
124
  else
121
125
  v
@@ -125,23 +129,23 @@ class HighLine
125
129
 
126
130
  # A sample ColorScheme.
127
131
  class SampleColorScheme < ColorScheme
132
+ SAMPLE_SCHEME = {
133
+ critical: [:yellow, :on_red],
134
+ error: [:bold, :red],
135
+ warning: [:bold, :yellow],
136
+ notice: [:bold, :magenta],
137
+ info: [:bold, :cyan],
138
+ debug: [:bold, :green],
139
+ row_even: [:cyan],
140
+ row_odd: [:magenta]
141
+ }.freeze
128
142
  #
129
143
  # Builds the sample scheme with settings for <tt>:critical</tt>,
130
144
  # <tt>:error</tt>, <tt>:warning</tt>, <tt>:notice</tt>, <tt>:info</tt>,
131
145
  # <tt>:debug</tt>, <tt>:row_even</tt>, and <tt>:row_odd</tt> colors.
132
146
  #
133
- def initialize( h = nil )
134
- scheme = {
135
- :critical => [ :yellow, :on_red ],
136
- :error => [ :bold, :red ],
137
- :warning => [ :bold, :yellow ],
138
- :notice => [ :bold, :magenta ],
139
- :info => [ :bold, :cyan ],
140
- :debug => [ :bold, :green ],
141
- :row_even => [ :cyan ],
142
- :row_odd => [ :magenta ]
143
- }
144
- super(scheme)
147
+ def initialize(_h = nil)
148
+ super(SAMPLE_SCHEME)
145
149
  end
146
150
  end
147
151
  end
@@ -4,13 +4,13 @@ unless STDIN.respond_to? :getbyte
4
4
  # HighLine adds #getbyte alias to #getc when #getbyte is not available.
5
5
  class IO
6
6
  # alias to #getc when #getbyte is not available
7
- alias_method :getbyte, :getc
7
+ alias getbyte getc
8
8
  end
9
9
 
10
10
  # HighLine adds #getbyte alias to #getc when #getbyte is not available.
11
11
  class StringIO
12
12
  # alias to #getc when #getbyte is not available
13
- alias_method :getbyte, :getc
13
+ alias getbyte getc
14
14
  end
15
15
  end
16
16
 
@@ -18,6 +18,6 @@ unless "".respond_to? :each_line
18
18
  # HighLine adds #each_line alias to #each when each_line is not available.
19
19
  class String
20
20
  # alias to #each when each_line is not available.
21
- alias_method :each_line, :each
21
+ alias each_line each
22
22
  end
23
23
  end
@@ -1,5 +1,6 @@
1
- class HighLine
1
+ # encoding: utf-8
2
2
 
3
+ class HighLine
3
4
  # Internal HighLine errors.
4
5
  module CustomErrors
5
6
  # An error that responds to :explanation_key
@@ -10,22 +10,19 @@
10
10
  require "highline"
11
11
  require "forwardable"
12
12
 
13
- $terminal = HighLine.new
14
-
15
13
  #
16
14
  # <tt>require "highline/import"</tt> adds shortcut methods to Kernel, making
17
15
  # {HighLine#agree}, {HighLine#ask}, {HighLine#choose} and {HighLine#say}
18
16
  # globally available. This is handy for
19
- # quick and dirty input and output. These methods use the HighLine object in
20
- # the global variable <tt>$terminal</tt>, which is initialized to use
21
- # <tt>$stdin</tt> and <tt>$stdout</tt> (you are free to change this).
22
- # Otherwise, these methods are identical to their {HighLine} counterparts, see that
23
- # class for detailed explanations.
17
+ # quick and dirty input and output. These methods use HighLine.default_instance
18
+ # which is initialized to use <tt>$stdin</tt> and <tt>$stdout</tt> (you are free
19
+ # to change this).
20
+ # Otherwise, these methods are identical to their {HighLine} counterparts,
21
+ # see that class for detailed explanations.
24
22
  #
25
23
  module Kernel
26
24
  extend Forwardable
27
- def_delegators :$terminal, :agree, :ask, :choose, :say,
28
- :use_color=, :use_color?, :reset_use_color
25
+ def_instance_delegators :HighLine, :agree, :ask, :choose, :say
29
26
  end
30
27
 
31
28
  # When requiring 'highline/import' HighLine adds {#or_ask} to Object so
@@ -41,11 +38,11 @@ class Object
41
38
  # @param details [lambda] block to be called with the question
42
39
  # instance as argument.
43
40
  # @return [String] answer
44
- def or_ask( *args, &details )
41
+ def or_ask(*args, &details)
45
42
  ask(*args) do |question|
46
43
  question.first_answer = String(self)
47
44
 
48
- details.call(question) if details
45
+ yield(question) if details
49
46
  end
50
47
  end
51
48
  end
data/lib/highline/list.rb CHANGED
@@ -1,10 +1,8 @@
1
1
  # coding: utf-8
2
2
 
3
3
  class HighLine
4
-
5
4
  # List class with some convenience methods like {#col_down}.
6
5
  class List
7
-
8
6
  # Original given *items* argument.
9
7
  # It's frozen at initialization time and
10
8
  # all later transformations will happen on {#list}.
@@ -33,7 +31,6 @@ class HighLine
33
31
 
34
32
  attr_reader :transpose_mode
35
33
 
36
-
37
34
  # Content are distributed first by column in col down mode.
38
35
  # @return [Boolean]
39
36
  #
@@ -69,7 +66,8 @@ class HighLine
69
66
  build
70
67
  end
71
68
 
72
- # Transpose the (already sliced by rows) list, turning its rows into columns.
69
+ # Transpose the (already sliced by rows) list,
70
+ # turning its rows into columns.
73
71
  # @return [self]
74
72
  def transpose
75
73
  first_row = @list[0]
@@ -141,9 +139,7 @@ class HighLine
141
139
 
142
140
  # Set the {#row_join_string}.
143
141
  # @see #row_join_string
144
- def row_join_string=(string)
145
- @row_join_string = string
146
- end
142
+ attr_writer :row_join_string
147
143
 
148
144
  # Returns the row join string size.
149
145
  # Useful for calculating the actual size of
@@ -178,4 +174,4 @@ class HighLine
178
174
  row.compact.join(row_join_string) + "\n"
179
175
  end
180
176
  end
181
- end
177
+ end
@@ -1,251 +1,257 @@
1
1
  # coding: utf-8
2
2
 
3
- require 'highline/template_renderer'
4
- require 'highline/wrapper'
5
- require 'highline/list'
6
-
7
- #
8
- # This class is a utility for quickly and easily laying out lists
9
- # to be used by HighLine.
10
- #
11
- class HighLine::ListRenderer
12
- # Items list
13
- # @return [Array]
14
- attr_reader :items
15
-
16
- # @return [Symbol] the current mode the List is being rendered
17
- # @see #initialize for more details see mode parameter of #initialize
18
- attr_reader :mode
19
-
20
- # Changes the behaviour of some modes. Example, in :inline mode
21
- # the option is treated as the 'end separator' (defaults to " or ")
22
- # @return option parameter that changes the behaviour of some modes.
23
- attr_reader :option
24
-
25
- # @return [HighLine] context
26
- attr_reader :highline
27
-
28
- # The only required parameters are _items_ and _highline_.
29
- # @param items [Array] the Array of items to list
30
- # @param mode [Symbol] controls how that list is formed
31
- # @param option has different effects, depending on the _mode_.
32
- # @param highline [HighLine] a HighLine instance to direct the output to.
33
- #
34
- # Recognized modes are:
3
+ require "highline/template_renderer"
4
+ require "highline/wrapper"
5
+ require "highline/list"
6
+
7
+ class HighLine
35
8
  #
36
- # <tt>:columns_across</tt>:: _items_ will be placed in columns,
37
- # flowing from left to right. If given,
38
- # _option_ is the number of columns to be
39
- # used. When absent, columns will be
40
- # determined based on _wrap_at_ or a
41
- # default of 80 characters.
42
- # <tt>:columns_down</tt>:: Identical to <tt>:columns_across</tt>,
43
- # save flow goes down.
44
- # <tt>:uneven_columns_across</tt>:: Like <tt>:columns_across</tt> but each
45
- # column is sized independently.
46
- # <tt>:uneven_columns_down</tt>:: Like <tt>:columns_down</tt> but each
47
- # column is sized independently.
48
- # <tt>:inline</tt>:: All _items_ are placed on a single line.
49
- # The last two _items_ are separated by
50
- # _option_ or a default of " or ". All
51
- # other _items_ are separated by ", ".
52
- # <tt>:rows</tt>:: The default mode. Each of the _items_ is
53
- # placed on its own line. The _option_
54
- # parameter is ignored in this mode.
9
+ # This class is a utility for quickly and easily laying out lists
10
+ # to be used by HighLine.
55
11
  #
56
- # Each member of the _items_ Array is passed through ERb and thus can contain
57
- # their own expansions. Color escape expansions do not contribute to the
58
- # final field width.
59
-
60
- def initialize(items, mode = :rows, option = nil, highline)
61
- @highline = highline
62
- @mode = mode
63
- @option = option
64
- @items = render_list_items(items)
65
- end
12
+ class ListRenderer
13
+ # Items list
14
+ # @return [Array]
15
+ attr_reader :items
16
+
17
+ # @return [Symbol] the current mode the List is being rendered
18
+ # @see #initialize for more details see mode parameter of #initialize
19
+ attr_reader :mode
20
+
21
+ # Changes the behaviour of some modes. Example, in :inline mode
22
+ # the option is treated as the 'end separator' (defaults to " or ")
23
+ # @return option parameter that changes the behaviour of some modes.
24
+ attr_reader :option
25
+
26
+ # @return [HighLine] context
27
+ attr_reader :highline
28
+
29
+ # The only required parameters are _items_ and _highline_.
30
+ # @param items [Array] the Array of items to list
31
+ # @param mode [Symbol] controls how that list is formed
32
+ # @param option has different effects, depending on the _mode_.
33
+ # @param highline [HighLine] a HighLine instance to direct the output to.
34
+ #
35
+ # Recognized modes are:
36
+ #
37
+ # <tt>:columns_across</tt>:: _items_ will be placed in columns,
38
+ # flowing from left to right. If given,
39
+ # _option_ is the number of columns to be
40
+ # used. When absent, columns will be
41
+ # determined based on _wrap_at_ or a
42
+ # default of 80 characters.
43
+ # <tt>:columns_down</tt>:: Identical to <tt>:columns_across</tt>,
44
+ # save flow goes down.
45
+ # <tt>:uneven_columns_across</tt>:: Like <tt>:columns_across</tt> but each
46
+ # column is sized independently.
47
+ # <tt>:uneven_columns_down</tt>:: Like <tt>:columns_down</tt> but each
48
+ # column is sized independently.
49
+ # <tt>:inline</tt>:: All _items_ are placed on a single
50
+ # line. The last two _items_ are
51
+ # separated by _option_ or a default of
52
+ # " or ". All other _items_ are
53
+ # separated by ", ".
54
+ # <tt>:rows</tt>:: The default mode. Each of the _items_
55
+ # is placed on its own line. The _option_
56
+ # parameter is ignored in this mode.
57
+ #
58
+ # Each member of the _items_ Array is passed through ERb and thus can
59
+ # contain their own expansions. Color escape expansions do not contribute to
60
+ # the final field width.
61
+
62
+ def initialize(items, mode = :rows, option = nil, highline)
63
+ @highline = highline
64
+ @mode = mode
65
+ @option = option
66
+ @items = render_list_items(items)
67
+ end
66
68
 
67
- # Render the list using the appropriate mode and options.
68
- # @return [String] rendered list as String
69
- def render
70
- return "" if items.empty?
71
-
72
- case mode
73
- when :inline
74
- list_inline_mode
75
- when :columns_across
76
- list_columns_across_mode
77
- when :columns_down
78
- list_columns_down_mode
79
- when :uneven_columns_across
80
- list_uneven_columns_mode
81
- when :uneven_columns_down
82
- list_uneven_columns_down_mode
83
- else
84
- list_default_mode
69
+ # Render the list using the appropriate mode and options.
70
+ # @return [String] rendered list as String
71
+ def render
72
+ return "" if items.empty?
73
+
74
+ case mode
75
+ when :inline
76
+ list_inline_mode
77
+ when :columns_across
78
+ list_columns_across_mode
79
+ when :columns_down
80
+ list_columns_down_mode
81
+ when :uneven_columns_across
82
+ list_uneven_columns_mode
83
+ when :uneven_columns_down
84
+ list_uneven_columns_down_mode
85
+ else
86
+ list_default_mode
87
+ end
85
88
  end
86
- end
87
89
 
88
- private
90
+ private
89
91
 
90
- def render_list_items(items)
91
- items.to_ary.map do |item|
92
- item = String(item)
93
- template = ERB.new(item, nil, "%")
94
- template_renderer = HighLine::TemplateRenderer.new(template, self, highline)
95
- template_renderer.render
92
+ def render_list_items(items)
93
+ items.to_ary.map do |item|
94
+ item = String(item)
95
+ template = ERB.new(item, nil, "%")
96
+ template_renderer =
97
+ HighLine::TemplateRenderer.new(template, self, highline)
98
+ template_renderer.render
99
+ end
96
100
  end
97
- end
98
101
 
99
- def list_default_mode
100
- items.map { |i| "#{i}\n" }.join
101
- end
102
+ def list_default_mode
103
+ items.map { |i| "#{i}\n" }.join
104
+ end
102
105
 
103
- def list_inline_mode
104
- end_separator = option || " or "
106
+ def list_inline_mode
107
+ end_separator = option || " or "
105
108
 
106
- if items.size == 1
107
- items.first
108
- else
109
- items[0..-2].join(", ") + "#{end_separator}#{items.last}"
109
+ if items.size == 1
110
+ items.first
111
+ else
112
+ items[0..-2].join(", ") + "#{end_separator}#{items.last}"
113
+ end
110
114
  end
111
- end
112
115
 
113
- def list_columns_across_mode
114
- HighLine::List.new(right_padded_items, cols: col_count).to_s
115
- end
116
+ def list_columns_across_mode
117
+ HighLine::List.new(right_padded_items, cols: col_count).to_s
118
+ end
116
119
 
117
- def list_columns_down_mode
118
- HighLine::List.new(right_padded_items, cols: col_count, col_down: true).to_s
119
- end
120
+ def list_columns_down_mode
121
+ HighLine::List.new(
122
+ right_padded_items,
123
+ cols: col_count,
124
+ col_down: true
125
+ ).to_s
126
+ end
120
127
 
121
- def list_uneven_columns_mode(list=nil)
122
- list ||= HighLine::List.new(items)
128
+ def list_uneven_columns_mode(list = nil)
129
+ list ||= HighLine::List.new(items)
123
130
 
124
- col_max = option || items.size
125
- col_max.downto(1) do |column_count|
126
- list.cols = column_count
127
- widths = get_col_widths(list)
131
+ col_max = option || items.size
132
+ col_max.downto(1) do |column_count|
133
+ list.cols = column_count
134
+ widths = get_col_widths(list)
128
135
 
129
- if column_count == 1 or # last guess
130
- inside_line_size_limit?(widths) or # good guess
131
- option # defined by user
132
- return pad_uneven_rows(list, widths)
136
+ if column_count == 1 || # last guess
137
+ inside_line_size_limit?(widths) || # good guess
138
+ option # defined by user
139
+ return pad_uneven_rows(list, widths)
140
+ end
133
141
  end
134
142
  end
135
- end
136
143
 
137
- def list_uneven_columns_down_mode
138
- list = HighLine::List.new(items, col_down: true)
139
- list_uneven_columns_mode(list)
140
- end
144
+ def list_uneven_columns_down_mode
145
+ list = HighLine::List.new(items, col_down: true)
146
+ list_uneven_columns_mode(list)
147
+ end
141
148
 
142
- def pad_uneven_rows(list, widths)
143
- right_padded_list = Array(list).map do |row|
144
- right_pad_row(row.compact, widths)
149
+ def pad_uneven_rows(list, widths)
150
+ right_padded_list = Array(list).map do |row|
151
+ right_pad_row(row.compact, widths)
152
+ end
153
+ stringfy_list(right_padded_list)
145
154
  end
146
- stringfy_list(right_padded_list)
147
- end
148
155
 
149
- def stringfy_list(list)
150
- list.map { |row| row_to_s(row) }.join
151
- end
156
+ def stringfy_list(list)
157
+ list.map { |row| row_to_s(row) }.join
158
+ end
152
159
 
153
- def row_to_s(row)
154
- row.compact.join(row_join_string) + "\n"
155
- end
160
+ def row_to_s(row)
161
+ row.compact.join(row_join_string) + "\n"
162
+ end
156
163
 
157
- def right_pad_row(row, widths)
158
- row.zip(widths).map do |field, width|
159
- right_pad_field(field, width)
164
+ def right_pad_row(row, widths)
165
+ row.zip(widths).map do |field, width|
166
+ right_pad_field(field, width)
167
+ end
160
168
  end
161
- end
162
169
 
163
- def right_pad_field(field, width)
164
- field = String(field) # nil protection
165
- pad_size = width - actual_length(field)
166
- field + (pad_char * pad_size)
167
- end
170
+ def right_pad_field(field, width)
171
+ field = String(field) # nil protection
172
+ pad_size = width - actual_length(field)
173
+ field + (pad_char * pad_size)
174
+ end
168
175
 
169
- def get_col_widths(lines)
170
- lines = transpose(lines)
171
- get_segment_widths(lines)
172
- end
176
+ def get_col_widths(lines)
177
+ lines = transpose(lines)
178
+ get_segment_widths(lines)
179
+ end
173
180
 
174
- def get_row_widths(lines)
175
- get_segment_widths(lines)
176
- end
181
+ def get_row_widths(lines)
182
+ get_segment_widths(lines)
183
+ end
177
184
 
178
- def get_segment_widths(lines)
179
- lines.map do |col|
180
- actual_lengths_for(col).max
185
+ def get_segment_widths(lines)
186
+ lines.map do |col|
187
+ actual_lengths_for(col).max
188
+ end
181
189
  end
182
- end
183
190
 
184
- def actual_lengths_for(line)
185
- line.map do |item|
186
- actual_length(item)
191
+ def actual_lengths_for(line)
192
+ line.map do |item|
193
+ actual_length(item)
194
+ end
187
195
  end
188
- end
189
196
 
190
- def transpose(lines)
191
- lines = Array(lines)
192
- first_line = lines.shift
193
- first_line.zip(*lines)
194
- end
197
+ def transpose(lines)
198
+ lines = Array(lines)
199
+ first_line = lines.shift
200
+ first_line.zip(*lines)
201
+ end
195
202
 
196
- def inside_line_size_limit?(widths)
197
- line_size = widths.inject(0) { |sum, n| sum + n + row_join_str_size }
198
- line_size <= line_size_limit + row_join_str_size
199
- end
203
+ def inside_line_size_limit?(widths)
204
+ line_size = widths.reduce(0) { |sum, n| sum + n + row_join_str_size }
205
+ line_size <= line_size_limit + row_join_str_size
206
+ end
200
207
 
201
- def actual_length(text)
202
- HighLine::Wrapper.actual_length text
203
- end
208
+ def actual_length(text)
209
+ HighLine::Wrapper.actual_length text
210
+ end
204
211
 
205
- def items_max_length
206
- @items_max_length ||= max_length(items)
207
- end
212
+ def items_max_length
213
+ @items_max_length ||= max_length(items)
214
+ end
208
215
 
209
- def max_length(items)
210
- items.map { |item| actual_length(item) }.max
211
- end
216
+ def max_length(items)
217
+ items.map { |item| actual_length(item) }.max
218
+ end
212
219
 
213
- def line_size_limit
214
- @line_size_limit ||= ( highline.wrap_at || 80 )
215
- end
220
+ def line_size_limit
221
+ @line_size_limit ||= (highline.wrap_at || 80)
222
+ end
216
223
 
217
- def row_join_string
218
- @row_join_string ||= " "
219
- end
224
+ def row_join_string
225
+ @row_join_string ||= " "
226
+ end
220
227
 
221
- def row_join_string=(string)
222
- @row_join_string = string
223
- end
228
+ attr_writer :row_join_string
224
229
 
225
- def row_join_str_size
226
- row_join_string.size
227
- end
230
+ def row_join_str_size
231
+ row_join_string.size
232
+ end
228
233
 
229
- def get_col_count
230
- (line_size_limit + row_join_str_size) /
231
- (items_max_length + row_join_str_size)
232
- end
234
+ def col_count_calculate
235
+ (line_size_limit + row_join_str_size) /
236
+ (items_max_length + row_join_str_size)
237
+ end
233
238
 
234
- def col_count
235
- option || get_col_count
236
- end
239
+ def col_count
240
+ option || col_count_calculate
241
+ end
237
242
 
238
- def right_padded_items
239
- items.map do |item|
240
- right_pad_field(item, items_max_length)
243
+ def right_padded_items
244
+ items.map do |item|
245
+ right_pad_field(item, items_max_length)
246
+ end
241
247
  end
242
- end
243
248
 
244
- def pad_char
245
- " "
246
- end
249
+ def pad_char
250
+ " "
251
+ end
247
252
 
248
- def row_count
249
- (items.count / col_count.to_f).ceil
253
+ def row_count
254
+ (items.count / col_count.to_f).ceil
255
+ end
250
256
  end
251
- end
257
+ end