Class: TTY2::Prompt

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/tty2/prompt.rb,
lib/tty2/prompt/list.rb,
lib/tty2/prompt/test.rb,
lib/tty2/prompt/const.rb,
lib/tty2/prompt/timer.rb,
lib/tty2/prompt/choice.rb,
lib/tty2/prompt/errors.rb,
lib/tty2/prompt/result.rb,
lib/tty2/prompt/slider.rb,
lib/tty2/prompt/choices.rb,
lib/tty2/prompt/symbols.rb,
lib/tty2/prompt/version.rb,
lib/tty2/prompt/distance.rb,
lib/tty2/prompt/expander.rb,
lib/tty2/prompt/keypress.rb,
lib/tty2/prompt/question.rb,
lib/tty2/prompt/enum_list.rb,
lib/tty2/prompt/evaluator.rb,
lib/tty2/prompt/multiline.rb,
lib/tty2/prompt/paginator.rb,
lib/tty2/prompt/statement.rb,
lib/tty2/prompt/converters.rb,
lib/tty2/prompt/multi_list.rb,
lib/tty2/prompt/suggestion.rb,
lib/tty2/prompt/converter_dsl.rb,
lib/tty2/prompt/mask_question.rb,
lib/tty2/prompt/block_paginator.rb,
lib/tty2/prompt/question/checks.rb,
lib/tty2/prompt/confirm_question.rb,
lib/tty2/prompt/selected_choices.rb,
lib/tty2/prompt/answers_collector.rb,
lib/tty2/prompt/question/modifier.rb,
lib/tty2/prompt/converter_registry.rb,
lib/tty2/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.5"

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/tty2/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 = TTY2::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/tty2/prompt.rb', line 55

def active_color
  @active_color
end

#cursorObject (readonly)

Returns the value of attribute cursor.



40
41
42
# File 'lib/tty2/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/tty2/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/tty2/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/tty2/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/tty2/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/tty2/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 = TTY2::Prompt.new(prefix: [?])

Returns:

  • (String)


50
51
52
# File 'lib/tty2/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/tty2/prompt.rb', line 60

def quiet
  @quiet
end

#readerObject (readonly)

Returns the value of attribute reader.



38
39
40
# File 'lib/tty2/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 = TTY2::Prompt.new(symbols: {marker: ">"})

Returns:

  • (Hash)


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

def symbols
  @symbols
end

Class Method Details

.messagesObject



83
84
85
86
87
88
89
90
# File 'lib/tty2/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| ... } ⇒ TTY2::Prompt::Question

Ask a question.

Examples:

propmt = TTY2::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/tty2/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



534
535
536
537
# File 'lib/tty2/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:

  • messages (Array)


484
485
486
487
488
489
490
491
492
493
494
# File 'lib/tty2/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:

  • :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/tty2/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 = TTY2::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/tty2/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



469
470
471
472
# File 'lib/tty2/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 = TTY2::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/tty2/prompt.rb', line 382

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

#inspectString

Inspect this instance public attributes

Returns:

  • (String)


574
575
576
577
578
579
580
581
582
583
584
585
586
587
# File 'lib/tty2/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 = TTY2::Prompt.new
prompt.invoke_question(Question, "Your name? ")

Returns:

  • (String)


178
179
180
181
182
# File 'lib/tty2/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 = TTY2::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/tty2/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/tty2/prompt.rb', line 210

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

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

Ask masked question

Examples:

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

Returns:



261
262
263
# File 'lib/tty2/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 = TTY2::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/tty2/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/tty2/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 = TTY2::Prompt.new
prompt.no?("Are you alien?") # => true
# => Are you human? (y/N)

Returns:

  • (Boolean)


357
358
359
360
361
# File 'lib/tty2/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



437
438
439
440
# File 'lib/tty2/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:

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

Returns:

  • (String)


418
419
420
421
422
423
424
# File 'lib/tty2/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 = TTY2::Prompt.new
prompt.select("What size?", %w(large medium small))
prompt = TTY2::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/tty2/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 = TTY2::Prompt.new
prompt.slider("What size?", min: 32, max: 54, step: 2)
prompt.slider("What size?", [ 'xs', 's', 'm', 'l', 'xl' ])

Parameters:

  • question (String)

    the question to ask

  • choices (Array) (defaults to: nil)

    the choices to display

Returns:

  • (String)


402
403
404
405
# File 'lib/tty2/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



565
566
567
# File 'lib/tty2/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



551
552
553
# File 'lib/tty2/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



558
559
560
# File 'lib/tty2/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:

  • 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)


518
519
520
521
# File 'lib/tty2/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:

  • (Boolean)


544
545
546
# File 'lib/tty2/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:

  • messages (Array)

Returns:

  • (Array)

    messages



453
454
455
456
# File 'lib/tty2/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 = TTY2::Prompt.new
prompt.yes?("Are you human?")
# => Are you human? (Y/n)

Returns:

  • (Boolean)


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

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