Module: CLI::UI::Prompt

Defined in:
lib/cli/ui/prompt.rb,
lib/cli/ui/prompt/options_handler.rb,
lib/cli/ui/prompt/interactive_options.rb

Defined Under Namespace

Classes: InteractiveOptions, OptionsHandler

Class Method Summary collapse

Class Method Details

.any_key(prompt = 'Press any key to continue...') ⇒ Object

Present the user with a message and wait for any key to be pressed, returning the pressed key.

Example Usage:

CLI::UI::Prompt.any_key # Press any key to continue...

CLI::UI::Prompt.any_key('Press RETURN to continue...') # Then check if that's what they pressed

: (?String prompt) -> String?



202
203
204
205
206
207
# File 'lib/cli/ui/prompt.rb', line 202

def any_key(prompt = 'Press any key to continue...')
  CLI::UI::StdoutRouter::Capture.in_alternate_screen do
    puts_question(prompt)
    read_char
  end
end

.ask(question, options: nil, default: nil, is_file: false, allow_empty: true, multiple: false, filter_ui: true, select_ui: true, &options_proc) ⇒ Object

Ask a user a question with either free form answer or a set of answers (multiple choice) Can use arrows, y/n, numbers (1/2), and vim bindings to control multiple choice selection Do not use this method for yes/no questions. Use confirm

  • Handles free form answers (options are nil)

  • Handles default answers for free form text

  • Handles file auto completion for file input

  • Handles interactively choosing answers using InteractiveOptions

Attributes

  • question - (required) The question to ask the user

Options

  • :options - Options that the user may select from. Will use InteractiveOptions to do so.

  • :default - The default answer to the question (e.g. they just press enter and don’t input anything)

  • :is_file - Tells the input to use file auto-completion (tab completion)

  • :allow_empty - Allows the answer to be empty

  • :multiple - Allow multiple options to be selected

  • :filter_ui - Enable option filtering (default: true)

  • :select_ui - Enable long-form option selection (default: true)

Note:

  • :options or providing a Block conflicts with :default and :is_file,

    you cannot set options with either of these keywords
    
  • :default conflicts with +:allow_empty:, you cannot set these together

  • :options conflicts with providing a Block , you may only set one

  • :multiple can only be used with :options or a Block; it is ignored, otherwise.

Block (optional)

  • A Proc that provides a OptionsHandler and uses the public :option method to add options and their respective handlers

Return Value

  • If a Block was not provided, the selected option or response to the free form question will be returned

  • If a Block was provided, the evaluated value of the Block will be returned

Example Usage:

Free form question

CLI::UI::Prompt.ask('What color is the sky?')

Free form question with a file answer

CLI::UI::Prompt.ask('Where is your Gemfile located?', is_file: true)

Free form question with a default answer

CLI::UI::Prompt.ask('What color is the sky?', default: 'blue')

Free form question when the answer can be empty

CLI::UI::Prompt.ask('What is your opinion on this question?', allow_empty: true)

Interactive (multiple choice) question

CLI::UI::Prompt.ask('What kind of project is this?', options: %w(rails go ruby python))

Interactive (multiple choice) question with defined handlers

CLI::UI::Prompt.ask('What kind of project is this?') do |handler|
  handler.option('rails')  { |selection| selection }
  handler.option('go')     { |selection| selection }
  handler.option('ruby')   { |selection| selection }
  handler.option('python') { |selection| selection }
end

: (String question, ?options: Array?, ?default: (String | Array)?, ?is_file: bool, ?allow_empty: bool, ?multiple: bool, ?filter_ui: bool, ?select_ui: bool) ?{ (OptionsHandler handler) -> void } -> (String | Array)



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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
147
148
149
# File 'lib/cli/ui/prompt.rb', line 103

def ask(
  question,
  options: nil,
  default: nil,
  is_file: false,
  allow_empty: true,
  multiple: false,
  filter_ui: true,
  select_ui: true,
  &options_proc
)
  has_options = !!(options || block_given?)
  if has_options && is_file
    raise(ArgumentError, 'conflicting arguments: is_file is only useful when options are not provided')
  end

  if options && multiple && default && !(Array(default) - options).empty?
    raise(ArgumentError, 'conflicting arguments: default should only include elements present in options')
  end

  if multiple && !has_options
    raise(ArgumentError, 'conflicting arguments: options must be provided when multiple is true')
  end

  if !multiple && default.is_a?(Array)
    raise(ArgumentError, 'conflicting arguments: multiple defaults may only be provided when multiple is true')
  end

  if has_options
    ask_interactive(
      question,
      options,
      multiple: multiple,
      default: default,
      filter_ui: filter_ui,
      select_ui: select_ui,
      &options_proc
    )
  else
    ask_free_form(
      question,
      default, #: as String?
      is_file,
      allow_empty,
    )
  end
end

.ask_password(question) ⇒ Object

Asks the user for a single-line answer, without displaying the characters while typing. Typically used for password prompts

Return Value

The password, without a trailing newline. If the user simply presses “Enter” without typing any password, this will return an empty string. : (String question) -> String



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/cli/ui/prompt.rb', line 159

def ask_password(question)
  require 'io/console'

  CLI::UI::StdoutRouter::Capture.in_alternate_screen do
    $stdout.print(CLI::UI.fmt('{{?}} ' + question)) # Do not use puts_question to avoid the new line.

    # noecho interacts poorly with Readline under system Ruby, so do a manual `gets` here.
    # No fancy Readline integration (like echoing back) is required for a password prompt anyway.
    password = $stdin.noecho do
      # Chomp will remove the one new line character added by `gets`, without touching potential extra spaces:
      # " 123 \n".chomp => " 123 "
      $stdin.gets.to_s.chomp
    end

    $stdout.puts # Complete the line

    password
  end
end

.confirm(question, default: true) ⇒ Object

Asks the user a yes/no question. Can use arrows, y/n, numbers (1/2), and vim bindings to control

Example Usage:

Confirmation question

CLI::UI::Prompt.confirm('Is the sky blue?')

CLI::UI::Prompt.confirm('Do a dangerous thing?', default: false)

: (String question, ?default: bool) -> bool



190
191
192
# File 'lib/cli/ui/prompt.rb', line 190

def confirm(question, default: true)
  ask_interactive(question, default ? ['yes', 'no'] : ['no', 'yes'], filter_ui: false) == 'yes'
end

.instructions_colorObject

: -> Color



20
21
22
# File 'lib/cli/ui/prompt.rb', line 20

def instructions_color
  @instructions_color ||= Color::YELLOW
end

.instructions_color=(color) ⇒ Object

Set the instructions color.

Attributes

  • color - the color to use for prompt instructions

: (colorable color) -> void



31
32
33
# File 'lib/cli/ui/prompt.rb', line 31

def instructions_color=(color)
  @instructions_color = CLI::UI.resolve_color(color)
end

.read_charObject

Wait for any key to be pressed, returning the pressed key. : -> String?



211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/cli/ui/prompt.rb', line 211

def read_char
  CLI::UI::StdoutRouter::Capture.in_alternate_screen do
    if $stdin.tty? && !ENV['TEST']
      require 'io/console'
      $stdin.getch # raw mode for tty
    else
      $stdin.getc # returns nil at end of input
    end
  end
rescue Errno::EIO, Errno::EPIPE, IOError
  "\e"
end