lib/tty/prompt/question.rb in tty-prompt-0.10.1 vs lib/tty/prompt/question.rb in tty-prompt-0.11.0

- old
+ new

@@ -1,22 +1,22 @@ # encoding: utf-8 -require 'tty/prompt/question/modifier' -require 'tty/prompt/question/validation' -require 'tty/prompt/question/checks' -require 'tty/prompt/converter_dsl' -require 'tty/prompt/converters' +require_relative 'converters' +require_relative 'evaluator' +require_relative 'question/modifier' +require_relative 'question/validation' +require_relative 'question/checks' +require_relative 'utils' module TTY # A class responsible for shell prompt interactions. class Prompt # A class responsible for gathering user input # # @api public class Question include Checks - include Converters UndefinedSetting = Module.new # Store question message # @api public @@ -40,10 +40,11 @@ @validation = options.fetch(:validation) { UndefinedSetting } @read = options.fetch(:read) { 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) @@ -98,16 +99,21 @@ # Read answer and convert to type # # @api private def render + @errors = [] until @done - render_question + lines = render_question result = process_input - errors = result.errors - render_error_or_finish(result) - refresh(errors.count) + if result.failure? + @errors = result.errors + render_error(result.errors) + else + @done = true + end + refresh(lines) end render_question convert_result(result.value) end @@ -122,11 +128,13 @@ header += @prompt.decorate("#{@input}", @active_color) elsif default? && !Utils.blank?(@default) header += @prompt.decorate("(#{default})", @help_color) + ' ' end @prompt.print(header) - @prompt.print("\n") if @done + @prompt.puts if @done + + header.lines.count + (@done ? 1 : 0) end # Decide how to handle input from user # # @api private @@ -144,58 +152,52 @@ def read_input case @read when :keypress @prompt.read_keypress when :multiline - @prompt.read_multiline + @prompt.read_multiline.each(&:chomp!) else - @prompt.read_line(echo) + @prompt.read_line(echo: echo).chomp end end # Handle error condition # # @api private - def render_error_or_finish(result) - if result.failure? - result.errors.each do |err| - @prompt.print(@prompt.clear_line) - @prompt.print(@prompt.decorate('>>', :red) + ' ' + err) - end - @prompt.print(@prompt.cursor.up(result.errors.count)) - else - @done = true - if result.errors.count.nonzero? - @prompt.print(@prompt.cursor.down(result.errors.count)) - end + def render_error(errors) + errors.each do |err| + newline = (@echo ? '' : "\n") + @prompt.print(newline + @prompt.decorate('>>', :red) + ' ' + err) end end # Determine area of the screen to clear # - # @param [Integer] errors + # @param [Array[String]] errors # # @api private - def refresh(errors = nil) - lines = @message.scan("\n").length - lines += ((!echo? || errors.nonzero?) ? 1 : 2) # clear user enter - - if errors.nonzero? && @done - lines += errors + def refresh(lines) + if @done + if @errors.count.zero? && @echo + @prompt.print(@prompt.cursor.up(lines)) + else + lines += @errors.count + end + else + @prompt.print(@prompt.cursor.up(lines)) end - @prompt.print(@prompt.clear_lines(lines)) end # Convert value to expected type # # @param [Object] value # # @api private def convert_result(value) if convert? & !Utils.blank?(value) - converter_registry.(@convert, value) + Converters.convert(@convert, value) else value end end @@ -301,13 +303,13 @@ # # @api public def in(value = (not_set = true), message = nil) messages[:range?] = message if message if in? && !@in.is_a?(Range) - @in = converter_registry.(:range, @in) + @in = Converters.convert(:range, @in) end return @in if not_set - @in = converter_registry.(:range, value) + @in = Converters.convert(:range, value) end # Check if range is set # # @return [Boolean]