lib/highline/menu.rb in highline-2.0.0.pre.develop.9 vs lib/highline/menu.rb in highline-2.0.0.pre.develop.11

- old
+ new

@@ -11,28 +11,29 @@ require "highline/question" require "highline/menu/item" class HighLine # - # Menu objects encapsulate all the details of a call to {HighLine#choose HighLine#choose}. + # Menu objects encapsulate all the details of a call to + # {HighLine#choose HighLine#choose}. # Using the accessors and {Menu#choice} and {Menu#choices}, the block passed # to {HighLine#choose} can detail all aspects of menu display and control. # class Menu < Question # Pass +false+ to _color_ to turn off HighLine::Menu's # index coloring. # Pass a color and the Menu's indices will be colored. - def self.index_color=(color = :rgb_77bbff) - @index_color = color + class << self + attr_writer :index_color end # Initialize it self.index_color = false # Returns color used for coloring Menu's indices - def self.index_color - @index_color + class << self + attr_reader :index_color end # # Create an instance of HighLine::Menu. All customization is done # through the passed block, which should call accessors, {#choice} and @@ -51,14 +52,14 @@ def initialize # # Initialize Question objects with ignored values, we'll # adjust ours as needed. # - super("Ignored", [ ], &nil) # avoiding passing the block along + super("Ignored", [], &nil) # avoiding passing the block along - @items = [ ] - @hidden_items = [ ] + @items = [] + @hidden_items = [] @help = Hash.new("There's no help for that topic.") @index = :number @index_suffix = ". " @select_by = :index_or_name @@ -73,17 +74,17 @@ # Used for coloring Menu indices. # Set it to default. But you may override it. @index_color = self.class.index_color # Override Questions responses, we'll set our own. - @responses = { } + @responses = {} # Context for action code. @highline = nil yield self if block_given? - init_help if @shell and not @help.empty? + init_help if @shell && !@help.empty? end # # An _index_ to append to each menu item in display. See # Menu.index=() for details. @@ -177,39 +178,40 @@ # @example Use of help string on menu items # cli = HighLine.new # cli.choose do |menu| # menu.shell = true # - # menu.choice(:load, text: 'Load a file', help: "Load a file using your favourite editor.") + # menu.choice(:load, text: 'Load a file', + # help: "Load a file using your favourite editor.") # menu.choice(:save, help: "Save data in file.") # menu.choice(:quit, help: "Exit program.") # # menu.help("rules", "The rules of this system are as follows...") # end - def choice( name, help = nil, text = nil, &action ) + def choice(name, help = nil, text = nil, &action) item = Menu::Item.new(name, text: text, help: help, action: action) @items << item @help.merge!(item.item_help) - update_responses # rebuild responses based on our settings + update_responses # rebuild responses based on our settings end # - # This method helps reduce the namespaces in the original call, which would look - # like this: HighLine::Menu::Item.new(...) + # This method helps reduce the namespaces in the original call, + # which would look like this: HighLine::Menu::Item.new(...) # With #build_item, it looks like this: menu.build_item(...) - # @param *args splat args, the same args you would pass to an initialization of - # HighLine::Menu::Item + # @param *args splat args, the same args you would pass to an + # initialization of HighLine::Menu::Item # @return [HighLine::Menu::Item] the menu item def build_item(*args) Menu::Item.new(*args) end # - # Adds an item directly to the menu. If you want more configuraiton or options, - # use this method + # Adds an item directly to the menu. If you want more configuration + # or options, use this method # # @param item [Menu::Item] item containing choice fields and more # @return [void] def add_item(item) @@ -221,30 +223,31 @@ # # A shortcut for multiple calls to the sister method {#choice}. <b>Be # warned:</b> An _action_ set here will apply to *all* provided # _names_. This is considered to be a feature, so you can easily # hand-off interface processing to a different chunk of code. - # @param names [Array<#to_s>] menu item titles/headers/names to be displayed. + # @param names [Array<#to_s>] menu item titles/headers/names to be + # displayed. # @param action (see #choice) # @return [void] # @example (see HighLine::Menu#initialize) # # choice has more options available to you, like longer text or help (and # of course, individual actions) # - def choices( *names, &action ) + def choices(*names, &action) names.each { |n| choice(n, &action) } end # Identical to {#choice}, but the item will not be listed for the user. # @see #choice # @param name (see #choice) # @param help (see #choice) # @param action (see #choice) # @return (see #choice) - def hidden( name, help = nil, &action ) + def hidden(name, help = nil, &action) item = Menu::Item.new(name, text: name, help: help, action: action) @hidden_items << item @help.merge!(item.item_help) end @@ -261,35 +264,40 @@ # # Setting the _index_ to <tt>:none</tt> or a literal String also adjusts # _index_suffix_ to a single space and _select_by_ to <tt>:name</tt>. # Because of this, you should make a habit of setting the _index_ first. # - def index=( style ) + def index=(style) @index = style + return unless @index == :none || @index.is_a?(::String) + # Default settings. - if @index == :none or @index.is_a?(::String) - @index_suffix = " " - @select_by = :name - end + @index_suffix = " " + @select_by = :name end # # Initializes the help system by adding a <tt>:help</tt> choice, some # action code, and the default help listing. # - def init_help( ) + def init_help return if @items.include?(:help) topics = @help.keys.sort - help_help = @help.include?("help") ? @help["help"] : - "This command will display helpful messages about " + - "functionality, like this one. To see the help for " + - "a specific topic enter:\n\thelp [TOPIC]\nTry asking " + - "for help on any of the following:\n\n" + - "<%= list(#{topics.inspect}, :columns_across) %>" - choice(:help, help_help) do |command, topic| + help_help = + if @help.include?("help") + @help["help"] + else + "This command will display helpful messages about " \ + "functionality, like this one. To see the help for " \ + "a specific topic enter:\n\thelp [TOPIC]\nTry asking " \ + "for help on any of the following:\n\n" \ + "<%= list(#{topics.inspect}, :columns_across) %>" + end + + choice(:help, help_help) do |_command, topic| topic.strip! topic.downcase! if topic.empty? @highline.say(@help["help"]) else @@ -300,15 +308,15 @@ # # Used to set help for arbitrary topics. Use the topic <tt>"help"</tt> # to override the default message. Mainly for internal use. # - # @param topic [String] the menu item header/title/name to be associated with - # a help message. + # @param topic [String] the menu item header/title/name to be associated + # with a help message. # @param help [String] the help message to be associated with the menu # item/title/name. - def help( topic, help ) + def help(topic, help) @help[topic] = help end # # Setting a _layout_ with this method also adjusts some other attributes @@ -337,18 +345,18 @@ # # If set to either <tt>:one_line</tt>, or <tt>:menu_only</tt>, _index_ # will default to <tt>:none</tt> and _flow_ will default to # <tt>:inline</tt>. # - def layout=( new_layout ) + def layout=(new_layout) @layout = new_layout # Default settings. case @layout when :one_line, :menu_only self.index = :none - @flow = :inline + @flow = :inline end end # # This method returns all possible options for auto-completion, based @@ -385,16 +393,18 @@ # # This method processes the auto-completed user selection, based on the # rules for this Menu object. If an action was provided for the # selection, it will be executed as described in {#choice}. # - # @param highline_context [HighLine] a HighLine instance to be used as context. - # @param selection [String, Integer] index or title of the selected menu item. + # @param highline_context [HighLine] a HighLine instance to be used + # as context. + # @param selection [String, Integer] index or title of the selected + # menu item. # @param details additional parameter to be passed when in shell mode. # @return [nil, Object] if @nil_on_handled is set it returns +nil+, # else it returns the action return value. - def select( highline_context, selection, details = nil ) + def select(highline_context, selection, details = nil) # add in any hidden menu commands items = all_items # Find the selected action. selected_item = find_item_from_selection(items, selection) @@ -421,22 +431,24 @@ # Returns the menu item referenced by its title/header/name. # @param selection [String] menu's title/header/name def get_item_by_letter(items, selection) item = items.find { |i| i.name == selection } return item if item - l_index = "`" # character before the letter "a" - index = items.map { "#{l_index.succ!}" }.index(selection) + + # 97 is the "a" letter at ascii table + # Ex: For "a" it will return 0, and for "c" it will return 2 + index = selection.ord - 97 items[index] end def value_for_selected_item(item, details) if item.action - if @shell - result = item.action.call(item.name, details) - else - result = item.action.call(item.name) - end + result = if @shell + item.action.call(item.name, details) + else + item.action.call(item.name) + end @nil_on_handled ? nil : result else item.name end end @@ -449,11 +461,11 @@ if selections.is_a?(Array) value_for_array_selections(items, selections, details) elsif selections.is_a?(Hash) value_for_hash_selections(items, selections, details) else - fail ArgumentError, 'selections must be either Array or Hash' + raise ArgumentError, "selections must be either Array or Hash" end end def value_for_array_selections(items, selections, details) # Find the selected items and return values @@ -510,38 +522,38 @@ # # Allows Menu to behave as a String, just like Question. Returns the # _layout_ to be rendered, which is used by HighLine.say(). # - def to_s( ) + def to_s case @layout when :list %(<%= header ? "#{header}:\n" : '' %>) + - parse_list + - show_default_if_any + - "<%= prompt %>" + parse_list + + show_default_if_any + + "<%= prompt %>" when :one_line %(<%= header ? "#{header}: " : '' %>) + - "<%= prompt %>" + - "(" + parse_list + ")" + - show_default_if_any + - "<%= prompt[/\s*$/] %>" + "<%= prompt %>" \ + "(" + parse_list + ")" + + show_default_if_any + + "<%= prompt[/\s*$/] %>" when :menu_only parse_list + - show_default_if_any + - "<%= prompt %>" + show_default_if_any + + "<%= prompt %>" else @layout end end def parse_list "<%= list( menu, #{@flow.inspect}, - #{@list_option.inspect} ) %>" + #{@list_option.inspect} ) %>" end def show_default_if_any - return default.to_s.empty? ? "" : "(#{default}) " + default.to_s.empty? ? "" : "(#{default}) " end # # This method will update the intelligent responses to account for # Menu specific differences. Calls the superclass' (Question's)