Class: TTY::Prompt::Question

Inherits:
Object
  • Object
show all
Includes:
Checks
Defined in:
lib/tty/prompt/question.rb,
lib/tty/prompt/question/checks.rb,
lib/tty/prompt/question/modifier.rb,
lib/tty/prompt/question/validation.rb

Overview

A class responsible for gathering user input

Direct Known Subclasses

ConfirmQuestion, Keypress, MaskQuestion, Multiline

Defined Under Namespace

Modules: Checks Classes: Modifier, Validation

Constant Summary collapse

UndefinedSetting =
Class.new do
  def to_s
    "undefined"
  end
  alias inspect to_s
end

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(prompt, options = {}) ⇒ Question

Initialize a Question


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# 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

Instance Attribute Details

#messageObject (readonly)

Store question message


28
29
30
# File 'lib/tty/prompt/question.rb', line 28

def message
  @message
end

#messagesObject (readonly)

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

* :range?
* :required?
* :valid?

68
69
70
# File 'lib/tty/prompt/question.rb', line 68

def messages
  @messages
end

#modifierObject (readonly)


30
31
32
# File 'lib/tty/prompt/question.rb', line 30

def modifier
  @modifier
end

#validationObject (readonly)


32
33
34
# File 'lib/tty/prompt/question.rb', line 32

def validation
  @validation
end

Instance Method Details

#call(message, &block) ⇒ self

Call the question

Parameters:

  • message (String)

Returns:

  • (self)

97
98
99
100
101
102
# 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) ⇒ Object

Specify answer conversion


212
213
214
# File 'lib/tty/prompt/question.rb', line 212

def convert(value)
  @convert = value
end

#convert?Boolean

Check if conversion is set

Returns:

  • (Boolean)

221
222
223
# File 'lib/tty/prompt/question.rb', line 221

def convert?
  @convert != UndefinedSetting
end

#convert_result(value) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Convert value to expected type

Parameters:

  • value (Object)

201
202
203
204
205
206
207
# 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)) ⇒ Object

Set default value.


228
229
230
231
# File 'lib/tty/prompt/question.rb', line 228

def default(value = (not_set = true))
  return @default if not_set
  @default = value
end

#default?Boolean

Check if default value is set

Returns:

  • (Boolean)

238
239
240
# File 'lib/tty/prompt/question.rb', line 238

def default?
  @default != UndefinedSetting
end

#echo(value = nil) ⇒ Object Also known as: echo?

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.


283
284
285
286
# File 'lib/tty/prompt/question.rb', line 283

def echo(value = nil)
  return @echo if value.nil?
  @echo = value
end

#in(value = (not_set = true), message = nil) ⇒ Object

Set expected range of values

Parameters:

  • value (String) (defaults to: (not_set = true))

303
304
305
306
307
308
309
310
# 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?Boolean

Check if range is set

Returns:

  • (Boolean)

317
318
319
# File 'lib/tty/prompt/question.rb', line 317

def in?
  @in != UndefinedSetting
end

#inspectObject

String representation of this question


328
329
330
# File 'lib/tty/prompt/question.rb', line 328

def inspect
  "#<#{self.class.name} @message=#{message}, @input=#{@input}>"
end

#message_for(name, tokens = nil) ⇒ Array[String]

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Retrieve message based on the key

Parameters:

  • name (Symbol)

    the name of message key

  • tokens (Hash) (defaults to: nil)

    the tokens to evaluate

Returns:

  • (Array[String])

81
82
83
84
85
86
87
88
# 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) ⇒ Object

Modify string according to the rule given.

Parameters:

  • rule (Symbol)

275
276
277
# File 'lib/tty/prompt/question.rb', line 275

def modify(*rules)
  @modifier = rules
end

#process_input(question) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Decide how to handle input from user


146
147
148
149
150
151
152
# 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) ⇒ Object Also known as: raw?

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


292
293
294
295
# File 'lib/tty/prompt/question.rb', line 292

def raw(value = nil)
  return @raw if value.nil?
  @raw = value
end

#read_input(question) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Process input


157
158
159
# File 'lib/tty/prompt/question.rb', line 157

def read_input(question)
  @prompt.read_line(question, echo: echo).chomp
end

#refresh(lines) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Determine area of the screen to clear

Parameters:

  • lines (Integer)

    number of lines to clear

Returns:

  • (String)

182
183
184
185
186
187
188
189
190
191
192
193
194
# 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

#renderObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Read answer and convert to type


107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# 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) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Handle error condition

Returns:

  • (String)

166
167
168
169
170
171
172
# 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_questionString

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Render question

Returns:

  • (String)

130
131
132
133
134
135
136
137
138
139
140
141
# 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) ⇒ Boolean Also known as: required?

Ensure that passed argument is present or not

Returns:

  • (Boolean)

247
248
249
250
251
# 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

#to_sObject


322
323
324
# File 'lib/tty/prompt/question.rb', line 322

def to_s
  "#{message}"
end

#validate(value = nil, message = nil, &block) ⇒ Question

Set validation rule for an argument

Parameters:

  • value (Object) (defaults to: nil)

Returns:


261
262
263
264
# 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?Boolean

Returns:

  • (Boolean)

266
267
268
# File 'lib/tty/prompt/question.rb', line 266

def validation?
  @validation != UndefinedSetting
end