lib/interactive/options.rb in interactive-0.5.0 vs lib/interactive/options.rb in interactive-0.6.0
- old
+ new
@@ -1,12 +1,18 @@
require 'delegate'
require 'interactive'
module Interactive
module_function
- def Options(options=[])
- options.empty? ? EmptyOptions.new([]) : NonEmptyOptions.new(options)
+ def Options(options=[], columns=[])
+ if options.empty?
+ EmptyOptions.new([])
+ elsif Array(columns).any?
+ TabularOptions.new(options, columns)
+ else
+ NonEmptyOptions.new(options)
+ end
end
class NonEmptyOptions < SimpleDelegator
include Interactive
def initialize(options)
@@ -50,9 +56,60 @@
@options.inject("") { |accum, opt| "#{accum}#{ opt.shortcut_value}/" }
end
def first_chars_without_last_slash(first_chars)
first_chars[0..first_chars.length-2]
+ end
+ end
+
+ class TabularOptions < NonEmptyOptions
+ def initialize(options, columns)
+ @options = options
+ @headings = columns.clone
+ columns.shift
+ @table_columns = columns
+ super(@options)
+ end
+
+ def shortcuts_meanings
+ non_table_shortcuts_meanings + table_shortcuts_meanings
+ end
+
+ private
+
+ def non_table_shortcuts_meanings
+ non_table_options.inject("") {|accum, opt| "#{accum} #{opt[0]} -- #{opt}\n"}
+ end
+
+ def table_shortcuts_meanings
+ @table = Terminal::Table.new(headings: @headings)
+ @table.align_column(0, :right)
+ rows.each {|row| @table << row}
+ @table.to_s
+ end
+
+ def non_table_options
+ @options.reject do |opt|
+ @table_columns.inject(true) {|accum, col| accum && opt.value.respond_to?(col) }
+ end
+ end
+
+ def table_options
+ @options.select do |opt|
+ opt_responds_to_each_column?(opt)
+ end
+ end
+
+ def rows
+ table_options.map.with_index do |opt, index|
+ @table_columns.inject([]) do |accum, col|
+ accum << opt.value.send(col)
+ end.insert(0, index)
+ end
+ end
+
+ def opt_responds_to_each_column?(opt)
+ @table_columns.inject(true) {|accum, col| accum && opt.value.respond_to?(col) }
end
end
class EmptyOptions < SimpleDelegator