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

Class Method Summary collapse

Class Method Details

.ask(question, options: nil, default: nil, is_file: nil, 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

95
96
97
98
99
100
101
102
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
# File 'lib/cli/ui/prompt.rb', line 95

def ask(
  question,
  options: nil,
  default: nil,
  is_file: nil,
  allow_empty: true,
  multiple: false,
  filter_ui: true,
  select_ui: true,
  &options_proc
)
  if (options || block_given?) && ((default && !multiple) || is_file)
    raise(ArgumentError, 'conflicting arguments: options provided with default or is_file')
  end

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

  if options || block_given?
    ask_interactive(
      question,
      options,
      multiple: multiple,
      default: default,
      filter_ui: filter_ui,
      select_ui: select_ui,
      &options_proc
    )
  else
    ask_free_form(question, default, 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.


136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/cli/ui/prompt.rb', line 136

def ask_password(question)
  require 'io/console'

  CLI::UI.with_frame_color(:blue) 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.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)

166
167
168
# File 'lib/cli/ui/prompt.rb', line 166

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