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

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/cli/ui/prompt.rb', line 80

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.


121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/cli/ui/prompt.rb', line 121

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)

151
152
153
# File 'lib/cli/ui/prompt.rb', line 151

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