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