class TTY::Prompt::Question

A class responsible for gathering user input

@api public

Constants

UndefinedSetting

Attributes

message[R]

Store question message @api public

messages[R]

Stores all the error messages displayed to user The currently supported messages are:

* :range?
* :required?
* :valid?
modifier[R]
validation[R]

Public Class Methods

new(prompt, options = {}) click to toggle source

Initialize a Question

@api public

# File lib/tty/prompt/question.rb, line 37
def initialize(prompt, options = {})
  @prompt     = prompt
  @prefix     = options.fetch(:prefix) { @prompt.prefix }
  @default    = options.fetch(:default) { UndefinedSetting }
  @required   = options.fetch(:required) { false }
  @echo       = options.fetch(:echo) { true }
  @in         = options.fetch(:in) { UndefinedSetting }
  @modifier   = options.fetch(:modifier) { [] }
  @validation = options.fetch(:validation) { UndefinedSetting }
  @convert    = options.fetch(:convert) { UndefinedSetting }
  @active_color = options.fetch(:active_color) { @prompt.active_color }
  @help_color = options.fetch(:help_color) { @prompt.help_color }
  @error_color = options.fetch(:error_color)  { :red }
  @messages   = Utils.deep_copy(options.fetch(:messages) { { } })
  @done       = false
  @input      = nil

  @evaluator = Evaluator.new(self)

  @evaluator << CheckRequired
  @evaluator << CheckDefault
  @evaluator << CheckRange
  @evaluator << CheckValidation
  @evaluator << CheckModifier
end

Public Instance Methods

call(message, &block) click to toggle source

Call the question

@param [String] message

@return [self]

@api public

# File lib/tty/prompt/question.rb, line 97
def call(message, &block)
  return if Utils.blank?(message)
  @message = message
  block.call(self) if block
  render
end
convert(value) click to toggle source

Specify answer conversion

@api public

# File lib/tty/prompt/question.rb, line 212
def convert(value)
  @convert = value
end
convert?() click to toggle source

Check if conversion is set

@return [Boolean]

@api public

# File lib/tty/prompt/question.rb, line 221
def convert?
  @convert != UndefinedSetting
end
convert_result(value) click to toggle source

Convert value to expected type

@param [Object] value

@api private

# File lib/tty/prompt/question.rb, line 201
def convert_result(value)
  if convert? & !Utils.blank?(value)
    Converters.convert(@convert, value)
  else
    value
  end
end
default(value = (not_set = true)) click to toggle source

Set default value.

@api public

# File lib/tty/prompt/question.rb, line 228
def default(value = (not_set = true))
  return @default if not_set
  @default = value
end
default?() click to toggle source

Check if default value is set

@return [Boolean]

@api public

# File lib/tty/prompt/question.rb, line 238
def default?
  @default != UndefinedSetting
end
echo(value = nil) click to toggle source

Turn terminal echo on or off. This is used to secure the display so that the entered characters are not echoed back to the screen.

@api public

# File lib/tty/prompt/question.rb, line 283
def echo(value = nil)
  return @echo if value.nil?
  @echo = value
end
Also aliased as: echo?
echo?(value = nil)
Alias for: echo
in(value = (not_set = true), message = nil) click to toggle source

Set expected range of values

@param [String] value

@api public

# File lib/tty/prompt/question.rb, line 303
def in(value = (not_set = true), message = nil)
  messages[:range?] = message if message
  if in? && !@in.is_a?(Range)
    @in = Converters.convert(:range, @in)
  end
  return @in if not_set
  @in = Converters.convert(:range, value)
end
in?() click to toggle source

Check if range is set

@return [Boolean]

@api public

# File lib/tty/prompt/question.rb, line 317
def in?
  @in != UndefinedSetting
end
inspect() click to toggle source

String representation of this question @api public

# File lib/tty/prompt/question.rb, line 328
def inspect
  "#<#{self.class.name} @message=#{message}, @input=#{@input}>"
end
message_for(name, tokens = nil) click to toggle source

Retrieve message based on the key

@param [Symbol] name

the name of message key

@param [Hash] tokens

the tokens to evaluate

@return [Array]

@api private

# File lib/tty/prompt/question.rb, line 81
def message_for(name, tokens = nil)
  template = @messages[name]
  if template && !template.match(/\%\{/).nil?
    [template % tokens]
  else
    [template || '']
  end
end
modify(*rules) click to toggle source

Modify string according to the rule given.

@param [Symbol] rule

@api public

# File lib/tty/prompt/question.rb, line 275
def modify(*rules)
  @modifier = rules
end
process_input(question) click to toggle source

Decide how to handle input from user

@api private

# File lib/tty/prompt/question.rb, line 146
def process_input(question)
  @input = read_input(question)
  if Utils.blank?(@input)
    @input = default? ? default : nil
  end
  @evaluator.(@input)
end
raw(value = nil) click to toggle source

Turn raw mode on or off. This enables character-based input.

@api public

# File lib/tty/prompt/question.rb, line 292
def raw(value = nil)
  return @raw if value.nil?
  @raw = value
end
Also aliased as: raw?
raw?(value = nil)
Alias for: raw
read_input(question) click to toggle source

Process input

@api private

# File lib/tty/prompt/question.rb, line 157
def read_input(question)
  @prompt.read_line(question, echo: echo).chomp
end
refresh(lines) click to toggle source

Determine area of the screen to clear

@param [Integer] lines

number of lines to clear

@return [String]

@api private

# File lib/tty/prompt/question.rb, line 182
def refresh(lines)
  output = ''
  if @done
    if @errors.count.zero? && @echo
      output << @prompt.cursor.up(lines)
    else
      lines += @errors.count
    end
  else
    output << @prompt.cursor.up(lines)
  end
  output + @prompt.clear_lines(lines)
end
render() click to toggle source

Read answer and convert to type

@api private

# File lib/tty/prompt/question.rb, line 107
def render
  @errors = []
  until @done
    question = render_question
    @prompt.print(question)
    result = process_input(question)
    if result.failure?
      @errors = result.errors
      @prompt.print(render_error(result.errors))
    else
      @done = true
    end
    @prompt.print(refresh(question.lines.count))
  end
  @prompt.print(render_question)
  convert_result(result.value)
end
render_error(errors) click to toggle source

Handle error condition

@return [String]

@api private

# File lib/tty/prompt/question.rb, line 166
def render_error(errors)
  errors.reduce('') do |acc, err|
    newline = (@echo ? '' : "\n")
    acc << newline + @prompt.decorate('>>', :red) + ' ' + err
    acc
  end
end
render_question() click to toggle source

Render question

@return [String]

@api private

# File lib/tty/prompt/question.rb, line 130
def render_question
  header = "#{@prefix}#{message} "
  if !echo?
    header
  elsif @done
    header += @prompt.decorate("#{@input}", @active_color)
  elsif default? && !Utils.blank?(@default)
    header += @prompt.decorate("(#{default})", @help_color) + ' '
  end
  header << "\n" if @done
  header
end
required(value = (not_set = true), message = nil) click to toggle source

Ensure that passed argument is present or not

@return [Boolean]

@api public

# File lib/tty/prompt/question.rb, line 247
def required(value = (not_set = true), message = nil)
  messages[:required?] = message if message
  return @required if not_set
  @required = value
end
Also aliased as: required?
required?(value = (not_set = true), message = nil)
Alias for: required
to_s() click to toggle source

@api public

# File lib/tty/prompt/question.rb, line 322
def to_s
  "#{message}"
end
validate(value = nil, message = nil, &block) click to toggle source

Set validation rule for an argument

@param [Object] value

@return [Question]

@api public

# File lib/tty/prompt/question.rb, line 261
def validate(value = nil, message = nil, &block)
  messages[:valid?] = message if message
  @validation = (value || block)
end
validation?() click to toggle source
# File lib/tty/prompt/question.rb, line 266
def validation?
  @validation != UndefinedSetting
end