summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rwxr-xr-xlib/highline.rb70
-rw-r--r--lib/highline/builtin_styles.rb86
-rw-r--r--lib/highline/color_scheme.rb60
-rw-r--r--lib/highline/compatibility.rb6
-rw-r--r--lib/highline/custom_errors.rb3
-rw-r--r--lib/highline/import.rb4
-rw-r--r--lib/highline/list.rb12
-rw-r--r--lib/highline/list_renderer.rb408
-rw-r--r--lib/highline/menu.rb138
-rw-r--r--lib/highline/menu/item.rb2
-rw-r--r--lib/highline/paginator.rb11
-rwxr-xr-xlib/highline/question.rb74
-rw-r--r--lib/highline/question/answer_converter.rb4
-rw-r--r--lib/highline/question_asker.rb32
-rw-r--r--lib/highline/simulate.rb16
-rw-r--r--lib/highline/statement.rb22
-rw-r--r--lib/highline/string.rb17
-rw-r--r--lib/highline/string_extensions.rb44
-rwxr-xr-xlib/highline/style.rb113
-rw-r--r--lib/highline/template_renderer.rb10
-rwxr-xr-xlib/highline/terminal.rb55
-rw-r--r--lib/highline/terminal/io_console.rb4
-rw-r--r--lib/highline/terminal/ncurses.rb7
-rw-r--r--lib/highline/terminal/unix_stty.rb21
-rw-r--r--lib/highline/version.rb2
-rw-r--r--lib/highline/wrapper.rb23
26 files changed, 657 insertions, 587 deletions
diff --git a/lib/highline.rb b/lib/highline.rb
index a94bbed..b51a1a0 100755
--- a/lib/highline.rb
+++ b/lib/highline.rb
@@ -10,6 +10,7 @@
#
# This is Free Software. See LICENSE and COPYING for details.
+require "English"
require "erb"
require "optparse"
require "stringio"
@@ -29,17 +30,17 @@ require "highline/builtin_styles"
#
# A HighLine object is a "high-level line oriented" shell over an input and an
# output stream. HighLine simplifies common console interaction, effectively
-# replacing {Kernel#puts} and {Kernel#gets}. User code can simply specify the question to ask
-# and any details about user interaction, then leave the rest of the work to
-# HighLine. When {HighLine#ask} returns, you'll have the answer you requested,
-# even if HighLine had to ask many times, validate results, perform range
-# checking, convert types, etc.
+# replacing {Kernel#puts} and {Kernel#gets}. User code can simply specify the
+# question to ask and any details about user interaction, then leave the rest
+# of the work to HighLine. When {HighLine#ask} returns, you'll have the answer
+# you requested, even if HighLine had to ask many times, validate results,
+# perform range checking, convert types, etc.
#
# @example Basic usage
# cli = HighLine.new
# answer = cli.ask "What do you think?"
# puts "You have answered: #{answer}"
-
+#
class HighLine
include BuiltinStyles
include CustomErrors
@@ -58,7 +59,7 @@ class HighLine
# Returns +true+ if HighLine is currently using a color scheme.
def using_color_scheme?
- !!@color_scheme
+ true if @color_scheme
end
# Reset color scheme to default (+nil+)
@@ -75,7 +76,8 @@ class HighLine
end
# For checking if the current version of HighLine supports RGB colors
- # Usage: HighLine.supports_rgb_color? rescue false # rescue for compatibility with older versions
+ # Usage: HighLine.supports_rgb_color? rescue false
+ # using rescue for compatibility with older versions
# Note: color usage also depends on HighLine.use_color being set
# TODO: Discuss removing this method
def supports_rgb_color?
@@ -97,8 +99,9 @@ class HighLine
# @param page_at [Integer] page size and paginating.
# @param indent_size [Integer] indentation size in spaces.
# @param indent_level [Integer] how deep is indentated.
- def initialize( input = $stdin, output = $stdout,
- wrap_at = nil, page_at = nil, indent_size=3, indent_level=0 )
+ def initialize(input = $stdin, output = $stdout,
+ wrap_at = nil, page_at = nil,
+ indent_size = 3, indent_level = 0)
@input = input
@output = output
@@ -123,7 +126,7 @@ class HighLine
# Returns truethy if HighLine instance is currently using color escapes.
def use_color?
- !!use_color
+ use_color
end
# Resets the use of color.
@@ -136,7 +139,7 @@ class HighLine
# Returns true if HighLine is currently tracking EOF for input.
def track_eof?
- !!track_eof
+ true if track_eof
end
# @return [Integer] The current column setting for wrapping output.
@@ -182,11 +185,13 @@ class HighLine
#
# Raises EOFError if input is exhausted.
#
- # @param yes_or_no_question [String] a question that accepts yes and no as answers
- # @param character [Boolean, :getc] character mode to be passed to Question#character
+ # @param yes_or_no_question [String] a question that accepts yes and no as
+ # answers
+ # @param character [Boolean, :getc] character mode to be passed to
+ # Question#character
# @see Question#character
- def agree( yes_or_no_question, character = nil )
- ask(yes_or_no_question, lambda { |yn| yn.downcase[0] == ?y}) do |q|
+ def agree(yes_or_no_question, character = nil)
+ ask(yes_or_no_question, ->(yn) { yn.downcase[0] == "y" }) do |q|
q.validate = /\A(?:y(?:es)?|no?)\Z/i
q.responses[:not_valid] = 'Please enter "yes" or "no".'
q.responses[:ask_on_error] = :question
@@ -236,7 +241,7 @@ class HighLine
# @param items [Array<String>]
# @param details [Proc] to be passed to Menu.new
# @return [String] answer
- def choose( *items, &details )
+ def choose(*items, &details)
menu = Menu.new(&details)
menu.choices(*items) unless items.empty?
@@ -268,7 +273,7 @@ class HighLine
# @return [lambda] lambda to be used in autocompletion operations
def shell_style_lambda(menu)
- lambda do |command| # shell-style selection
+ lambda do |command| # shell-style selection
first_word = command.to_s.split.first || ""
options = menu.options
@@ -359,7 +364,7 @@ class HighLine
statement = render_statement(statement)
return if statement.empty?
- statement = (indentation+statement)
+ statement = (indentation + statement)
# Don't add a newline if statement ends with whitespace, OR
# if statement ends with whitespace before a color escape code.
@@ -384,7 +389,7 @@ class HighLine
# set to <tt>:auto</tt>, HighLine will attempt to determine the columns
# available for the <tt>@output</tt> or use a sensible default.
#
- def wrap_at=( setting )
+ def wrap_at=(setting)
@wrap_at = setting == :auto ? output_cols : setting
end
@@ -394,7 +399,7 @@ class HighLine
# set to <tt>:auto</tt>, HighLine will attempt to determine the rows available
# for the <tt>@output</tt> or use a sensible default.
#
- def page_at=( setting )
+ def page_at=(setting)
@page_at = setting == :auto ? output_rows - 2 : setting
end
@@ -402,7 +407,7 @@ class HighLine
# Outputs indentation with current settings
#
def indentation
- ' '*@indent_size*@indent_level
+ " " * @indent_size * @indent_level
end
#
@@ -413,7 +418,7 @@ class HighLine
# @param multiline [Boolean]
# @return [void]
# @see #multi_indent
- def indent(increase=1, statement=nil, multiline=nil)
+ def indent(increase = 1, statement = nil, multiline = nil)
@indent_level += increase
multi = @multi_indent
@multi_indent ||= multiline
@@ -443,7 +448,7 @@ class HighLine
def output_cols
return 80 unless @output.tty?
terminal.terminal_size.first
- rescue
+ rescue NoMethodError
return 80
end
@@ -454,7 +459,7 @@ class HighLine
def output_rows
return 24 unless @output.tty?
terminal.terminal_size.last
- rescue
+ rescue NoMethodError
return 24
end
@@ -468,7 +473,8 @@ class HighLine
# Creates a new HighLine instance with the same options
#
def new_scope
- self.class.new(@input, @output, @wrap_at, @page_at, @indent_size, @indent_level)
+ self.class.new(@input, @output, @wrap_at,
+ @page_at, @indent_size, @indent_level)
end
private
@@ -505,7 +511,7 @@ class HighLine
# @param question [Question]
# @return [String] response
def get_response_line_mode(question)
- if question.echo == true and !question.limit
+ if question.echo == true && !question.limit
get_line(question)
else
get_line_raw_no_echo_mode(question)
@@ -529,13 +535,15 @@ class HighLine
line = ""
terminal.raw_no_echo_mode_exec do
- while character = terminal.get_character
+ loop do
+ character = terminal.get_character
+ break unless character
break if ["\n", "\r"].include? character
# honor backspace and delete
if character == "\b"
chopped = line.chop!
- output_erase_char if chopped and question.echo
+ output_erase_char if chopped && question.echo
else
line << character
say_last_char_or_echo_char(line, question)
@@ -563,11 +571,11 @@ class HighLine
def say_last_char_or_echo_char(line, question)
@output.print(line[-1]) if question.echo == true
- @output.print(question.echo) if question.echo and question.echo != true
+ @output.print(question.echo) if question.echo && question.echo != true
end
def line_overflow_for_question?(line, question)
- question.limit and line.size == question.limit
+ question.limit && line.size == question.limit
end
def output_erase_char
diff --git a/lib/highline/builtin_styles.rb b/lib/highline/builtin_styles.rb
index c829f60..71c2429 100644
--- a/lib/highline/builtin_styles.rb
+++ b/lib/highline/builtin_styles.rb
@@ -1,4 +1,4 @@
-#coding: utf-8
+# coding: utf-8
class HighLine
# Builtin Styles that are included at HighLine initialization.
@@ -23,17 +23,19 @@ class HighLine
blink: "\e[5m",
reverse: "\e[7m",
concealed: "\e[8m"
- }
+ }.freeze
STYLE_LIST.each do |style_name, code|
- style = String(style_name).upcase
+ style = String(style_name).upcase
- const_set style, code
- const_set style + "_STYLE", Style.new(name: style_name, code: code, builtin: true)
+ const_set style, code
+ const_set style + "_STYLE",
+ Style.new(name: style_name, code: code, builtin: true)
end
# Basic Style names like CLEAR, BOLD, UNDERLINE
- STYLES = %w{CLEAR RESET BOLD DARK UNDERLINE UNDERSCORE BLINK REVERSE CONCEALED}
+ STYLES = %w[CLEAR RESET BOLD DARK UNDERLINE
+ UNDERSCORE BLINK REVERSE CONCEALED].freeze
# A Hash with the basic colors an their ANSI escape codes.
COLOR_LIST = {
@@ -48,33 +50,35 @@ class HighLine
gray: { code: "\e[37m", rgb: [192, 192, 192] },
grey: { code: "\e[37m", rgb: [192, 192, 192] },
none: { code: "\e[38m", rgb: [0, 0, 0] }
- }
+ }.freeze
COLOR_LIST.each do |color_name, attributes|
- color = String(color_name).upcase
+ color = String(color_name).upcase
- style = Style.new(
- name: color_name,
- code: attributes[:code],
- rgb: attributes[:rgb],
- builtin: true
- )
+ style = Style.new(
+ name: color_name,
+ code: attributes[:code],
+ rgb: attributes[:rgb],
+ builtin: true
+ )
- const_set color + "_STYLE", style
+ const_set color + "_STYLE", style
end
# The builtin styles basic colors like black, red, green.
- BASIC_COLORS = %w{BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE GRAY GREY NONE}
+ BASIC_COLORS =
+ %w[BLACK RED GREEN YELLOW BLUE
+ MAGENTA CYAN WHITE GRAY GREY NONE].freeze
colors = BASIC_COLORS.dup
BASIC_COLORS.each do |color|
bright_color = "BRIGHT_#{color}"
colors << bright_color
- const_set bright_color + '_STYLE', const_get(color + '_STYLE').bright
+ const_set bright_color + "_STYLE", const_get(color + "_STYLE").bright
light_color = "LIGHT_#{color}"
colors << light_color
- const_set light_color + '_STYLE', const_get(color + '_STYLE').light
+ const_set light_color + "_STYLE", const_get(color + "_STYLE").light
end
# The builtin styles' colors like LIGHT_RED and BRIGHT_BLUE.
@@ -86,11 +90,10 @@ class HighLine
const_set "ON_#{color}", const_get("ON_#{color}_STYLE").code
end
- ON_NONE_STYLE.rgb = [255,255,255] # Override; white background
+ ON_NONE_STYLE.rgb = [255, 255, 255] # Override; white background
# BuiltinStyles class methods to be extended.
module ClassMethods
-
# Regexp to match against RGB style constant names.
RGB_COLOR_PATTERN = /^(ON_)?(RGB_)([A-F0-9]{6})(_STYLE)?$/
@@ -98,27 +101,28 @@ class HighLine
# builtin constants (without explicitly defining them)
# @param name [Symbol] missing constant name
def const_missing(name)
- if name.to_s =~ RGB_COLOR_PATTERN
- on = $1
- suffix = $4
-
- if suffix
- code_name = $1.to_s + $2 + $3
- else
- code_name = name.to_s
- end
-
- style_name = code_name + '_STYLE'
- style = Style.rgb($3)
- style = style.on if on
-
- const_set(style_name, style)
- const_set(code_name, style.code)
-
- suffix ? style : style.code
- else
- raise NameError, "Bad color or uninitialized constant #{name}"
- end
+ raise NameError, "Bad color or uninitialized constant #{name}" unless
+ name.to_s =~ RGB_COLOR_PATTERN
+
+ on = Regexp.last_match(1)
+ suffix = Regexp.last_match(4)
+
+ code_name = if suffix
+ Regexp.last_match(1).to_s +
+ Regexp.last_match(2) +
+ Regexp.last_match(3)
+ else
+ name.to_s
+ end
+
+ style_name = code_name + "_STYLE"
+ style = Style.rgb(Regexp.last_match(3))
+ style = style.on if on
+
+ const_set(style_name, style)
+ const_set(code_name, style.code)
+
+ suffix ? style : style.code
end
end
end
diff --git a/lib/highline/color_scheme.rb b/lib/highline/color_scheme.rb
index 11cd687..e1bec88 100644
--- a/lib/highline/color_scheme.rb
+++ b/lib/highline/color_scheme.rb
@@ -8,7 +8,6 @@
#
# This is Free Software. See LICENSE and COPYING for details
-
class HighLine
#
# ColorScheme objects encapsulate a named set of colors to be used in the
@@ -19,7 +18,8 @@ class HighLine
#
# A ColorScheme contains named sets of HighLine color constants.
#
- # @example Instantiating a color scheme, applying it to HighLine, and using it:
+ # @example Instantiating a color scheme, applying it to HighLine,
+ # and using it:
# ft = HighLine::ColorScheme.new do |cs|
# cs[:headline] = [ :bold, :yellow, :on_black ]
# cs[:horizontal_line] = [ :bold, :white ]
@@ -49,15 +49,15 @@ class HighLine
# constants.
#
# @param h [Hash]
- def initialize( h = nil )
- @scheme = Hash.new
+ def initialize(h = nil)
+ @scheme = {}
load_from_hash(h) if h
yield self if block_given?
end
# Load multiple colors from key/value pairs.
# @param h [Hash]
- def load_from_hash( h )
+ def load_from_hash(h)
h.each_pair do |color_tag, constants|
self[color_tag] = constants
end
@@ -66,20 +66,20 @@ class HighLine
# Does this color scheme include the given tag name?
# @param color_tag [#to_sym]
# @return [Boolean]
- def include?( color_tag )
+ def include?(color_tag)
@scheme.keys.include?(to_symbol(color_tag))
end
# Allow the scheme to be accessed like a Hash.
# @param color_tag [#to_sym]
# @return [Style]
- def []( color_tag )
+ def [](color_tag)
@scheme[to_symbol(color_tag)]
end
# Retrieve the original form of the scheme
# @param color_tag [#to_sym]
- def definition( color_tag )
+ def definition(color_tag)
style = @scheme[to_symbol(color_tag)]
style && style.list
end
@@ -93,29 +93,33 @@ class HighLine
# Allow the scheme to be set like a Hash.
# @param color_tag [#to_sym]
# @param constants [Array<Symbol>] Array of Style symbols
- def []=( color_tag, constants )
- @scheme[to_symbol(color_tag)] = HighLine::Style.new(:name=>color_tag.to_s.downcase.to_sym,
- :list=>constants, :no_index=>true)
+ def []=(color_tag, constants)
+ @scheme[to_symbol(color_tag)] =
+ HighLine::Style.new(name: color_tag.to_s.downcase.to_sym,
+ list: constants,
+ no_index: true)
end
# Retrieve the color scheme hash (in original definition format)
# @return [Hash] scheme as Hash. It may be reused in a new ColorScheme.
def to_hash
- @scheme.inject({}) { |hsh, pair| key, value = pair; hsh[key] = value.list; hsh }
+ @scheme.each_with_object({}) do |pair, hsh|
+ key, value = pair
+ hsh[key] = value.list
+ end
end
-
private
# Return a normalized representation of a color name.
- def to_symbol( t )
+ def to_symbol(t)
t.to_s.downcase
end
# Return a normalized representation of a color setting.
- def to_constant( v )
+ def to_constant(v)
v = v.to_s if v.is_a?(Symbol)
- if v.is_a?(::String) then
+ if v.is_a?(::String)
HighLine.const_get(v.upcase)
else
v
@@ -125,23 +129,23 @@ class HighLine
# A sample ColorScheme.
class SampleColorScheme < ColorScheme
+ SAMPLE_SCHEME = {
+ critical: [:yellow, :on_red],
+ error: [:bold, :red],
+ warning: [:bold, :yellow],
+ notice: [:bold, :magenta],
+ info: [:bold, :cyan],
+ debug: [:bold, :green],
+ row_even: [:cyan],
+ row_odd: [:magenta]
+ }.freeze
#
# Builds the sample scheme with settings for <tt>:critical</tt>,
# <tt>:error</tt>, <tt>:warning</tt>, <tt>:notice</tt>, <tt>:info</tt>,
# <tt>:debug</tt>, <tt>:row_even</tt>, and <tt>:row_odd</tt> colors.
#
- def initialize( h = nil )
- scheme = {
- :critical => [ :yellow, :on_red ],
- :error => [ :bold, :red ],
- :warning => [ :bold, :yellow ],
- :notice => [ :bold, :magenta ],
- :info => [ :bold, :cyan ],
- :debug => [ :bold, :green ],
- :row_even => [ :cyan ],
- :row_odd => [ :magenta ]
- }
- super(scheme)
+ def initialize(_h = nil)
+ super(SAMPLE_SCHEME)
end
end
end
diff --git a/lib/highline/compatibility.rb b/lib/highline/compatibility.rb
index 33c889c..ee13fd6 100644
--- a/lib/highline/compatibility.rb
+++ b/lib/highline/compatibility.rb
@@ -4,13 +4,13 @@ unless STDIN.respond_to? :getbyte
# HighLine adds #getbyte alias to #getc when #getbyte is not available.
class IO
# alias to #getc when #getbyte is not available
- alias_method :getbyte, :getc
+ alias getbyte getc
end
# HighLine adds #getbyte alias to #getc when #getbyte is not available.
class StringIO
# alias to #getc when #getbyte is not available
- alias_method :getbyte, :getc
+ alias getbyte getc
end
end
@@ -18,6 +18,6 @@ unless "".respond_to? :each_line
# HighLine adds #each_line alias to #each when each_line is not available.
class String
# alias to #each when each_line is not available.
- alias_method :each_line, :each
+ alias each_line each
end
end
diff --git a/lib/highline/custom_errors.rb b/lib/highline/custom_errors.rb
index 2d45687..28e97df 100644
--- a/lib/highline/custom_errors.rb
+++ b/lib/highline/custom_errors.rb
@@ -1,5 +1,6 @@
-class HighLine
+# encoding: utf-8
+class HighLine
# Internal HighLine errors.
module CustomErrors
# An error that responds to :explanation_key
diff --git a/lib/highline/import.rb b/lib/highline/import.rb
index c2e6084..46cb3db 100644
--- a/lib/highline/import.rb
+++ b/lib/highline/import.rb
@@ -38,11 +38,11 @@ class Object
# @param details [lambda] block to be called with the question
# instance as argument.
# @return [String] answer
- def or_ask( *args, &details )
+ def or_ask(*args, &details)
ask(*args) do |question|
question.first_answer = String(self)
- details.call(question) if details
+ yield(question) if details
end
end
end
diff --git a/lib/highline/list.rb b/lib/highline/list.rb
index 1f2af2c..6ca876f 100644
--- a/lib/highline/list.rb
+++ b/lib/highline/list.rb
@@ -1,10 +1,8 @@
# coding: utf-8
class HighLine
-
# List class with some convenience methods like {#col_down}.
class List
-
# Original given *items* argument.
# It's frozen at initialization time and
# all later transformations will happen on {#list}.
@@ -33,7 +31,6 @@ class HighLine
attr_reader :transpose_mode
-
# Content are distributed first by column in col down mode.
# @return [Boolean]
#
@@ -69,7 +66,8 @@ class HighLine
build
end
- # Transpose the (already sliced by rows) list, turning its rows into columns.
+ # Transpose the (already sliced by rows) list,
+ # turning its rows into columns.
# @return [self]
def transpose
first_row = @list[0]
@@ -141,9 +139,7 @@ class HighLine
# Set the {#row_join_string}.
# @see #row_join_string
- def row_join_string=(string)
- @row_join_string = string
- end
+ attr_writer :row_join_string
# Returns the row join string size.
# Useful for calculating the actual size of
@@ -178,4 +174,4 @@ class HighLine
row.compact.join(row_join_string) + "\n"
end
end
-end \ No newline at end of file
+end
diff --git a/lib/highline/list_renderer.rb b/lib/highline/list_renderer.rb
index fde6ad4..cc53bf0 100644
--- a/lib/highline/list_renderer.rb
+++ b/lib/highline/list_renderer.rb
@@ -1,251 +1,257 @@
# coding: utf-8
-require 'highline/template_renderer'
-require 'highline/wrapper'
-require 'highline/list'
-
-#
-# This class is a utility for quickly and easily laying out lists
-# to be used by HighLine.
-#
-class HighLine::ListRenderer
- # Items list
- # @return [Array]
- attr_reader :items
-
- # @return [Symbol] the current mode the List is being rendered
- # @see #initialize for more details see mode parameter of #initialize
- attr_reader :mode
-
- # Changes the behaviour of some modes. Example, in :inline mode
- # the option is treated as the 'end separator' (defaults to " or ")
- # @return option parameter that changes the behaviour of some modes.
- attr_reader :option
-
- # @return [HighLine] context
- attr_reader :highline
-
- # The only required parameters are _items_ and _highline_.
- # @param items [Array] the Array of items to list
- # @param mode [Symbol] controls how that list is formed
- # @param option has different effects, depending on the _mode_.
- # @param highline [HighLine] a HighLine instance to direct the output to.
- #
- # Recognized modes are:
+require "highline/template_renderer"
+require "highline/wrapper"
+require "highline/list"
+
+class HighLine
#
- # <tt>:columns_across</tt>:: _items_ will be placed in columns,
- # flowing from left to right. If given,
- # _option_ is the number of columns to be
- # used. When absent, columns will be
- # determined based on _wrap_at_ or a
- # default of 80 characters.
- # <tt>:columns_down</tt>:: Identical to <tt>:columns_across</tt>,
- # save flow goes down.
- # <tt>:uneven_columns_across</tt>:: Like <tt>:columns_across</tt> but each
- # column is sized independently.
- # <tt>:uneven_columns_down</tt>:: Like <tt>:columns_down</tt> but each
- # column is sized independently.
- # <tt>:inline</tt>:: All _items_ are placed on a single line.
- # The last two _items_ are separated by
- # _option_ or a default of " or ". All
- # other _items_ are separated by ", ".
- # <tt>:rows</tt>:: The default mode. Each of the _items_ is
- # placed on its own line. The _option_
- # parameter is ignored in this mode.
+ # This class is a utility for quickly and easily laying out lists
+ # to be used by HighLine.
#
- # Each member of the _items_ Array is passed through ERb and thus can contain
- # their own expansions. Color escape expansions do not contribute to the
- # final field width.
-
- def initialize(items, mode = :rows, option = nil, highline)
- @highline = highline
- @mode = mode
- @option = option
- @items = render_list_items(items)
- end
+ class ListRenderer
+ # Items list
+ # @return [Array]
+ attr_reader :items
+
+ # @return [Symbol] the current mode the List is being rendered
+ # @see #initialize for more details see mode parameter of #initialize
+ attr_reader :mode
+
+ # Changes the behaviour of some modes. Example, in :inline mode
+ # the option is treated as the 'end separator' (defaults to " or ")
+ # @return option parameter that changes the behaviour of some modes.
+ attr_reader :option
+
+ # @return [HighLine] context
+ attr_reader :highline
+
+ # The only required parameters are _items_ and _highline_.
+ # @param items [Array] the Array of items to list
+ # @param mode [Symbol] controls how that list is formed
+ # @param option has different effects, depending on the _mode_.
+ # @param highline [HighLine] a HighLine instance to direct the output to.
+ #
+ # Recognized modes are:
+ #
+ # <tt>:columns_across</tt>:: _items_ will be placed in columns,
+ # flowing from left to right. If given,
+ # _option_ is the number of columns to be
+ # used. When absent, columns will be
+ # determined based on _wrap_at_ or a
+ # default of 80 characters.
+ # <tt>:columns_down</tt>:: Identical to <tt>:columns_across</tt>,
+ # save flow goes down.
+ # <tt>:uneven_columns_across</tt>:: Like <tt>:columns_across</tt> but each
+ # column is sized independently.
+ # <tt>:uneven_columns_down</tt>:: Like <tt>:columns_down</tt> but each
+ # column is sized independently.
+ # <tt>:inline</tt>:: All _items_ are placed on a single
+ # line. The last two _items_ are
+ # separated by _option_ or a default of
+ # " or ". All other _items_ are
+ # separated by ", ".
+ # <tt>:rows</tt>:: The default mode. Each of the _items_
+ # is placed on its own line. The _option_
+ # parameter is ignored in this mode.
+ #
+ # Each member of the _items_ Array is passed through ERb and thus can
+ # contain their own expansions. Color escape expansions do not contribute to
+ # the final field width.
+
+ def initialize(items, mode = :rows, option = nil, highline)
+ @highline = highline
+ @mode = mode
+ @option = option
+ @items = render_list_items(items)
+ end
- # Render the list using the appropriate mode and options.
- # @return [String] rendered list as String
- def render
- return "" if items.empty?
-
- case mode
- when :inline
- list_inline_mode
- when :columns_across
- list_columns_across_mode
- when :columns_down
- list_columns_down_mode
- when :uneven_columns_across
- list_uneven_columns_mode
- when :uneven_columns_down
- list_uneven_columns_down_mode
- else
- list_default_mode
+ # Render the list using the appropriate mode and options.
+ # @return [String] rendered list as String
+ def render
+ return "" if items.empty?
+
+ case mode
+ when :inline
+ list_inline_mode
+ when :columns_across
+ list_columns_across_mode
+ when :columns_down
+ list_columns_down_mode
+ when :uneven_columns_across
+ list_uneven_columns_mode
+ when :uneven_columns_down
+ list_uneven_columns_down_mode
+ else
+ list_default_mode
+ end
end
- end
- private
+ private
- def render_list_items(items)
- items.to_ary.map do |item|
- item = String(item)
- template = ERB.new(item, nil, "%")
- template_renderer = HighLine::TemplateRenderer.new(template, self, highline)
- template_renderer.render
+ def render_list_items(items)
+ items.to_ary.map do |item|
+ item = String(item)
+ template = ERB.new(item, nil, "%")
+ template_renderer =
+ HighLine::TemplateRenderer.new(template, self, highline)
+ template_renderer.render
+ end
end
- end
- def list_default_mode
- items.map { |i| "#{i}\n" }.join
- end
+ def list_default_mode
+ items.map { |i| "#{i}\n" }.join
+ end
- def list_inline_mode
- end_separator = option || " or "
+ def list_inline_mode
+ end_separator = option || " or "
- if items.size == 1
- items.first
- else
- items[0..-2].join(", ") + "#{end_separator}#{items.last}"
+ if items.size == 1
+ items.first
+ else
+ items[0..-2].join(", ") + "#{end_separator}#{items.last}"
+ end
end
- end
- def list_columns_across_mode
- HighLine::List.new(right_padded_items, cols: col_count).to_s
- end
+ def list_columns_across_mode
+ HighLine::List.new(right_padded_items, cols: col_count).to_s
+ end
- def list_columns_down_mode
- HighLine::List.new(right_padded_items, cols: col_count, col_down: true).to_s
- end
+ def list_columns_down_mode
+ HighLine::List.new(
+ right_padded_items,
+ cols: col_count,
+ col_down: true
+ ).to_s
+ end
- def list_uneven_columns_mode(list=nil)
- list ||= HighLine::List.new(items)
+ def list_uneven_columns_mode(list = nil)
+ list ||= HighLine::List.new(items)
- col_max = option || items.size
- col_max.downto(1) do |column_count|
- list.cols = column_count
- widths = get_col_widths(list)
+ col_max = option || items.size
+ col_max.downto(1) do |column_count|
+ list.cols = column_count
+ widths = get_col_widths(list)
- if column_count == 1 or # last guess
- inside_line_size_limit?(widths) or # good guess
- option # defined by user
- return pad_uneven_rows(list, widths)
+ if column_count == 1 || # last guess
+ inside_line_size_limit?(widths) || # good guess
+ option # defined by user
+ return pad_uneven_rows(list, widths)
+ end
end
end
- end
- def list_uneven_columns_down_mode
- list = HighLine::List.new(items, col_down: true)
- list_uneven_columns_mode(list)
- end
+ def list_uneven_columns_down_mode
+ list = HighLine::List.new(items, col_down: true)
+ list_uneven_columns_mode(list)
+ end
- def pad_uneven_rows(list, widths)
- right_padded_list = Array(list).map do |row|
- right_pad_row(row.compact, widths)
+ def pad_uneven_rows(list, widths)
+ right_padded_list = Array(list).map do |row|
+ right_pad_row(row.compact, widths)
+ end
+ stringfy_list(right_padded_list)
end
- stringfy_list(right_padded_list)
- end
- def stringfy_list(list)
- list.map { |row| row_to_s(row) }.join
- end
+ def stringfy_list(list)
+ list.map { |row| row_to_s(row) }.join
+ end
- def row_to_s(row)
- row.compact.join(row_join_string) + "\n"
- end
+ def row_to_s(row)
+ row.compact.join(row_join_string) + "\n"
+ end
- def right_pad_row(row, widths)
- row.zip(widths).map do |field, width|
- right_pad_field(field, width)
+ def right_pad_row(row, widths)
+ row.zip(widths).map do |field, width|
+ right_pad_field(field, width)
+ end
end
- end
- def right_pad_field(field, width)
- field = String(field) # nil protection
- pad_size = width - actual_length(field)
- field + (pad_char * pad_size)
- end
+ def right_pad_field(field, width)
+ field = String(field) # nil protection
+ pad_size = width - actual_length(field)
+ field + (pad_char * pad_size)
+ end
- def get_col_widths(lines)
- lines = transpose(lines)
- get_segment_widths(lines)
- end
+ def get_col_widths(lines)
+ lines = transpose(lines)
+ get_segment_widths(lines)
+ end
- def get_row_widths(lines)
- get_segment_widths(lines)
- end
+ def get_row_widths(lines)
+ get_segment_widths(lines)
+ end
- def get_segment_widths(lines)
- lines.map do |col|
- actual_lengths_for(col).max
+ def get_segment_widths(lines)
+ lines.map do |col|
+ actual_lengths_for(col).max
+ end
end
- end
- def actual_lengths_for(line)
- line.map do |item|
- actual_length(item)
+ def actual_lengths_for(line)
+ line.map do |item|
+ actual_length(item)
+ end
end
- end
- def transpose(lines)
- lines = Array(lines)
- first_line = lines.shift
- first_line.zip(*lines)
- end
+ def transpose(lines)
+ lines = Array(lines)
+ first_line = lines.shift
+ first_line.zip(*lines)
+ end
- def inside_line_size_limit?(widths)
- line_size = widths.inject(0) { |sum, n| sum + n + row_join_str_size }
- line_size <= line_size_limit + row_join_str_size
- end
+ def inside_line_size_limit?(widths)
+ line_size = widths.reduce(0) { |sum, n| sum + n + row_join_str_size }
+ line_size <= line_size_limit + row_join_str_size
+ end
- def actual_length(text)
- HighLine::Wrapper.actual_length text
- end
+ def actual_length(text)
+ HighLine::Wrapper.actual_length text
+ end
- def items_max_length
- @items_max_length ||= max_length(items)
- end
+ def items_max_length
+ @items_max_length ||= max_length(items)
+ end
- def max_length(items)
- items.map { |item| actual_length(item) }.max
- end
+ def max_length(items)
+ items.map { |item| actual_length(item) }.max
+ end
- def line_size_limit
- @line_size_limit ||= ( highline.wrap_at || 80 )
- end
+ def line_size_limit
+ @line_size_limit ||= (highline.wrap_at || 80)
+ end
- def row_join_string
- @row_join_string ||= " "
- end
+ def row_join_string
+ @row_join_string ||= " "
+ end
- def row_join_string=(string)
- @row_join_string = string
- end
+ attr_writer :row_join_string
- def row_join_str_size
- row_join_string.size
- end
+ def row_join_str_size
+ row_join_string.size
+ end
- def get_col_count
- (line_size_limit + row_join_str_size) /
- (items_max_length + row_join_str_size)
- end
+ def col_count_calculate
+ (line_size_limit + row_join_str_size) /
+ (items_max_length + row_join_str_size)
+ end
- def col_count
- option || get_col_count
- end
+ def col_count
+ option || col_count_calculate
+ end
- def right_padded_items
- items.map do |item|
- right_pad_field(item, items_max_length)
+ def right_padded_items
+ items.map do |item|
+ right_pad_field(item, items_max_length)
+ end
end
- end
- def pad_char
- " "
- end
+ def pad_char
+ " "
+ end
- def row_count
- (items.count / col_count.to_f).ceil
+ def row_count
+ (items.count / col_count.to_f).ceil
+ end
end
-end \ No newline at end of file
+end
diff --git a/lib/highline/menu.rb b/lib/highline/menu.rb
index e1834ef..5f73cd7 100644
--- a/lib/highline/menu.rb
+++ b/lib/highline/menu.rb
@@ -13,7 +13,8 @@ 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.
#
@@ -21,16 +22,16 @@ class HighLine
# 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
#
@@ -53,10 +54,10 @@ class HighLine
# 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
@@ -75,13 +76,13 @@ class HighLine
@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
#
@@ -179,26 +180,27 @@ class HighLine
# 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)
@@ -206,8 +208,8 @@ class HighLine
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]
@@ -223,7 +225,8 @@ class HighLine
# 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)
@@ -231,7 +234,7 @@ class HighLine
# 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
@@ -242,7 +245,7 @@ class HighLine
# @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)
@@ -263,31 +266,36 @@ class HighLine
# _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?
@@ -302,11 +310,11 @@ class HighLine
# 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
@@ -339,14 +347,14 @@ class HighLine
# 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
@@ -387,12 +395,14 @@ class HighLine
# 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
@@ -423,18 +433,20 @@ class HighLine
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
@@ -451,7 +463,7 @@ class HighLine
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
@@ -512,23 +524,23 @@ class HighLine
# 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
@@ -536,11 +548,11 @@ class HighLine
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
#
diff --git a/lib/highline/menu/item.rb b/lib/highline/menu/item.rb
index 76e1e56..78594cf 100644
--- a/lib/highline/menu/item.rb
+++ b/lib/highline/menu/item.rb
@@ -1,3 +1,5 @@
+# encoding: utf-8
+
class HighLine
class Menu < Question
# Represents an Item of a HighLine::Menu.
diff --git a/lib/highline/paginator.rb b/lib/highline/paginator.rb
index 48792af..9da8735 100644
--- a/lib/highline/paginator.rb
+++ b/lib/highline/paginator.rb
@@ -3,7 +3,6 @@
class HighLine
# Take the task of paginating some piece of text given a HighLine context
class Paginator
-
# @return [HighLine] HighLine context
attr_reader :highline
@@ -36,18 +35,18 @@ class HighLine
# Return last line if user wants to abort paging
return "...\n#{lines.last}" unless continue_paging?
end
- return lines.join
+ lines.join
end
#
- # Ask user if they wish to continue paging output. Allows them to type "q" to
- # cancel the paging process.
+ # Ask user if they wish to continue paging output. Allows them to
+ # type "q" to cancel the paging process.
#
def continue_paging?
command = highline.new_scope.ask(
"-- press enter/return to continue or q to stop -- "
) { |q| q.character = true }
- command !~ /\A[qQ]\Z/ # Only continue paging if Q was not hit.
+ command !~ /\A[qQ]\Z/ # Only continue paging if Q was not hit.
end
end
-end \ No newline at end of file
+end
diff --git a/lib/highline/question.rb b/lib/highline/question.rb
index 4f9560c..f93d4d1 100755
--- a/lib/highline/question.rb
+++ b/lib/highline/question.rb
@@ -8,6 +8,7 @@
#
# This is Free Software. See LICENSE and COPYING for details.
+require "English"
require "optparse"
require "date"
require "pathname"
@@ -59,11 +60,11 @@ class HighLine
@case = nil
@in = nil
@first_answer = nil
- @directory = Pathname.new(File.expand_path(File.dirname($0)))
@glob = "*"
- @user_responses = Hash.new
- @internal_responses = default_responses_hash
@overwrite = false
+ @user_responses = {}
+ @internal_responses = default_responses_hash
+ @directory = Pathname.new(File.expand_path(File.dirname($PROGRAM_NAME)))
# allow block to override settings
yield self if block_given?
@@ -148,11 +149,11 @@ class HighLine
#
# Asks a yes or no confirmation question, to ensure a user knows what
# they have just agreed to. The confirm attribute can be set to :
- # +true+ : In this case the question will be, "Are you sure?".
- # Proc : The Proc is yielded the answer given. The Proc must
- # output a string which is then used as the confirm
- # question.
- # String : The String must use ERB syntax. The String is
+ # +true+ : In this case the question will be, "Are you sure?".
+ # Proc : The Proc is yielded the answer given. The Proc must
+ # output a string which is then used as the confirm
+ # question.
+ # String : The String must use ERB syntax. The String is
# evaluated with access to question and answer and
# is then used as the confirm question.
# When set to +false+ or +nil+ (the default), answers are not confirmed.
@@ -261,8 +262,8 @@ class HighLine
def default_responses_hash
{
- :ask_on_error => "? ",
- :mismatch => "Your entries didn't match."
+ ask_on_error: "? ",
+ mismatch: "Your entries didn't match."
}
end
@@ -270,15 +271,15 @@ class HighLine
# @param message_source (see #build_responses)
# @return [Hash] responses hash
def build_responses_new_hash(message_source)
- { :ambiguous_completion => "Ambiguous choice. Please choose one of " +
- choice_error_str(message_source) + '.',
- :invalid_type => "You must enter a valid #{message_source}.",
- :no_completion => "You must choose one of " +
- choice_error_str(message_source) + '.',
- :not_in_range => "Your answer isn't within the expected range " +
- "(#{expected_range}).",
- :not_valid => "Your answer isn't valid (must match " +
- "#{validate.inspect})." }
+ { ambiguous_completion: "Ambiguous choice. Please choose one of " +
+ choice_error_str(message_source) + ".",
+ invalid_type: "You must enter a valid #{message_source}.",
+ no_completion: "You must choose one of " +
+ choice_error_str(message_source) + ".",
+ not_in_range: "Your answer isn't within the expected range " \
+ "(#{expected_range}).",
+ not_valid: "Your answer isn't valid (must match " \
+ "#{validate.inspect})." }
end
# This is the actual responses hash that gets used in determining output
@@ -369,7 +370,7 @@ class HighLine
# Returns an English explanation of the current range settings.
def expected_range
- expected = [ ]
+ expected = []
expected << "above #{above}" if above
expected << "below #{below}" if below
@@ -392,7 +393,7 @@ class HighLine
# Returns true if _first_answer_ is set.
def first_answer?
- !!@first_answer
+ true if @first_answer
end
#
@@ -402,9 +403,9 @@ class HighLine
# are not checked.
#
def in_range?
- (!above or answer > above) and
- (!below or answer < below) and
- (!@in or @in.include?(answer))
+ (!above || answer > above) &&
+ (!below || answer < below) &&
+ (!@in || @in.include?(answer))
end
#
@@ -468,7 +469,7 @@ class HighLine
File.basename(file)
end
else
- [ ]
+ []
end
end
@@ -485,9 +486,9 @@ class HighLine
# and case handling.
#
def valid_answer?
- !validate or
- (validate.is_a?(Regexp) and answer =~ validate) or
- (validate.is_a?(Proc) and validate[answer])
+ !validate ||
+ (validate.is_a?(Regexp) && answer =~ validate) ||
+ (validate.is_a?(Proc) && validate[answer])
end
#
@@ -534,11 +535,11 @@ class HighLine
if confirm == true
"Are you sure? "
elsif confirm.is_a?(Proc)
- confirm.call(self.answer)
+ confirm.call(answer)
else
# evaluate ERb under initial scope, so it will have
# access to question and answer
- template = ERB.new(confirm, nil, "%")
+ template = ERB.new(confirm, nil, "%")
template_renderer = TemplateRenderer.new(template, self, highline)
template_renderer.render
end
@@ -547,7 +548,8 @@ class HighLine
# Provides the String to be asked when at an error situation.
# It may be just the question itself (repeat on error).
# @return [self] if :ask_on_error on responses Hash is set to :question
- # @return [String] if :ask_on_error on responses Hash is set to something else
+ # @return [String] if :ask_on_error on responses Hash is set to
+ # something else
def ask_on_error_msg
if final_responses[:ask_on_error] == :question
self
@@ -564,7 +566,7 @@ class HighLine
# @param highline [HighLine] context
# @return [void]
def show_question(highline)
- highline.say(self) unless (readline && (echo == true && !limit))
+ highline.say(self) unless readline && (echo == true && !limit)
end
# Returns an echo string that is adequate for this Question settings.
@@ -577,7 +579,7 @@ class HighLine
if echo == true
response
# any truethy value, probably a String
- elsif !!echo
+ elsif echo
echo
# any falsy value, false or nil
else
@@ -594,11 +596,11 @@ class HighLine
#
def append_default
if template =~ /([\t ]+)\Z/
- template << "|#{default}|#{$1}"
+ template << "|#{default}|#{Regexp.last_match(1)}"
elsif template == ""
template << "|#{default}| "
elsif template[-1, 1] == "\n"
- template[-2, 0] = " |#{default}|"
+ template[-2, 0] = " |#{default}|"
else
template << " |#{default}|"
end
@@ -606,7 +608,7 @@ class HighLine
def choice_error_str(message_source)
if message_source.is_a? Array
- '[' + message_source.join(', ') + ']'
+ "[" + message_source.join(", ") + "]"
else
message_source.inspect
end
diff --git a/lib/highline/question/answer_converter.rb b/lib/highline/question/answer_converter.rb
index d4067f1..76558ae 100644
--- a/lib/highline/question/answer_converter.rb
+++ b/lib/highline/question/answer_converter.rb
@@ -1,6 +1,6 @@
# coding: utf-8
-require 'forwardable'
+require "forwardable"
class HighLine
class Question
@@ -100,4 +100,4 @@ class HighLine
end
end
end
-end \ No newline at end of file
+end
diff --git a/lib/highline/question_asker.rb b/lib/highline/question_asker.rb
index 06e6647..cb8dfa8 100644
--- a/lib/highline/question_asker.rb
+++ b/lib/highline/question_asker.rb
@@ -1,3 +1,5 @@
+# encoding: utf-8
+
class HighLine
# Deals with the task of "asking" a question
class QuestionAsker
@@ -31,13 +33,12 @@ class HighLine
question.convert
if question.confirm
- raise NoConfirmationQuestionError unless @highline.send(:confirm, question)
+ confirmation = @highline.send(:confirm, question)
+ raise NoConfirmationQuestionError unless confirmation
end
-
rescue ExplainableError => e
explain_error(e.explanation_key)
retry
-
rescue ArgumentError => error
case error.message
when /ambiguous/
@@ -65,29 +66,27 @@ class HighLine
#
# @return [Array, Hash] answers
def gather_answers
- original_question_template = question.template
verify_match = question.verify_match
+ answers = []
- begin # when verify_match is set this loop will repeat until unique_answers == 1
- question.template = original_question_template
-
+ # when verify_match is set this loop will repeat until unique_answers == 1
+ loop do
answers = gather_answers_based_on_type
- if verify_match && (@highline.send(:unique_answers, answers).size > 1)
- explain_error(:mismatch)
- else
- verify_match = false
- end
- end while verify_match
+ break unless verify_match &&
+ (@highline.send(:unique_answers, answers).size > 1)
+
+ explain_error(:mismatch)
+ end
- question.verify_match ? @highline.send(:last_answer, answers) : answers
+ verify_match ? @highline.send(:last_answer, answers) : answers
end
# Gather multiple integer values based on {Question#gather} count
# @return [Array] answers
def gather_integer
gather_with_array do |answers|
- (question.gather-1).times { answers << ask_once }
+ (question.gather - 1).times { answers << ask_once }
end
end
@@ -112,7 +111,6 @@ class HighLine
end
end
-
private
## Delegate to Highline
@@ -133,7 +131,7 @@ class HighLine
def answer_matches_regex(answer)
if question.gather.is_a?(::String) || question.gather.is_a?(Symbol)
answer.to_s == question.gather.to_s
- else question.gather.is_a?(Regexp)
+ elsif question.gather.is_a?(Regexp)
answer.to_s =~ question.gather
end
end
diff --git a/lib/highline/simulate.rb b/lib/highline/simulate.rb
index c1ee6df..f92eaa3 100644
--- a/lib/highline/simulate.rb
+++ b/lib/highline/simulate.rb
@@ -10,12 +10,9 @@
#
# adapted from https://gist.github.com/194554
-
class HighLine
-
# Simulates Highline input for use in tests.
class Simulate
-
# Creates a simulator with an array of Strings as a script
# @param strings [Array<String>] preloaded string to be used
# as input buffer when simulating.
@@ -28,14 +25,15 @@ class HighLine
@strings.shift
end
- # Simulate StringIO#getbyte by shifting a single character off of the next line of the script
+ # Simulate StringIO#getbyte by shifting a single character off of
+ # the next line of the script
def getbyte
line = gets
- if line.length > 0
- char = line.slice! 0
- @strings.unshift line
- char
- end
+ return if line.empty?
+
+ char = line.slice! 0
+ @strings.unshift line
+ char
end
# The simulator handles its own EOF
diff --git a/lib/highline/statement.rb b/lib/highline/statement.rb
index 5e6e2f2..35d7961 100644
--- a/lib/highline/statement.rb
+++ b/lib/highline/statement.rb
@@ -1,8 +1,8 @@
# coding: utf-8
-require 'highline/wrapper'
-require 'highline/paginator'
-require 'highline/template_renderer'
+require "highline/wrapper"
+require "highline/paginator"
+require "highline/template_renderer"
class HighLine
# This class handles proper formatting based
@@ -45,6 +45,10 @@ class HighLine
statement
end
+ def self.const_missing(constant)
+ HighLine.const_get(constant)
+ end
+
private
def stringfy(template_string)
@@ -52,14 +56,16 @@ class HighLine
end
def format_statement
- return template_string unless template_string.length > 0
+ return template_string if template_string.empty?
statement = render_template
statement = HighLine::Wrapper.wrap(statement, highline.wrap_at)
statement = HighLine::Paginator.new(highline).page_print(statement)
- statement = statement.gsub(/\n(?!$)/,"\n#{highline.indentation}") if highline.multi_indent
+ statement = statement.gsub(/\n(?!$)/, "\n#{highline.indentation}") if
+ highline.multi_indent
+
statement
end
@@ -74,9 +80,5 @@ class HighLine
def template
@template ||= ERB.new(template_string, nil, "%")
end
-
- def self.const_missing(constant)
- HighLine.const_get(constant)
- end
end
-end \ No newline at end of file
+end
diff --git a/lib/highline/string.rb b/lib/highline/string.rb
index 162cfeb..8d2e0a6 100644
--- a/lib/highline/string.rb
+++ b/lib/highline/string.rb
@@ -3,12 +3,13 @@
require "highline/string_extensions"
class HighLine
-
#
- # HighLine::String is a subclass of String with convenience methods added for colorization.
+ # HighLine::String is a subclass of String with convenience methods added
+ # for colorization.
#
# Available convenience methods include:
- # * 'color' method e.g. highline_string.color(:bright_blue, :underline)
+ # * 'color' method e.g. highline_string.color(:bright_blue,
+ # :underline)
# * colors e.g. highline_string.magenta
# * RGB colors e.g. highline_string.rgb_ff6000
# or highline_string.rgb(255,96,0)
@@ -17,19 +18,19 @@ class HighLine
# or highline_string.on_rgb(255,96,0)
# * styles e.g. highline_string.underline
#
- # Additionally, convenience methods can be chained, for instance the following are equivalent:
+ # Additionally, convenience methods can be chained, for instance the
+ # following are equivalent:
# highline_string.bright_blue.blink.underline
# highline_string.color(:bright_blue, :blink, :underline)
# HighLine.color(highline_string, :bright_blue, :blink, :underline)
#
- # For those less squeamish about possible conflicts, the same convenience methods can be
- # added to the built-in String class, as follows:
+ # For those less squeamish about possible conflicts, the same convenience
+ # methods can be added to the built-in String class, as follows:
#
# require 'highline'
# Highline.colorize_strings
#
-
class String < ::String
include StringExtensions
end
-end \ No newline at end of file
+end
diff --git a/lib/highline/string_extensions.rb b/lib/highline/string_extensions.rb
index d2f2de4..f6c4c6b 100644
--- a/lib/highline/string_extensions.rb
+++ b/lib/highline/string_extensions.rb
@@ -1,16 +1,18 @@
# coding: utf-8
-class HighLine
+class HighLine #:nodoc:
# Returns a HighLine::String from any given String.
# @param s [String]
# @return [HighLine::String] from the given string.
- def self.String(s)
+ def self.String(s) # rubocop:disable Naming/MethodName
HighLine::String.new(s)
end
# HighLine extensions for String class.
# Included by HighLine::String.
module StringExtensions
+ STYLE_METHOD_NAME_PATTERN = /^(on_)?rgb_([0-9a-fA-F]{6})$/
+
# Included hook. Actions to take when being included.
# @param base [Class, Module] base class
def self.included(base)
@@ -35,7 +37,7 @@ class HighLine
undef :on if method_defined? :on
def on(arg)
- color(('on_' + arg.to_s).to_sym)
+ color(("on_" + arg.to_s).to_sym)
end
undef :uncolor if method_defined? :uncolor
@@ -57,19 +59,33 @@ class HighLine
# @todo Chain existing method_missing?
undef :method_missing if method_defined? :method_missing
- def method_missing(method, *args, &blk)
- if method.to_s =~ /^(on_)?rgb_([0-9a-fA-F]{6})$/
+ def method_missing(method, *_args)
+ if method.to_s =~ STYLE_METHOD_NAME_PATTERN
color(method)
else
- raise NoMethodError, "undefined method `#{method}' for #<#{self.class}:#{'%#x'%self.object_id}>"
+ super
end
end
+ undef :respond_to_missing if method_defined? :respond_to_missing
+ def respond_to_missing?(method_name, include_private = false)
+ method_name.to_s =~ STYLE_METHOD_NAME_PATTERN || super
+ end
+
private
def setup_color_code(*colors)
- color_code = colors.map{|color| color.is_a?(Numeric) ? '%02x'%color : color.to_s}.join
- raise "Bad RGB color #{colors.inspect}" unless color_code =~ /^[a-fA-F0-9]{6}/
+ color_code = colors.map do |color|
+ if color.is_a?(Numeric)
+ format("%02x", color)
+ else
+ color.to_s
+ end
+ end.join
+
+ raise "Bad RGB color #{colors.inspect}" unless
+ color_code =~ /^[a-fA-F0-9]{6}/
+
color_code
end
end
@@ -80,28 +96,28 @@ class HighLine
def self.define_builtin_style_methods(base)
HighLine::COLORS.each do |color|
color = color.downcase
- base.class_eval <<-END
+ base.class_eval <<-METHOD_DEFINITION
undef :#{color} if method_defined? :#{color}
def #{color}
color(:#{color})
end
- END
+ METHOD_DEFINITION
- base.class_eval <<-END
+ base.class_eval <<-METHOD_DEFINITION
undef :on_#{color} if method_defined? :on_#{color}
def on_#{color}
on(:#{color})
end
- END
+ METHOD_DEFINITION
HighLine::STYLES.each do |style|
style = style.downcase
- base.class_eval <<-END
+ base.class_eval <<-METHOD_DEFINITION
undef :#{style} if method_defined? :#{style}
def #{style}
color(:#{style})
end
- END
+ METHOD_DEFINITION
end
end
end
diff --git a/lib/highline/style.rb b/lib/highline/style.rb
index c53024a..773cba0 100755
--- a/lib/highline/style.rb
+++ b/lib/highline/style.rb
@@ -8,16 +8,14 @@
#
# This is Free Software. See LICENSE and COPYING for details
-
-class HighLine
-
+class HighLine #:nodoc:
# Creates a style using {.find_or_create_style} or
# {.find_or_create_style_list}
# @param args [Array<Style, Hash, String>] style properties
# @return [Style]
def self.Style(*args)
args = args.compact.flatten
- if args.size==1
+ if args.size == 1
find_or_create_style(args.first)
else
find_or_create_style_list(*args)
@@ -33,21 +31,22 @@ class HighLine
if arg.is_a?(Style)
Style.list[arg.name] || Style.index(arg)
elsif arg.is_a?(::String) && arg =~ /^\e\[/ # arg is a code
- if styles = Style.code_index[arg]
+ styles = Style.code_index[arg]
+ if styles
styles.first
else
- Style.new(:code=>arg)
+ Style.new(code: arg)
end
- elsif style = Style.list[arg]
- style
+ elsif Style.list[arg]
+ Style.list[arg]
elsif HighLine.color_scheme && HighLine.color_scheme[arg]
HighLine.color_scheme[arg]
elsif arg.is_a?(Hash)
Style.new(arg)
elsif arg.to_s.downcase =~ /^rgb_([a-f0-9]{6})$/
- Style.rgb($1)
+ Style.rgb(Regexp.last_match(1))
elsif arg.to_s.downcase =~ /^on_rgb_([a-f0-9]{6})$/
- Style.rgb($1).on
+ Style.rgb(Regexp.last_match(1)).on
else
raise NameError, "#{arg.inspect} is not a defined Style"
end
@@ -62,12 +61,11 @@ class HighLine
def self.find_or_create_style_list(*args)
name = args
- Style.list[name] || Style.new(:list=>args)
+ Style.list[name] || Style.new(list: args)
end
# ANSI styles to be used by HighLine.
class Style
-
# Index the given style.
# Uses @code_index (Hash) as repository.
# @param style [Style]
@@ -77,10 +75,12 @@ class HighLine
@styles ||= {}
@styles[style.name] = style
end
- if !style.list
+ unless style.list
@code_index ||= {}
@code_index[style.code] ||= []
- @code_index[style.code].reject!{|indexed_style| indexed_style.name == style.name}
+ @code_index[style.code].reject! do |indexed_style|
+ indexed_style.name == style.name
+ end
@code_index[style.code] << style
end
style
@@ -91,9 +91,9 @@ class HighLine
# @return [void]
def self.clear_index
# reset to builtin only styles
- @styles = list.select { |name, style| style.builtin }
+ @styles = list.select { |_name, style| style.builtin }
@code_index = {}
- @styles.each { |name, style| index(style) }
+ @styles.each_value { |style| index(style) }
end
# Converts all given color codes to hexadecimal and
@@ -106,7 +106,7 @@ class HighLine
# HighLine::Style.rgb_hex(9, 10, "11") # => "090a11"
def self.rgb_hex(*colors)
colors.map do |color|
- color.is_a?(Numeric) ? '%02x'%color : color.to_s
+ color.is_a?(Numeric) ? format("%02x", color) : color.to_s
end.join
end
@@ -117,7 +117,7 @@ class HighLine
# HighLine::Style.rgb_parts("090A0B") # => [9, 10, 11]
def self.rgb_parts(hex)
- hex.scan(/../).map{|part| part.to_i(16)}
+ hex.scan(/../).map { |part| part.to_i(16) }
end
# Search for or create a new Style from the colors provided.
@@ -132,29 +132,37 @@ class HighLine
#
def self.rgb(*colors)
hex = rgb_hex(*colors)
- name = ('rgb_' + hex).to_sym
- if style = list[name]
- style
- else
- parts = rgb_parts(hex)
- new(:name=>name, :code=>"\e[38;5;#{rgb_number(parts)}m", :rgb=>parts)
- end
+ name = ("rgb_" + hex).to_sym
+ style = list[name]
+ return style if style
+
+ parts = rgb_parts(hex)
+ new(name: name, code: "\e[38;5;#{rgb_number(parts)}m", rgb: parts)
end
# Returns the rgb number to be used as escape code on ANSI terminals.
- # @param parts [Array<Numeric>] three numerical codes for red, green and blue
+ # @param parts [Array<Numeric>] three numerical codes for red, green
+ # and blue
# @return [Numeric] to be used as escape code on ANSI terminals
def self.rgb_number(*parts)
parts = parts.flatten
- 16 + parts.inject(0) {|kode, part| kode*6 + (part/256.0*6.0).floor}
+ 16 + parts.reduce(0) do |kode, part|
+ kode * 6 + (part / 256.0 * 6.0).floor
+ end
end
# From an ANSI number (color escape code), craft an 'rgb_hex' code of it
# @param ansi_number [Integer] ANSI escape code
# @return [String] all color codes joined as {.rgb_hex}
def self.ansi_rgb_to_hex(ansi_number)
- raise "Invalid ANSI rgb code #{ansi_number}" unless (16..231).include?(ansi_number)
- parts = (ansi_number-16).to_s(6).rjust(3,'0').scan(/./).map{|d| (d.to_i*255.0/6.0).ceil}
+ raise "Invalid ANSI rgb code #{ansi_number}" unless
+ (16..231).cover?(ansi_number)
+ parts = (ansi_number - 16).
+ to_s(6).
+ rjust(3, "0").
+ scan(/./).
+ map { |d| (d.to_i * 255.0 / 6.0).ceil }
+
rgb_hex(*parts)
end
@@ -170,9 +178,9 @@ class HighLine
# Remove any ANSI color escape sequence of the given String.
# @param string [String]
- # @return [String]
+ # @return [String]
def self.uncolor(string)
- string.gsub(/\e\[\d+(;\d+)*m/, '')
+ string.gsub(/\e\[\d+(;\d+)*m/, "")
end
# Style name
@@ -202,7 +210,7 @@ class HighLine
@builtin = defn[:builtin]
if @rgb
hex = self.class.rgb_hex(@rgb)
- @name ||= 'rgb_' + hex
+ @name ||= "rgb_" + hex
elsif @list
@name ||= @list
end
@@ -228,11 +236,12 @@ class HighLine
code + string + HighLine::CLEAR
end
- # @return [String] all codes of the Style list joined together (if a Style list)
+ # @return [String] all codes of the Style list joined together
+ # (if a Style list)
# @return [String] the Style code
def code
if @list
- @list.map{|element| HighLine.Style(element).code}.join
+ @list.map { |element| HighLine.Style(element).code }.join
else
@code
end
@@ -257,22 +266,30 @@ class HighLine
# @param new_name [Symbol]
# @param options [Hash] Style attributes to be changed
# @return [Style] new Style with changed attributes
- def variant(new_name, options={})
+ def variant(new_name, options = {})
raise "Cannot create a variant of a style list (#{inspect})" if @list
new_code = options[:code] || code
if options[:increment]
- raise "Unexpected code in #{inspect}" unless new_code =~ /^(.*?)(\d+)(.*)/
- new_code = $1 + ($2.to_i + options[:increment]).to_s + $3
+ raise "Unexpected code in #{inspect}" unless
+ new_code =~ /^(.*?)(\d+)(.*)/
+
+ new_code =
+ Regexp.last_match(1) +
+ (Regexp.last_match(2).to_i +
+ options[:increment]).to_s +
+ Regexp.last_match(3)
end
new_rgb = options[:rgb] || @rgb
- self.class.new(self.to_hash.merge(:name=>new_name, :code=>new_code, :rgb=>new_rgb))
+ self.class.new(to_hash.merge(name: new_name,
+ code: new_code,
+ rgb: new_rgb))
end
# Uses the color as background and return a new style.
# @return [Style]
def on
- new_name = ('on_'+@name.to_s).to_sym
- self.class.list[new_name] ||= variant(new_name, :increment=>10)
+ new_name = ("on_" + @name.to_s).to_sym
+ self.class.list[new_name] ||= variant(new_name, increment: 10)
end
# @return [Style] a brighter version of this Style
@@ -288,11 +305,17 @@ class HighLine
private
def create_bright_variant(variant_name)
- raise "Cannot create a #{name} variant of a style list (#{inspect})" if @list
- new_name = ("#{variant_name}_"+@name.to_s).to_sym
- new_rgb = @rgb == [0,0,0] ? [128, 128, 128] : @rgb.map {|color| color==0 ? 0 : [color+128,255].min }
-
- find_style(new_name) or variant(new_name, :increment=>60, :rgb=>new_rgb)
+ raise "Cannot create a #{name} variant of a style list (#{inspect})" if
+ @list
+ new_name = ("#{variant_name}_" + @name.to_s).to_sym
+ new_rgb =
+ if @rgb == [0, 0, 0]
+ [128, 128, 128]
+ else
+ @rgb.map { |color| color.zero? ? 0 : [color + 128, 255].min }
+ end
+
+ find_style(new_name) || variant(new_name, increment: 60, rgb: new_rgb)
end
def find_style(name)
diff --git a/lib/highline/template_renderer.rb b/lib/highline/template_renderer.rb
index 9ac3970..e948c06 100644
--- a/lib/highline/template_renderer.rb
+++ b/lib/highline/template_renderer.rb
@@ -1,6 +1,6 @@
# coding: utf-8
-require 'forwardable'
+require "forwardable"
class HighLine
# Renders an erb template taking a {Question} and a {HighLine} instance
@@ -42,9 +42,9 @@ class HighLine
# is not available.
# @return [String] error message.
def method_missing(method, *args)
- "Method #{method} with args #{args.inspect} " +
- "is not available on #{self.inspect}. " +
- "Try #{methods(false).sort.inspect}"
+ "Method #{method} with args #{args.inspect} " \
+ "is not available on #{inspect}. " \
+ "Try #{methods(false).sort.inspect}"
end
# @return [Question, Menu] {#source} attribute.
@@ -59,4 +59,4 @@ class HighLine
HighLine.const_get(name)
end
end
-end \ No newline at end of file
+end
diff --git a/lib/highline/terminal.rb b/lib/highline/terminal.rb
index a76a136..cd1d3dc 100755
--- a/lib/highline/terminal.rb
+++ b/lib/highline/terminal.rb
@@ -16,24 +16,17 @@ class HighLine
# input and output to.
# The specialized Terminals all decend from this HighLine::Terminal class
class Terminal
-
# Probe for and return a suitable Terminal instance
# @param input [IO] input stream
# @param output [IO] output stream
def self.get_terminal(input, output)
- terminal = nil
-
# First of all, probe for io/console
begin
require "io/console"
require "highline/terminal/io_console"
terminal = HighLine::Terminal::IOConsole.new(input, output)
rescue LoadError
- end
-
- # Fall back to UnixStty
- unless terminal
- require 'highline/terminal/unix_stty'
+ require "highline/terminal/unix_stty"
terminal = HighLine::Terminal::UnixStty.new(input, output)
end
@@ -57,8 +50,7 @@ class HighLine
# An initialization callback.
# It is called by {.get_terminal}.
- def initialize_system_extensions
- end
+ def initialize_system_extensions; end
# @return [Array<Integer, Integer>] two value terminal
# size like [columns, lines]
@@ -67,8 +59,7 @@ class HighLine
end
# Enter Raw No Echo mode.
- def raw_no_echo_mode
- end
+ def raw_no_echo_mode; end
# Yieds a block to be executed in Raw No Echo mode and
# then restore the terminal state.
@@ -80,40 +71,38 @@ class HighLine
end
# Restore terminal to its default mode
- def restore_mode
- end
+ def restore_mode; end
# Get one character from the terminal
# @return [String] one character
- def get_character
- end
+ def get_character; end # rubocop:disable Naming/AccessorMethodName
# Get one line from the terminal and format accordling.
# Use readline if question has readline mode set.
# @param question [HighLine::Question]
# @param highline [HighLine]
# @param options [Hash]
- def get_line(question, highline, options={})
+ def get_line(question, highline)
raw_answer =
- if question.readline
- get_line_with_readline(question, highline, options={})
- else
- get_line_default(highline)
- end
+ if question.readline
+ get_line_with_readline(question, highline)
+ else
+ get_line_default(highline)
+ end
question.format_answer(raw_answer)
end
# Get one line using #readline_read
# @param (see #get_line)
- def get_line_with_readline(question, highline, options={})
- require "readline" # load only if needed
+ def get_line_with_readline(question, highline)
+ require "readline" # load only if needed
question_string = highline.render_statement(question)
raw_answer = readline_read(question_string, question)
- if !raw_answer and highline.track_eof?
+ if !raw_answer && highline.track_eof?
raise EOFError, "The input stream is exhausted."
end
@@ -140,7 +129,7 @@ class HighLine
Readline.readline(prompt, true)
end
- $VERBOSE = old_verbose
+ $VERBOSE = old_verbose
raw_answer
end
@@ -148,8 +137,8 @@ class HighLine
# Get one line from terminal using default #gets method.
# @param highline (see #get_line)
def get_line_default(highline)
- raise EOFError, "The input stream is exhausted." if highline.track_eof? and
- highline.input.eof?
+ raise EOFError, "The input stream is exhausted." if highline.track_eof? &&
+ highline.input.eof?
highline.input.gets
end
@@ -157,12 +146,12 @@ class HighLine
# Running on JRuby?
def jruby?
- defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
+ defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
end
# Running on Rubinius?
def rubinius?
- defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
+ defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx"
end
# Running on Windows?
@@ -190,7 +179,11 @@ class HighLine
# Saves terminal state using shell stty command.
def save_stty
- @stty_save = `stty -g`.chomp rescue nil
+ @stty_save = begin
+ `stty -g`.chomp
+ rescue StandardError
+ nil
+ end
end
# Restores terminal state using shell stty command.
diff --git a/lib/highline/terminal/io_console.rb b/lib/highline/terminal/io_console.rb
index eee152f..e9ff925 100644
--- a/lib/highline/terminal/io_console.rb
+++ b/lib/highline/terminal/io_console.rb
@@ -21,9 +21,9 @@ class HighLine
end
# (see Terminal#get_character)
- def get_character
+ def get_character # rubocop:disable Naming/AccessorMethodName
input.getch # from ruby io/console
end
end
end
-end \ No newline at end of file
+end
diff --git a/lib/highline/terminal/ncurses.rb b/lib/highline/terminal/ncurses.rb
index 817cc23..72ffac8 100644
--- a/lib/highline/terminal/ncurses.rb
+++ b/lib/highline/terminal/ncurses.rb
@@ -3,9 +3,10 @@
class HighLine
class Terminal
# NCurses HighLine::Terminal
- # @note Code migrated +UNTESTED+ from the old code base to the new terminal api.
+ # @note Code migrated +UNTESTED+ from the old code base to the new
+ # terminal api.
class NCurses < Terminal
- require 'ffi-ncurses'
+ require "ffi-ncurses"
# (see Terminal#raw_no_echo_mode)
def raw_no_echo_mode
@@ -34,4 +35,4 @@ class HighLine
end
end
end
-end \ No newline at end of file
+end
diff --git a/lib/highline/terminal/unix_stty.rb b/lib/highline/terminal/unix_stty.rb
index 3b9668a..ad9c85d 100644
--- a/lib/highline/terminal/unix_stty.rb
+++ b/lib/highline/terminal/unix_stty.rb
@@ -5,25 +5,28 @@ class HighLine
# HighLine::Terminal option that uses external "stty" program
# to control terminal options.
class UnixStty < Terminal
-
# A Unix savvy method using stty to fetch the console columns, and rows.
# ... stty does not work in JRuby
# @return (see Terminal#terminal_size)
def terminal_size
begin
require "io/console"
- winsize = IO.console.winsize.reverse rescue nil
+ winsize = begin
+ IO.console.winsize.reverse
+ rescue NoMethodError
+ nil
+ end
return winsize if winsize
rescue LoadError
end
- if /solaris/ =~ RUBY_PLATFORM and
- `stty` =~ /\brows = (\d+).*\bcolumns = (\d+)/
- [$2, $1].map { |x| x.to_i }
+ if /solaris/ =~ RUBY_PLATFORM &&
+ `stty` =~ /\brows = (\d+).*\bcolumns = (\d+)/
+ [Regexp.last_match(2), Regexp.last_match(1)].map(&:to_i)
elsif `stty size` =~ /^(\d+)\s(\d+)$/
- [$2.to_i, $1.to_i]
+ [Regexp.last_match(2).to_i, Regexp.last_match(1).to_i]
else
- [ 80, 24 ]
+ [80, 24]
end
end
@@ -40,9 +43,9 @@ class HighLine
end
# (see Terminal#get_character)
- def get_character( input = STDIN )
+ def get_character(input = STDIN)
input.getc
end
end
end
-end \ No newline at end of file
+end
diff --git a/lib/highline/version.rb b/lib/highline/version.rb
index 5b6b4f8..87be435 100644
--- a/lib/highline/version.rb
+++ b/lib/highline/version.rb
@@ -2,5 +2,5 @@
class HighLine
# The version of the installed library.
- VERSION = "2.0.0-develop.10".freeze
+ VERSION = "2.0.0-develop.11".freeze
end
diff --git a/lib/highline/wrapper.rb b/lib/highline/wrapper.rb
index ae93db6..a2ab4ac 100644
--- a/lib/highline/wrapper.rb
+++ b/lib/highline/wrapper.rb
@@ -1,12 +1,12 @@
# coding: utf-8
-class HighLine
+require "English"
+class HighLine
# A simple Wrapper module that is aware of ANSI escape codes.
# It compensates for the ANSI escape codes so it works on the
# actual (visual) line length.
module Wrapper
-
#
# Wrap a sequence of _lines_ at _wrap_at_ characters per line. Existing
# newlines will not be affected by this process, but additional newlines
@@ -18,24 +18,25 @@ class HighLine
return text unless wrap_at
wrap_at = Integer(wrap_at)
- wrapped = [ ]
+ wrapped = []
text.each_line do |line|
# take into account color escape sequences when wrapping
- wrap_at = wrap_at + (line.length - actual_length(line))
+ wrap_at += (line.length - actual_length(line))
while line =~ /([^\n]{#{wrap_at + 1},})/
- search = $1.dup
- replace = $1.dup
- if index = replace.rindex(" ", wrap_at)
+ search = Regexp.last_match(1).dup
+ replace = Regexp.last_match(1).dup
+ index = replace.rindex(" ", wrap_at)
+ if index
replace[index, 1] = "\n"
replace.sub!(/\n[ \t]+/, "\n")
line.sub!(search, replace)
else
- line[$~.begin(1) + wrap_at, 0] = "\n"
+ line[$LAST_MATCH_INFO.begin(1) + wrap_at, 0] = "\n"
end
end
wrapped << line
end
- return wrapped.join
+ wrapped.join
end
#
@@ -45,8 +46,8 @@ class HighLine
# @param string_with_escapes [String] any ANSI colored String
# @return [Integer] length based on the visual size of the String
# (without the escape codes)
- def self.actual_length( string_with_escapes )
+ def self.actual_length(string_with_escapes)
string_with_escapes.to_s.gsub(/\e\[\d{1,2}m/, "").length
end
end
-end \ No newline at end of file
+end