class TTY::Prompt

A main entry for asking prompt questions.

A class responsible for shell prompt interactions.

A class responsible for shell prompt interactions.

A class responsible for shell prompt interactions.

A class responsible for terminal prompt interactions.

Used for initializing test cases

Constants

ArgumentRequired

Raised when the required argument is not supplied

ArgumentValidation

Raised when the argument validation fails

ConfigurationError

Raised when wrong parameter is used to configure prompt

ConversionAlreadyDefined

Raised when overriding already defined conversion

ConversionError

Raised when type conversion cannot be performed

Error
InvalidArgument

Raised when the argument is not expected

UnsupportedConversion

Raised when conversion type isn't registered

VERSION
ValidationCoercion

Raised when the passed in validation argument is of wrong type

Attributes

active_color[R]

Theme colors

@api private

cursor[R]
enabled_color[R]

Theme colors

@api private

error_color[R]

Theme colors

@api private

help_color[R]

Theme colors

@api private

input[R]

@api private

output[R]

@api private

prefix[R]

Prompt prefix

@example

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

@return [String]

@api private

quiet[R]

Quiet mode

@api private

reader[R]
symbols[R]

The collection of display symbols

@example

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

@return [Hash]

@api private

Public Class Methods

messages() click to toggle source
# File lib/tty/prompt.rb, line 82
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
new(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) click to toggle source

Initialize a Prompt

@param [IO] :input

the input stream

@param [IO] :output

the output stream

@param [Hash] :env

the environment variables

@param [Hash] :symbols

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

@param options [Boolean] :quiet

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

@param [String] :prefix

the prompt prefix, by default empty

@param [Symbol] :interrupt

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

@param [Boolean] :track_history

disable line history tracking, true by default

@param [Boolean] :enable_color

enable color support, true by default

@param [String,Proc] :active_color

the color used for selected option

@param [String,Proc] :help_color

the color used for help text

@param [String] :error_color

the color used for displaying error messages

@api public

# File lib/tty/prompt.rb, line 119
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

Public Instance Methods

ask(message = "", **options, &block) click to toggle source

Ask a question.

@example

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

@param [String] message

the question to be asked

@yieldparam [TTY::Prompt::Question] question

further configure the question

@yield [question]

@return [TTY::Prompt::Question]

@api public

# File lib/tty/prompt.rb, line 200
def ask(message = "", **options, &block)
  invoke_question(Question, message, **options, &block)
end
collect(**options, &block) click to toggle source

Gathers more than one aswer

@example

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

@return [Hash]

the collection of answers

@api public

# File lib/tty/prompt.rb, line 533
def collect(**options, &block)
  collector = AnswersCollector.new(self, **options)
  collector.call(&block)
end
debug(*messages) click to toggle source

Print debug information in terminal top right corner

@example

prompt.debug "info1", "info2"

@param [Array] messages

@retrun [nil]

@api public

# File lib/tty/prompt.rb, line 483
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) click to toggle source

Decorate a string with colors

@param [String] :string

the string to color

@param [Array<Proc|Symbol>] :colors

collection of color symbols or callable object

@api public

# File lib/tty/prompt.rb, line 155
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) click to toggle source

Ask a question with indexed list

@example

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

@param [String] question

the question to ask

@param [Array] choices

the choices to select from

@return [String]

@api public

# File lib/tty/prompt.rb, line 324
def enum_select(question, *args, &block)
  invoke_select(EnumList, question, *args, &block)
end
error(*args, **options) click to toggle source

Print statement(s) out in red color.

@example

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

@param [Array] messages

@return [Array] messages

@api public

# File lib/tty/prompt.rb, line 468
def error(*args, **options)
  opts = { color: :red }.merge(options)
  args.each { |message| say(message, **opts) }
end
expand(message, *args, &block) click to toggle source

Expand available options

@example

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

@return [Object]

the user specified value

@api public

# File lib/tty/prompt.rb, line 381
def expand(message, *args, &block)
  invoke_select(Expander, message, *args, &block)
end
inspect() click to toggle source

Inspect this instance public attributes

@return [String]

@api public

# File lib/tty/prompt.rb, line 573
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) click to toggle source

Invoke a question type of prompt

@example

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

@return [String]

@api public

# File lib/tty/prompt.rb, line 177
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) click to toggle source

Invoke a list type of prompt

@example

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

@return [String]

@api public

# File lib/tty/prompt.rb, line 235
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) click to toggle source

Ask a question with a keypress answer

@see ask

@api public

# File lib/tty/prompt.rb, line 209
def keypress(message = "", **options, &block)
  invoke_question(Keypress, message, **options, &block)
end
mask(message = "", **options, &block) click to toggle source

Ask masked question

@example

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

@return [TTY::Prompt::MaskQuestion]

@api public

# File lib/tty/prompt.rb, line 260
def mask(message = "", **options, &block)
  invoke_question(MaskQuestion, message, **options, &block)
end
multi_select(question, *args, &block) click to toggle source

Ask a question with multiple attributes activated

@example

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

@param [String] question

the question to ask

@param [Array] choices

the choices to select from

@return [String]

@api public

# File lib/tty/prompt.rb, line 304
def multi_select(question, *args, &block)
  invoke_select(MultiList, question, *args, &block)
end
multiline(message = "", **options, &block) click to toggle source

Ask a question with a multiline answer

@example

prompt.multiline("Description?")

@return [Array]

@api public

# File lib/tty/prompt.rb, line 221
def multiline(message = "", **options, &block)
  invoke_question(Multiline, message, **options, &block)
end
no?(message, **options, &block) click to toggle source

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

@example

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

@return [Boolean]

@api public

# File lib/tty/prompt.rb, line 356
def no?(message, **options, &block)
  opts = { default: false }.merge(options)
  question = ConfirmQuestion.new(self, **opts)
  !question.call(message, &block)
end
ok(*args, **options) click to toggle source

Print statement(s) out in red green.

@example

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

@param [Array] messages

@return [Array] messages

@api public

# File lib/tty/prompt.rb, line 436
def ok(*args, **options)
  opts = { color: :green }.merge(options)
  args.each { |message| say(message, **opts) }
end
say(message = "", **options) click to toggle source

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

@example

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

@param [String] message

@return [String]

@api public

# File lib/tty/prompt.rb, line 417
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) click to toggle source

Ask a question with a list of options

@example

prompt = TTY::Prompt.new
prompt.select("What size?", %w(large medium small))

@example

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

@param [String] question

the question to ask

@param [Array] choices

the choices to select from

@api public

# File lib/tty/prompt.rb, line 284
def select(question, *args, &block)
  invoke_select(List, question, *args, &block)
end
slider(question, choices = nil, **options, &block) click to toggle source

Ask a question with a range slider

@example

prompt = TTY::Prompt.new
prompt.slider("What size?", min: 32, max: 54, step: 2)
prompt.slider("What size?", [ 'xs', 's', 'm', 'l', 'xl' ])

@param [String] question

the question to ask

@param [Array] choices

the choices to display

@return [String]

@api public

# File lib/tty/prompt.rb, line 401
def slider(question, choices = nil, **options, &block)
  slider = Slider.new(self, **options)
  slider.call(question, choices, &block)
end
stderr() click to toggle source

Return standard error

@api private

# File lib/tty/prompt.rb, line 564
def stderr
  $stderr
end
stdin() click to toggle source

Return standard in

@api private

# File lib/tty/prompt.rb, line 550
def stdin
  $stdin
end
stdout() click to toggle source

Return standard out

@api private

# File lib/tty/prompt.rb, line 557
def stdout
  $stdout
end
suggest(message, possibilities, **options) click to toggle source

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

@example

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

@param [String] message

@param [Array] possibilities

@param [Hash] options @option options [String] :indent

The number of spaces for indentation

@option options [String] :single_text

The text for a single suggestion

@option options [String] :plural_text

The text for multiple suggestions

@return [String]

@api public

# File lib/tty/prompt.rb, line 517
def suggest(message, possibilities, **options)
  suggestion = Suggestion.new(**options)
  say(suggestion.suggest(message, possibilities))
end
tty?() click to toggle source

Check if outputing to terminal

@return [Boolean]

@api public

# File lib/tty/prompt.rb, line 543
def tty?
  stdout.tty?
end
warn(*args, **options) click to toggle source

Print statement(s) out in yellow color.

@example

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

@param [Array] messages

@return [Array] messages

@api public

# File lib/tty/prompt.rb, line 452
def warn(*args, **options)
  opts = { color: :yellow }.merge(options)
  args.each { |message| say(message, **opts) }
end
yes?(message, **options, &block) click to toggle source

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

@example

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

@return [Boolean]

@api public

# File lib/tty/prompt.rb, line 339
def yes?(message, **options, &block)
  opts = { default: true }.merge(options)
  question = ConfirmQuestion.new(self, **opts)
  question.call(message, &block)
end