Module: SplttyCLI::Prompt

Defined in:
lib/spltty_cli/prompt.rb

Overview

Minimal stdlib prompts. Prompts render on stderr so stdout stays clean for the final confirmation line; input is read from stdin.

Defined Under Namespace

Classes: Abort

Class Method Summary collapse

Class Method Details

.ask(label, default: nil, required: false) ⇒ Object

Ask for a value. Returns the entered string (or the default when the user just hits enter). With required: true, keeps asking until non-empty. At EOF (piped/no tty) it falls back to the default, or raises when a required value has no default.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/spltty_cli/prompt.rb', line 15

def ask(label, default: nil, required: false)
  loop do
    suffix = default && !default.to_s.empty? ? " [#{default}]" : ""
    $stderr.print "#{label}#{suffix}: "
    raw = $stdin.gets
    if raw.nil?
      return default.to_s if default
      raise Abort, "no input available for required field: #{label}" if required

      return ""
    end
    answer = raw.strip
    answer = default.to_s if answer.empty? && default
    return answer unless required && answer.empty?

    $stderr.puts "  (required)"
  end
end

.choose(label, options, default: 1) ⇒ Object

Pick one of options (an array of labels). Accepts the 1-based number or the label itself (case-insensitive). Returns the 0-based index. Empty input or EOF selects default (which is 1-based, like what's displayed).

Raises:

  • (ArgumentError)


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/spltty_cli/prompt.rb', line 37

def choose(label, options, default: 1)
  raise ArgumentError, "choose needs at least one option" if options.empty?

  loop do
    options.each_with_index { |opt, i| $stderr.puts "  #{i + 1}) #{opt}" }
    $stderr.print "#{label} [#{default}]: "
    raw = $stdin.gets
    return default - 1 if raw.nil?

    answer = raw.strip
    return default - 1 if answer.empty?

    index =
      if answer.match?(/\A\d+\z/)
        i = answer.to_i - 1
        i if i >= 0 && i < options.length
      else
        options.index { |o| o.to_s.casecmp?(answer) }
      end
    return index if index

    $stderr.puts "  (enter a number between 1 and #{options.length}, or the name)"
  end
end

.confirm(label, default: true) ⇒ Object

Yes/no confirmation. Default answer used on empty input or EOF.



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/spltty_cli/prompt.rb', line 63

def confirm(label, default: true)
  suffix = default ? "Y/n" : "y/N"
  $stderr.print "#{label} [#{suffix}]: "
  raw = $stdin.gets
  return default if raw.nil?

  answer = raw.strip.downcase
  return default if answer.empty?

  answer.start_with?("y")
end