class TTY::Prompt::Question
A class responsible for gathering user input
@api public
Constants
- UndefinedSetting
Attributes
Store question message @api public
Stores all the error messages displayed to user The currently supported messages are:
* :range? * :required? * :valid?
Public Class Methods
Initialize a Question
@api public
# File lib/tty/prompt/question.rb, line 36 def initialize(prompt, **options) # Option deprecation if options[:validation] warn "[DEPRECATION] The `:validation` option is deprecated. Use `:validate` instead." options[:validate] = options[:validation] end @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(:validate) { 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 } @value = options.fetch(:value) { UndefinedSetting } @quiet = options.fetch(:quiet) { @prompt.quiet } @messages = Utils.deep_copy(options.fetch(:messages) { {} }) @done = false @first_render = true @input = nil @evaluator = Evaluator.new(self) @evaluator << CheckRequired @evaluator << CheckDefault @evaluator << CheckRange @evaluator << CheckValidation @evaluator << CheckModifier @evaluator << CheckConversion end
Public Instance Methods
Call the question
@param [String] message
@return [self]
@api public
# File lib/tty/prompt/question.rb, line 106 def call(message = "", &block) @message = message block.call(self) if block @prompt.subscribe(self) do render end end
Specify answer conversion
@api public
# File lib/tty/prompt/question.rb, line 236 def convert(value = (not_set = true), message = nil) messages[:convert?] = message if message if not_set @convert else @convert = value end end
Check if conversion is set
@return [Boolean]
@api public
# File lib/tty/prompt/question.rb, line 250 def convert? @convert != UndefinedSetting end
Convert value to expected type
@param [Object] value
@api private
# File lib/tty/prompt/question.rb, line 220 def convert_result(value) if convert? && !Utils.blank?(value) case @convert when Proc @convert.call(value) else Converters.convert(@convert, value) end else value end end
Set default value.
@api public
# File lib/tty/prompt/question.rb, line 257 def default(value = (not_set = true)) return @default if not_set @default = value end
Check if default value is set
@return [Boolean]
@api public
# File lib/tty/prompt/question.rb, line 268 def default? @default != UndefinedSetting end
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 330 def echo(value = nil) return @echo if value.nil? @echo = value end
Set expected range of values
@param [String] value
@api public
# File lib/tty/prompt/question.rb, line 352 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
Check if range is set
@return [Boolean]
@api public
# File lib/tty/prompt/question.rb, line 367 def in? @in != UndefinedSetting end
String representation of this question @api public
# File lib/tty/prompt/question.rb, line 385 def inspect "#<#{self.class.name} @message=#{message}, @input=#{@input}>" end
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 90 def message_for(name, tokens = nil) template = @messages[name] if template && !template.match(/\%\{/).nil? [template % tokens] else [template || ""] end end
Modify string according to the rule given.
@param [Symbol] rule
@api public
# File lib/tty/prompt/question.rb, line 322 def modify(*rules) @modifier = rules end
Decide how to handle input from user
@api private
# File lib/tty/prompt/question.rb, line 160 def process_input(question) @input = read_input(question) if Utils.blank?(@input) @input = default? ? default : nil end @evaluator.(@input) end
Set quiet mode.
@api public
# File lib/tty/prompt/question.rb, line 374 def quiet(value) @quiet = value end
Turn raw mode on or off. This enables character-based input.
@api public
# File lib/tty/prompt/question.rb, line 340 def raw(value = nil) return @raw if value.nil? @raw = value end
Process input
@api private
# File lib/tty/prompt/question.rb, line 171 def read_input(question) options = { echo: echo } if value? && @first_render options[:value] = @value @first_render = false end @prompt.read_line(question, **options).chomp end
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 200 def refresh(lines, lines_to_clear) output = [] if @done if @errors.count.zero? output << @prompt.cursor.up(lines) else lines += @errors.count lines_to_clear += @errors.count end else output << @prompt.cursor.up(lines) end output.join + @prompt.clear_lines(lines_to_clear) end
Read answer and convert to type
@api private
# File lib/tty/prompt/question.rb, line 117 def render @errors = [] until @done result = process_input(render_question) if result.failure? @errors = result.errors @prompt.print(render_error(result.errors)) else @done = true end question = render_question input_line = question + result.value.to_s total_lines = @prompt.count_screen_lines(input_line) @prompt.print(refresh(question.lines.count, total_lines)) end @prompt.print(render_question) unless @quiet result.value end
Handle error condition
@return [String]
@api private
# File lib/tty/prompt/question.rb, line 185 def render_error(errors) errors.reduce([]) do |acc, err| acc << @prompt.decorate(">>", :red) + " " + err acc end.join("\n") end
Render question
@return [String]
@api private
# File lib/tty/prompt/question.rb, line 141 def render_question header = [] if !Utils.blank?(@prefix) || !Utils.blank?(message) header << "#{@prefix}#{message} " end if !echo? header elsif @done header << @prompt.decorate(@input.to_s, @active_color) elsif default? && !Utils.blank?(@default) header << @prompt.decorate("(#{default})", @help_color) + " " end header << "\n" if @done header.join end
Ensure that passed argument is present or not
@return [Boolean]
@api public
# File lib/tty/prompt/question.rb, line 277 def required(value = (not_set = true), message = nil) messages[:required?] = message if message return @required if not_set @required = value end
@api public
# File lib/tty/prompt/question.rb, line 379 def to_s message.to_s end
Set validation rule for an argument
@param [Object] value
@return [Question]
@api public
# File lib/tty/prompt/question.rb, line 292 def validate(value = nil, message = nil, &block) messages[:valid?] = message if message @validation = (value || block) end
# File lib/tty/prompt/question.rb, line 313 def validation? @validation != UndefinedSetting end
Prepopulate input with custom content
@api public
# File lib/tty/prompt/question.rb, line 300 def value(val) return @value if val.nil? @value = val end
Check if custom value is present
@api private
# File lib/tty/prompt/question.rb, line 309 def value? @value != UndefinedSetting end