Module: Potty::Mouth

Defined in:
lib/potty/mouth.rb

Overview

potty’s batteries-included inline helpers — quick terminal I/O that hides the Application/View machinery and hands you back a value:

Potty::Mouth.say("deploying…", :info)        # styled output, no app
name = Potty::Mouth.ask("Your name?")        # (with listen mode) -> String
ok   = Potty::Mouth.confirm("Proceed?")      # -> true/false

This is a convenience layer *built on* Application.new(mode: :inline), not a second way to run views — to run your own inline View, use the inline Application directly. Colour is dropped when output isn’t a TTY, so logs stay clean.

Defined Under Namespace

Modules: Prompt

Class Method Summary collapse

Class Method Details

.ask(prompt, default: '', theme: nil, out: $stdout, input: $stdin) ⇒ Object

Ask for a line of text inline; returns the entered String, or nil if the user cancels with ESC. Needs a TTY — off a TTY (pipe/cron) it can’t prompt, so it returns ‘default` rather than hanging.



49
50
51
52
53
54
55
# File 'lib/potty/mouth.rb', line 49

def ask(prompt, default: '', theme: nil, out: $stdout, input: $stdin)
  return default unless tty?(input)

  app = inline_app(lines: 2, theme: theme, out: out, input: input)
  app.run(view = Prompt::Ask.new(app, prompt: prompt, default: default))
  view.result
end

.bleep(word, char: '*') ⇒ Object

Censor a word — a potty mouth ought to know how. Keeps the first and last letter, stars the middle. (Purely for the laugh.)



40
41
42
43
44
# File 'lib/potty/mouth.rb', line 40

def bleep(word, char: '*')
  return word if word.length <= 2

  "#{word[0]}#{char * (word.length - 2)}#{word[-1]}"
end

.choose(prompt, options, default: :__first__, theme: nil, out: $stdout, input: $stdin) ⇒ Object

Pick one of ‘options` (values or label:) inline; returns the chosen value, or nil on ESC. Arrows move, Enter picks. Off a TTY, returns `default` (the first option’s value unless given).



70
71
72
73
74
75
76
77
78
# File 'lib/potty/mouth.rb', line 70

def choose(prompt, options, default: :__first__, theme: nil, out: $stdout, input: $stdin)
  unless tty?(input)
    return default == :__first__ ? value_of(options.first) : default
  end

  app = inline_app(lines: options.size + 1, theme: theme, out: out, input: input)
  app.run(view = Prompt::Choose.new(app, prompt: prompt, options: options))
  view.result
end

.confirm(prompt, default: false, theme: nil, out: $stdout, input: $stdin) ⇒ Object

Yes/no inline; returns true/false (ESC or Enter use ‘default`). Off a TTY, returns `default`.



59
60
61
62
63
64
65
# File 'lib/potty/mouth.rb', line 59

def confirm(prompt, default: false, theme: nil, out: $stdout, input: $stdin)
  return default unless tty?(input)

  app = inline_app(lines: 1, theme: theme, out: out, input: input)
  app.run(view = Prompt::Confirm.new(app, prompt: prompt, default: default))
  view.result
end

.inline_app(lines:, theme:, out:, input:) ⇒ Object

Build (not run) a configured inline, listening Application for a prompt.



81
82
83
84
85
# File 'lib/potty/mouth.rb', line 81

def inline_app(lines:, theme:, out:, input:)
  app = Application.new(mode: :inline, listen: true, lines: lines, theme: theme, out: out, input: input)
  app.tick_interval = 50
  app
end

.say(text, color = :normal, bold: false, out: $stdout) ⇒ Object

Print one styled line. ‘color` is a Theme palette name (:info, :success, :error, :warning, :dim, …); unknown names fall back to :normal.



29
30
31
32
33
34
35
36
# File 'lib/potty/mouth.rb', line 29

def say(text, color = :normal, bold: false, out: $stdout)
  if tty?(out)
    out.puts("#{Ansi.sgr(style_for(color, bold))}#{text}#{Ansi::RESET}")
  else
    out.puts(text)
  end
  nil
end

.style_for(color, bold) ⇒ Object



87
88
89
90
# File 'lib/potty/mouth.rb', line 87

def style_for(color, bold)
  c = Theme::PALETTE[color] || Theme::PALETTE[:normal]
  Style.new(fg: c[:fg], bg: c[:bg], bold: bold)
end

.tty?(io) ⇒ Boolean

Returns:

  • (Boolean)


92
93
94
# File 'lib/potty/mouth.rb', line 92

def tty?(io)
  io.respond_to?(:tty?) && io.tty?
end

.value_of(option) ⇒ Object



96
97
98
# File 'lib/potty/mouth.rb', line 96

def value_of(option)
  option.is_a?(Hash) ? option[:value] : option
end