Module: Commander::UI

Defined in:
lib/commander/user_interaction.rb

Overview

User Interaction

Commander’s user interaction module mixes in common methods which extend HighLine’s functionality such as a #password method rather than calling #ask directly.

Defined Under Namespace

Modules: AskForClass Classes: ProgressBar

Class Method Summary collapse

Class Method Details

.applescript(script) ⇒ Object

Execute apple script.



183
184
185
# File 'lib/commander/user_interaction.rb', line 183

def applescript script
  `osascript -e "#{ script.gsub('"', '\"') }"`
end

.ask_editor(input = nil, editor = ENV['EDITOR'] || 'mate') ⇒ Object

Prompt editor for input. Optionally supply initial input which is written to the editor.

The editor defaults to the EDITOR environment variable when present, or ‘mate’ for TextMate.

Examples

ask_editor                # => prompts EDITOR with no input
ask_editor('foo')         # => prompts EDITOR with default text of 'foo'
ask_editor('foo', :mate)  # => prompts TextMate with default text of 'foo'


242
243
244
245
246
247
248
# File 'lib/commander/user_interaction.rb', line 242

def ask_editor input = nil, editor = ENV['EDITOR'] || 'mate'
  IO.popen(editor.to_s, 'w+') do |pipe|
    pipe.puts input.to_s unless input.nil?
    pipe.close_write
    pipe.read
  end
end

.choose(message, *choices) ⇒ Object

Choose from a set array of choices.



41
42
43
44
# File 'lib/commander/user_interaction.rb', line 41

def choose message, *choices
  say message
  super *choices
end

.color(*args) ⇒ Object

‘Say’ something using the specified color

Examples

color 'I am blue', :blue
color 'I am bold', :bold
color 'White on Red', :white, :on_red

Notes

You may use:
* color:    black blue cyan green magenta red white yellow
* style:    blink bold clear underline
* highligh: on_<color>


115
116
117
# File 'lib/commander/user_interaction.rb', line 115

def color(*args)
  say $terminal.color(*args)
end

.converse(prompt, responses = {}) ⇒ Object

Converse with speech recognition.

Currently a “poorman’s” DSL to utilize applescript and the MacOS speech recognition server.

Examples

case converse 'What is the best food?', :cookies => 'Cookies', :unknown => 'Nothing'
when :cookies 
  speak 'o.m.g. you are awesome!'
else
  case converse 'That is lame, shall I convince you cookies are the best?', :yes => 'Ok', :no => 'No', :maybe => 'Maybe another time'
  when :yes
    speak 'Well you see, cookies are just fantastic.'
  else
    speak 'Ok then, bye.'
  end
end

Notes

  • MacOS only



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/commander/user_interaction.rb', line 163

def converse prompt, responses = {}
  i, commands = 0, responses.map { |key, value| value.inspect }.join(',')
  statement = responses.inject '' do |statement, (key, value)|
    statement << (((i += 1) == 1 ? 
      %(if response is "#{value}" then\n):
        %(else if response is "#{value}" then\n))) <<
          %(do shell script "echo '#{key}'"\n)
  end
  applescript(%(
    tell application "SpeechRecognitionServer" 
      set response to listen for {#{commands}} with prompt "#{prompt}"
      #{statement}
      end if
    end tell
  )).strip.to_sym
end

.enable_pagingObject

Enable paging of output after called.



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/commander/user_interaction.rb', line 253

def enable_paging
  return unless $stdout.tty?
  return if Platform::jruby? # Fork is not supported by JRuby
  read, write = IO.pipe

  if Kernel.fork
    $stdin.reopen read
    read.close; write.close
    Kernel.select [$stdin]
    ENV['LESS'] = 'FSRX'
    pager = ENV['PAGER'] || 'less'
    exec pager rescue exec '/bin/sh', '-c', pager
  else
    $stdout.reopen write
    $stderr.reopen write if $stderr.tty?
    read.close; write.close
    return
  end
end

.io(input = nil, output = nil, &block) ⇒ Object

Normalize IO streams, allowing for redirection of input and/or output, for example:

$ foo              # => read from terminal I/O
$ foo in           # => read from 'in' file, output to terminal output stream
$ foo in out       # => read from 'in' file, output to 'out' file
$ foo < in > out   # => equivalent to above (essentially)

Optionally a block may be supplied, in which case IO will be reset once the block has executed.

Examples

command :foo do |c|
  c.syntax = 'foo [input] [output]'
  c.when_called do |args, options|
    # or io(args.shift, args.shift)
    io *args
    str = $stdin.gets
    puts 'input was: ' + str.inspect
  end
end


212
213
214
215
216
217
218
219
# File 'lib/commander/user_interaction.rb', line 212

def io input = nil, output = nil, &block
  $stdin = File.new(input) if input
  $stdout = File.new(output, 'r+') if output
  if block
    yield
    reset_io
  end
end

.log(action, *args) ⇒ Object

‘Log’ an action to the terminal. This is typically used for verbose output regarding actions performed. For example:

create  path/to/file.rb
remove  path/to/old_file.rb
remove  path/to/old_file2.rb


55
56
57
# File 'lib/commander/user_interaction.rb', line 55

def log action, *args
  say '%15s  %s' % [action, args.join(' ')]
end

.password(message = 'Password: ', mask = '*') ⇒ Object

Ask the user for a password. Specify a custom message other than ‘Password: ’ or override the default mask of ‘*’.



32
33
34
35
36
# File 'lib/commander/user_interaction.rb', line 32

def password message = 'Password: ', mask = '*'
  pass = ask(message) { |q| q.echo = mask }
  pass = password message, mask if pass.nil? || pass.empty?
  pass
end

.progress(arr, options = {}, &block) ⇒ Object

Output progress while iterating arr.

Examples

uris = %w( http://vision-media.ca http://google.com )
progress uris, :format => "Remaining: :time_remaining" do |uri|
  res = open uri
end


284
285
286
287
288
# File 'lib/commander/user_interaction.rb', line 284

def progress arr, options = {}, &block
  bar = ProgressBar.new arr.length, options
  bar.show
  arr.each { |v| bar.increment yield(v) }
end

.replace_tokens(str, hash) ⇒ Object

Substitute hash’s keys with their associated values in str.



312
313
314
315
316
# File 'lib/commander/user_interaction.rb', line 312

def replace_tokens str, hash #:nodoc:
  hash.inject str do |str, (key, value)|
    str.gsub ":#{key}", value.to_s
  end
end

.reset_ioObject

Reset IO to initial constant streams.



224
225
226
# File 'lib/commander/user_interaction.rb', line 224

def reset_io
  $stdin, $stdout = STDIN, STDOUT
end

.say_error(*args) ⇒ Object

‘Say’ something using the ERROR color (red).

Examples

say_error 'Everything is not fine'
say_error 'It is not ok', 'This is not ok too'


95
96
97
98
99
# File 'lib/commander/user_interaction.rb', line 95

def say_error *args
  args.each do |arg|
    say $terminal.color(arg, :red)
  end
end

.say_ok(*args) ⇒ Object

‘Say’ something using the OK color (green).

Examples

say_ok 'Everything is fine'
say_ok 'It is ok', 'This is ok too'


67
68
69
70
71
# File 'lib/commander/user_interaction.rb', line 67

def say_ok *args
  args.each do |arg|
    say $terminal.color(arg, :green)
  end
end

.say_warning(*args) ⇒ Object

‘Say’ something using the WARNING color (yellow).

Examples

say_warning 'This is a warning'
say_warning 'Be careful', 'Think about it'


81
82
83
84
85
# File 'lib/commander/user_interaction.rb', line 81

def say_warning *args
  args.each do |arg|
    say $terminal.color(arg, :yellow)
  end
end

.speak(message, voice = :Alex) ⇒ Object

Speak message using voice which defaults to ‘Alex’, which is one of the better voices.

Examples

speak 'What is your favorite food? '
food = ask 'favorite food?: '
speak "wow, I like #{food} too. We have so much alike."

Notes

  • MacOS only



134
135
136
# File 'lib/commander/user_interaction.rb', line 134

def speak message, voice = :Alex
  Thread.new { applescript "say #{message.inspect} using #{voice.to_s.inspect}" }
end