Module: Planter::Prompt

Included in:
Planter
Defined in:
lib/planter/prompt.rb

Overview

Individual question

Defined Under Namespace

Classes: Question

Class Method Summary collapse

Class Method Details

.choice(choices, prompt = 'Make a selection', default_response: nil) ⇒ String

Choose from an array of multiple choices. Letter surrounded in parenthesis becomes character for response. Only one letter should be specified per choice and must be unique.

Parameters:

  • choices (Array)

    The choices

  • prompt (String) (defaults to: 'Make a selection')

    The prompt

  • default_response (String) (defaults to: nil)

    The character of the default response

Returns:

  • (String)

    string of selected response with parenthesis removed



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
# File 'lib/planter/prompt.rb', line 274

def self.choice(choices, prompt = 'Make a selection', default_response: nil)
  $stdin.reopen('/dev/tty')

  choices = choices.choices_to_hash if choices.is_a?(Array) && choices.first.is_a?(Hash)

  if choices.is_a?(Hash)
    choices.stringify!
    numeric = choices.keys.first =~ /^\(?\d+\.?\)? /
    keys = choices.keys.to_options(numeric)
    values = choices.values.map(&:clean_value)
    choices = choices.keys
  else
    numeric = choices.first =~ /^\(?\d+\.?\)? /
    keys = choices.to_options(numeric)
    values = choices.to_values.map(&:clean_value)
  end

  die('Choice(s) without selector, please edit config') unless keys.all?(&:selector?)

  default = case default_response.to_s
            when /^\d+$/
              values[default.to_i]
            when /^[a-z]$/i
              keys.include?(default_response) ? values[keys.index(default_response)] : nil
            end

  # If --defaults is set or not an interactive shell, return default
  return default if Planter.accept_defaults || ENV['PLANTER_DEBUG'] || !$stdout.isatty

  default = default_response.to_s if default_response

  # clear the buffer
  if ARGV&.length
    ARGV.length.times do
      ARGV.shift
    end
  end
  system 'stty cbreak'

  vertical = numeric || choices.join(', ').length + 4 > TTY::Screen.cols

  desc = keys.map { |c| c.highlight_character(default: default) }
  abbr = keys.abbr_choices(default: default)

  options = if vertical
              "{x}#{desc.join("\n")}\n{by}#{prompt}{x} #{abbr}{bw}? "
            else
              "{by}#{prompt}{bw}?\n#{desc.join(', ')}{x} #{abbr}:{x} "
            end

  $stdout.syswrite options.x

  res = if numeric && choices.length > 9
          $stdin.sysread choices.length.to_s.length
        else
          $stdin.sysread 1
        end

  puts
  system 'stty cooked'

  res.chomp!
  res.downcase!

  res = res.empty? ? default : res

  return choice(choices, prompt, default_response: default_response) if res.nil? || res.empty?

  if res.to_i.positive?
    values[res.to_i - 1]
  elsif res =~ /^[a-z]/ && keys&.option_index(res)
    values[keys.option_index(res)]
  end
end

.file_what?(entry) ⇒ Symbol

Determine what to do with a file

Parameters:

Returns:

  • (Symbol)

    :merge, :overwrite, :copy, :ignore



355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
# File 'lib/planter/prompt.rb', line 355

def self.file_what?(entry)
  options = %w[(o)vewrite (m)erge]
  options << '(c)opy' unless File.exist?(entry.target)
  options << '(i)gnore'
  opt = Prompt.choice(options, "What do you want to do with #{File.basename(entry.target)}", default_response: 'i')
  case opt
  when /^m/
    :merge
  when /^o/
    :overwrite
  when /^c/
    :copy
  else
    :ignore
  end
end

.yn(question, default_response: false) ⇒ Boolean

Ask a yes or no question in the terminal

Parameters:

  • question (String)

    The question to ask

  • default_response (Boolean) (defaults to: false)

    default response if no input

Returns:

  • (Boolean)

    yes or no



382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
# File 'lib/planter/prompt.rb', line 382

def self.yn(question, default_response: false)
  $stdin.reopen('/dev/tty')

  default = if default_response.is_a?(String)
              default_response =~ /y/i ? true : false
            else
              default_response
            end

  # if PLANTER_DEBUG is set, answer default
  return true if ENV['PLANTER_DEBUG']

  # if this isn't an interactive shell, answer default
  return default unless $stdout.isatty

  # If --defaults is set, return default
  return default if Planter.accept_defaults

  # clear the buffer
  if ARGV&.length
    ARGV.length.times do
      ARGV.shift
    end
  end
  system 'stty cbreak'

  options = if default.nil?
              '{w}[{bw}y{w}/{bw}n{w}]'
            else
              "{w}[#{default ? '{bg}Y{w}/{bw}n' : '{bw}y{w}/{bg}N'}{w}]"
            end

  $stdout.syswrite "{bw}#{question.sub(/\?$/, '')} #{options}{bw}? {x}".x
  res = $stdin.sysread 1
  puts
  system 'stty cooked'

  res.chomp!
  res.downcase!

  return default if res.empty?

  res =~ /y/i ? true : false
end