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.23.1"

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:

  • the input stream

  • the output stream

  • the environment variables

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

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

  • the prompt prefix, by default empty

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

  • disable line history tracking, true by default

  • enable color support, true by default

  • the color used for selected option

  • the color used for help text

  • the color used for displaying error messages

API:

  • public



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

API:

  • private



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

API:

  • private



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

API:

  • private



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

API:

  • private



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.

API:

  • private



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.

API:

  • private



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:

API:

  • private



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

API:

  • private



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:

API:

  • private



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:

  • (defaults to: "")

    the question to be asked

Yields:

  • (question)

Yield Parameters:

Returns:

API:

  • public



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:

  • the collection of answers

API:

  • public



534
535
536
537
# File 'lib/tty/prompt.rb', line 534

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:

API:

  • public



484
485
486
487
488
489
490
491
492
493
494
# File 'lib/tty/prompt.rb', line 484

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:

  • the string to color

  • collection of color symbols or callable object

API:

  • public



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:

  • the question to ask

  • the choices to select from

Returns:

API:

  • public



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:

Returns:

  • messages

API:

  • public



469
470
471
472
# File 'lib/tty/prompt.rb', line 469

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:

  • the user specified value

API:

  • public



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:

API:

  • public



574
575
576
577
578
579
580
581
582
583
584
585
586
587
# File 'lib/tty/prompt.rb', line 574

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:

API:

  • public



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:

API:

  • public



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:

API:

  • public



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:

API:

  • public



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:

  • the question to ask

  • the choices to select from

Returns:

API:

  • public



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:

API:

  • public



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:

API:

  • public



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:

Returns:

  • messages

API:

  • public



437
438
439
440
# File 'lib/tty/prompt.rb', line 437

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:

  • (defaults to: "")

Returns:

API:

  • public



418
419
420
421
422
423
424
# File 'lib/tty/prompt.rb', line 418

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:

  • the question to ask

  • the choices to select from

API:

  • public



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

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

#slider(question, choices = nil, **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)
prompt.slider("What size?", [ 'xs', 's', 'm', 'l', 'xl' ])

Parameters:

  • the question to ask

  • (defaults to: nil)

    the choices to display

Returns:

API:

  • public



402
403
404
405
# File 'lib/tty/prompt.rb', line 402

def slider(question, choices = nil, **options, &block)
  slider = Slider.new(self, **options)
  slider.call(question, choices, &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

API:

  • private



565
566
567
# File 'lib/tty/prompt.rb', line 565

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

API:

  • private



551
552
553
# File 'lib/tty/prompt.rb', line 551

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

API:

  • private



558
559
560
# File 'lib/tty/prompt.rb', line 558

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:

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:

API:

  • public



518
519
520
521
# File 'lib/tty/prompt.rb', line 518

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

#tty?Boolean

Check if outputing to terminal

Returns:

API:

  • public



544
545
546
# File 'lib/tty/prompt.rb', line 544

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:

Returns:

  • messages

API:

  • public



453
454
455
456
# File 'lib/tty/prompt.rb', line 453

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:

API:

  • public



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