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.
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