Class: TTY::Prompt

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/tty/prompt.rb,
lib/tty/prompt/list.rb,
lib/tty/prompt/test.rb,
lib/tty/prompt/const.rb,
lib/tty/prompt/timer.rb,
lib/tty/prompt/choice.rb,
lib/tty/prompt/errors.rb,
lib/tty/prompt/result.rb,
lib/tty/prompt/slider.rb,
lib/tty/prompt/choices.rb,
lib/tty/prompt/symbols.rb,
lib/tty/prompt/version.rb,
lib/tty/prompt/distance.rb,
lib/tty/prompt/expander.rb,
lib/tty/prompt/keypress.rb,
lib/tty/prompt/question.rb,
lib/tty/prompt/enum_list.rb,
lib/tty/prompt/evaluator.rb,
lib/tty/prompt/multiline.rb,
lib/tty/prompt/paginator.rb,
lib/tty/prompt/statement.rb,
lib/tty/prompt/converters.rb,
lib/tty/prompt/multi_list.rb,
lib/tty/prompt/suggestion.rb,
lib/tty/prompt/converter_dsl.rb,
lib/tty/prompt/mask_question.rb,
lib/tty/prompt/block_paginator.rb,
lib/tty/prompt/question/checks.rb,
lib/tty/prompt/confirm_question.rb,
lib/tty/prompt/selected_choices.rb,
lib/tty/prompt/answers_collector.rb,
lib/tty/prompt/question/modifier.rb,
lib/tty/prompt/converter_registry.rb,
lib/tty/prompt/question/validation.rb

Overview

A class responsible for terminal prompt interactions.

Direct Known Subclasses

Test

Defined Under Namespace

Modules: Const, ConverterDSL, Converters, StringIOExtensions, Symbols Classes: AnswersCollector, BlockPaginator, Choice, Choices, ConfirmQuestion, ConverterRegistry, Distance, EnumList, Evaluator, Expander, Keypress, List, MaskQuestion, MultiList, Multiline, Paginator, Question, Result, SelectedChoices, Slider, Statement, Suggestion, Test, Timer

Constant Summary collapse

Error =
Class.new(StandardError)
ConfigurationError =

Raised when wrong parameter is used to configure prompt

Class.new(Error)
ConversionError =

Raised when type conversion cannot be performed

Class.new(Error)
ValidationCoercion =

Raised when the passed in validation argument is of wrong type

Class.new(Error)
ArgumentRequired =

Raised when the required argument is not supplied

Class.new(Error)
ArgumentValidation =

Raised when the argument validation fails

Class.new(Error)
InvalidArgument =

Raised when the argument is not expected

Class.new(Error)
ConversionAlreadyDefined =

Raised when overriding already defined conversion

Class.new(Error)
UnsupportedConversion =

Raised when conversion type isn't registered

Class.new(Error)
VERSION =
"0.22.0"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input: $stdin, output: $stdout, env: ENV, symbols: {}, prefix: "", interrupt: :error, track_history: true, quiet: false, enable_color: nil, active_color: :green, help_color: :bright_black, error_color: :red) ⇒ Prompt

Initialize a Prompt

Parameters:

  • :input (IO)

    the input stream

  • :output (IO)

    the output stream

  • :env (Hash)

    the environment variables

  • :symbols (Hash)

    the symbols displayed in prompts such as :marker, :cross

  • options (Boolean)

    :quiet enable quiet mode, don't re-echo the question

  • :prefix (String)

    the prompt prefix, by default empty

  • :interrupt (Symbol)

    handling of Ctrl+C key out of :signal, :exit, :noop

  • :track_history (Boolean)

    disable line history tracking, true by default

  • :enable_color (Boolean)

    enable color support, true by default

  • :active_color (String, Proc)

    the color used for selected option

  • :help_color (String, Proc)

    the color used for help text

  • :error_color (String)

    the color used for displaying error messages


120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/tty/prompt.rb', line 120

def initialize(input: $stdin, output: $stdout, env: ENV, symbols: {},
               prefix: "", interrupt: :error, track_history: true,
               quiet: false, enable_color: nil, active_color: :green,
               help_color: :bright_black, error_color: :red)
  @input  = input
  @output = output
  @env    = env
  @prefix = prefix
  @enabled_color = enable_color
  @active_color  = active_color
  @help_color    = help_color
  @error_color   = error_color
  @interrupt     = interrupt
  @track_history = track_history
  @symbols       = Symbols.symbols.merge(symbols)
  @quiet         = quiet

  @cursor = TTY::Cursor
  @pastel = enabled_color.nil? ? Pastel.new : Pastel.new(enabled: enabled_color)
  @reader = TTY::Reader.new(
    input: input,
    output: output,
    interrupt: interrupt,
    track_history: track_history,
    env: env
  )
end

Instance Attribute Details

#active_colorObject (readonly)

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.

Theme colors


55
56
57
# File 'lib/tty/prompt.rb', line 55

def active_color
  @active_color
end

#cursorObject (readonly)

Returns the value of attribute cursor


40
41
42
# File 'lib/tty/prompt.rb', line 40

def cursor
  @cursor
end

#enabled_colorObject (readonly)

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.

Theme colors


55
56
57
# File 'lib/tty/prompt.rb', line 55

def enabled_color
  @enabled_color
end

#error_colorObject (readonly)

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.

Theme colors


55
56
57
# File 'lib/tty/prompt.rb', line 55

def error_color
  @error_color
end

#help_colorObject (readonly)

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.

Theme colors


55
56
57
# File 'lib/tty/prompt.rb', line 55

def help_color
  @help_color
end

#inputObject (readonly)

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.


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

def input
  @input
end

#outputObject (readonly)

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.


36
37
38
# File 'lib/tty/prompt.rb', line 36

def output
  @output
end

#prefixString (readonly)

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.

Prompt prefix

Examples:

prompt = TTY::Prompt.new(prefix: [?])

Returns:

  • (String)

50
51
52
# File 'lib/tty/prompt.rb', line 50

def prefix
  @prefix
end

#quietObject (readonly)

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.

Quiet mode


60
61
62
# File 'lib/tty/prompt.rb', line 60

def quiet
  @quiet
end

#readerObject (readonly)

Returns the value of attribute reader


38
39
40
# File 'lib/tty/prompt.rb', line 38

def reader
  @reader
end

#symbolsHash (readonly)

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.

The collection of display symbols

Examples:

prompt = TTY::Prompt.new(symbols: {marker: ">"})

Returns:

  • (Hash)

70
71
72
# File 'lib/tty/prompt.rb', line 70

def symbols
  @symbols
end

Class Method Details

.messagesObject


83
84
85
86
87
88
89
90
# File 'lib/tty/prompt.rb', line 83

def self.messages
  {
    range?: "Value %{value} must be within the range %{in}",
    valid?: "Your answer is invalid (must match %{valid})",
    required?: "Value must be provided",
    convert?: "Cannot convert `%{value}` to '%{type}' type"
  }
end

Instance Method Details

#ask(message = "", **options) {|question| ... } ⇒ TTY::Prompt::Question

Ask a question.

Examples:

propmt = TTY::Prompt.new
prompt.ask("What is your name?")

Parameters:

  • message (String) (defaults to: "")

    the question to be asked

Yields:

  • (question)

Yield Parameters:

Returns:


201
202
203
# File 'lib/tty/prompt.rb', line 201

def ask(message = "", **options, &block)
  invoke_question(Question, message, **options, &block)
end

#collect(**options, &block) ⇒ Hash

Gathers more than one aswer

Examples:

prompt.collect do
  key(:name).ask("Name?")
end

Returns:

  • (Hash)

    the collection of answers


530
531
532
533
# File 'lib/tty/prompt.rb', line 530

def collect(**options, &block)
  collector = AnswersCollector.new(self, **options)
  collector.call(&block)
end

#debug(*messages) ⇒ Object

Print debug information in terminal top right corner

Examples:

prompt.debug "info1", "info2"

Parameters:

  • messages (Array)

480
481
482
483
484
485
486
487
488
489
490
# File 'lib/tty/prompt.rb', line 480

def debug(*messages)
  longest = messages.max_by(&:length).size
  width = TTY::Screen.width - longest
  print cursor.save
  messages.reverse_each do |msg|
    print cursor.column(width) + cursor.up + cursor.clear_line_after
    print msg
  end
ensure
  print cursor.restore
end

#decorate(string, *colors) ⇒ Object

Decorate a string with colors

Parameters:

  • :string (String)

    the string to color

  • :colors (Array<Proc|Symbol>)

    collection of color symbols or callable object


156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/tty/prompt.rb', line 156

def decorate(string, *colors)
  if Utils.blank?(string) || @enabled_color == false || colors.empty?
    return string
  end

  coloring = colors.first
  if coloring.respond_to?(:call)
    coloring.call(string)
  else
    @pastel.decorate(string, *colors)
  end
end

#enum_select(question, *args, &block) ⇒ String

Ask a question with indexed list

Examples:

prompt = TTY::Prompt.new
editors = %w(emacs nano vim)
prompt.enum_select(EnumList, "Select editor: ", editors)

Parameters:

  • question (String)

    the question to ask

  • choices (Array[Object])

    the choices to select from

Returns:

  • (String)

325
326
327
# File 'lib/tty/prompt.rb', line 325

def enum_select(question, *args, &block)
  invoke_select(EnumList, question, *args, &block)
end

#error(*args, **options) ⇒ Array

Print statement(s) out in red color.

Examples:

prompt.error "Shutting down all systems!"
prompt.error "Nothing is fine!", "All is broken!"

Parameters:

  • messages (Array)

Returns:

  • (Array)

    messages


465
466
467
468
# File 'lib/tty/prompt.rb', line 465

def error(*args, **options)
  opts = { color: :red }.merge(options)
  args.each { |message| say(message, **opts) }
end

#expand(message, *args, &block) ⇒ Object

Expand available options

Examples:

prompt = TTY::Prompt.new
choices = [{
  key: "Y",
  name: "Overwrite",
  value: :yes
}, {
  key: "n",
  name: "Skip",
  value: :no
}]
prompt.expand("Overwirte Gemfile?", choices)

Returns:

  • (Object)

    the user specified value


382
383
384
# File 'lib/tty/prompt.rb', line 382

def expand(message, *args, &block)
  invoke_select(Expander, message, *args, &block)
end

#inspectString

Inspect this instance public attributes

Returns:

  • (String)

570
571
572
573
574
575
576
577
578
579
580
581
582
583
# File 'lib/tty/prompt.rb', line 570

def inspect
  attributes = [
    :prefix,
    :quiet,
    :enabled_color,
    :active_color,
    :error_color,
    :help_color,
    :input,
    :output,
  ]
  name = self.class.name
  "#<#{name}#{attributes.map { |attr| " #{attr}=#{send(attr).inspect}" }.join}>"
end

#invoke_question(object, message, **options, &block) ⇒ String

Invoke a question type of prompt

Examples:

prompt = TTY::Prompt.new
prompt.invoke_question(Question, "Your name? ")

Returns:

  • (String)

178
179
180
181
182
# File 'lib/tty/prompt.rb', line 178

def invoke_question(object, message, **options, &block)
  options[:messages] = self.class.messages
  question = object.new(self, **options)
  question.(message, &block)
end

#invoke_select(object, question, *args, &block) ⇒ String

Invoke a list type of prompt

Examples:

prompt = TTY::Prompt.new
editors = %w(emacs nano vim)
prompt.invoke_select(EnumList, "Select editor: ", editors)

Returns:

  • (String)

236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/tty/prompt.rb', line 236

def invoke_select(object, question, *args, &block)
  options = Utils.extract_options!(args)
  choices = if args.empty? && !block
              possible = options.dup
              options = {}
              possible
            elsif args.size == 1 && args[0].is_a?(Hash)
              Utils.extract_options!(args)
            else
              args.flatten
            end

  list = object.new(self, **options)
  list.(question, choices, &block)
end

#keypress(message = "", **options, &block) ⇒ Object

Ask a question with a keypress answer

See Also:


210
211
212
# File 'lib/tty/prompt.rb', line 210

def keypress(message = "", **options, &block)
  invoke_question(Keypress, message, **options, &block)
end

#mask(message = "", **options, &block) ⇒ TTY::Prompt::MaskQuestion

Ask masked question

Examples:

propmt = TTY::Prompt.new
prompt.mask("What is your secret?")

Returns:


261
262
263
# File 'lib/tty/prompt.rb', line 261

def mask(message = "", **options, &block)
  invoke_question(MaskQuestion, message, **options, &block)
end

#multi_select(question, *args, &block) ⇒ String

Ask a question with multiple attributes activated

Examples:

prompt = TTY::Prompt.new
choices = %w(Scorpion Jax Kitana Baraka Jade)
prompt.multi_select("Choose your destiny?", choices)

Parameters:

  • question (String)

    the question to ask

  • choices (Array[Object])

    the choices to select from

Returns:

  • (String)

305
306
307
# File 'lib/tty/prompt.rb', line 305

def multi_select(question, *args, &block)
  invoke_select(MultiList, question, *args, &block)
end

#multiline(message = "", **options, &block) ⇒ Array[String]

Ask a question with a multiline answer

Examples:

prompt.multiline("Description?")

Returns:

  • (Array[String])

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

def multiline(message = "", **options, &block)
  invoke_question(Multiline, message, **options, &block)
end

#no?(message, **options, &block) ⇒ Boolean

A shortcut method to ask the user negative question and return true for “no” reply.

Examples:

prompt = TTY::Prompt.new
prompt.no?("Are you alien?") # => true
# => Are you human? (y/N)

Returns:

  • (Boolean)

357
358
359
360
361
# File 'lib/tty/prompt.rb', line 357

def no?(message, **options, &block)
  opts = { default: false }.merge(options)
  question = ConfirmQuestion.new(self, **opts)
  !question.call(message, &block)
end

#ok(*args, **options) ⇒ Array

Print statement(s) out in red green.

Examples:

prompt.ok "Are you sure?"
prompt.ok "All is fine!", "This is fine too."

Parameters:

  • messages (Array)

Returns:

  • (Array)

    messages


433
434
435
436
# File 'lib/tty/prompt.rb', line 433

def ok(*args, **options)
  opts = { color: :green }.merge(options)
  args.each { |message| say(message, **opts) }
end

#say(message = "", **options) ⇒ String

Print statement out. If the supplied message ends with a space or tab character, a new line will not be appended.

Examples:

say("Simple things.", color: :red)

Parameters:

  • message (String) (defaults to: "")

Returns:

  • (String)

414
415
416
417
418
419
420
# File 'lib/tty/prompt.rb', line 414

def say(message = "", **options)
  message = message.to_s
  return if message.empty?

  statement = Statement.new(self, **options)
  statement.call(message)
end

#select(question, *args, &block) ⇒ Object

Ask a question with a list of options

Examples:

prompt = TTY::Prompt.new
prompt.select("What size?", %w(large medium small))
prompt = TTY::Prompt.new
prompt.select("What size?") do |menu|
  menu.choice :large
  menu.choices %w(:medium :small)
end

Parameters:

  • question (String)

    the question to ask

  • choices (Array[Object])

    the choices to select from


285
286
287
# File 'lib/tty/prompt.rb', line 285

def select(question, *args, &block)
  invoke_select(List, question, *args, &block)
end

#slider(question, **options, &block) ⇒ String

Ask a question with a range slider

Examples:

prompt = TTY::Prompt.new
prompt.slider("What size?", min: 32, max: 54, step: 2)

Parameters:

  • question (String)

    the question to ask

Returns:

  • (String)

398
399
400
401
# File 'lib/tty/prompt.rb', line 398

def slider(question, **options, &block)
  slider = Slider.new(self, **options)
  slider.call(question, &block)
end

#stderrObject

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.

Return standard error


561
562
563
# File 'lib/tty/prompt.rb', line 561

def stderr
  $stderr
end

#stdinObject

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.

Return standard in


547
548
549
# File 'lib/tty/prompt.rb', line 547

def stdin
  $stdin
end

#stdoutObject

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.

Return standard out


554
555
556
# File 'lib/tty/prompt.rb', line 554

def stdout
  $stdout
end

#suggest(message, possibilities, **options) ⇒ String

Takes the string provided by the user and compare it with other possible matches to suggest an unambigous string

Examples:

prompt.suggest("sta", ["status", "stage", "commit", "branch"])
# => "status, stage"

Parameters:

  • message (String)
  • possibilities (Array)
  • options (Hash)

Options Hash (**options):

  • :indent (String)

    The number of spaces for indentation

  • :single_text (String)

    The text for a single suggestion

  • :plural_text (String)

    The text for multiple suggestions

Returns:

  • (String)

514
515
516
517
# File 'lib/tty/prompt.rb', line 514

def suggest(message, possibilities, **options)
  suggestion = Suggestion.new(**options)
  say(suggestion.suggest(message, possibilities))
end

#tty?Boolean

Check if outputing to terminal

Returns:

  • (Boolean)

540
541
542
# File 'lib/tty/prompt.rb', line 540

def tty?
  stdout.tty?
end

#warn(*args, **options) ⇒ Array

Print statement(s) out in yellow color.

Examples:

prompt.warn "This action can have dire consequences"
prompt.warn "Carefull young apprentice", "This is potentially dangerous"

Parameters:

  • messages (Array)

Returns:

  • (Array)

    messages


449
450
451
452
# File 'lib/tty/prompt.rb', line 449

def warn(*args, **options)
  opts = { color: :yellow }.merge(options)
  args.each { |message| say(message, **opts) }
end

#yes?(message, **options, &block) ⇒ Boolean

A shortcut method to ask the user positive question and return true for “yes” reply, false for “no”.

Examples:

prompt = TTY::Prompt.new
prompt.yes?("Are you human?")
# => Are you human? (Y/n)

Returns:

  • (Boolean)

340
341
342
343
344
# File 'lib/tty/prompt.rb', line 340

def yes?(message, **options, &block)
  opts = { default: true }.merge(options)
  question = ConfirmQuestion.new(self, **opts)
  question.call(message, &block)
end