Module: Commander::UI
- Included in:
- Methods
- 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
-
.applescript(script) ⇒ Object
Execute apple script.
-
.ask_editor(input = nil, preferred_editor = nil) ⇒ Object
Prompt an editor for input.
-
.available_editor(preferred = nil) ⇒ Object
Find an editor available in path.
-
.choose(message = nil, *choices, &block) ⇒ Object
Choose from a set array of choices.
-
.color(*args) ⇒ Object
‘Say’ something using the specified color.
-
.converse(prompt, responses = {}) ⇒ Object
Converse with speech recognition.
-
.enable_paging ⇒ Object
Enable paging of output after called.
-
.io(input = nil, output = nil, &block) ⇒ Object
Normalize IO streams, allowing for redirection of
input
and/oroutput
, for example:. -
.log(action, *args) ⇒ Object
‘Log’ an action to the terminal.
-
.password(message = 'Password: ', mask = '*') ⇒ Object
Ask the user for a password.
-
.progress(arr, options = {}) ⇒ Object
Output progress while iterating arr.
-
.replace_tokens(str, hash) ⇒ Object
Substitute hash’s keys with their associated values in str.
-
.say_error(*args) ⇒ Object
‘Say’ something using the ERROR color (red).
-
.say_ok(*args) ⇒ Object
‘Say’ something using the OK color (green).
-
.say_warning(*args) ⇒ Object
‘Say’ something using the WARNING color (yellow).
-
.speak(message, voice = :Alex, rate = 175) ⇒ Object
Speak message using voice at a speaking rate of rate.
Class Method Details
.applescript(script) ⇒ Object
Execute apple script.
193 194 195 |
# File 'lib/commander/user_interaction.rb', line 193 def applescript(script) `osascript -e "#{ script.gsub('"', '\"') }"` end |
.ask_editor(input = nil, preferred_editor = nil) ⇒ Object
Prompt an editor for input. Optionally supply initial input which is written to the editor.
preferred_editor can be hinted.
Examples
ask_editor # => prompts EDITOR with no input
ask_editor('foo') # => prompts EDITOR with default text of 'foo'
ask_editor('foo', 'mate -w') # => prompts TextMate with default text of 'foo'
256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/commander/user_interaction.rb', line 256 def ask_editor(input = nil, preferred_editor = nil) editor = available_editor preferred_editor program = Commander::Runner.instance.program(:name).downcase rescue 'commander' tmpfile = Tempfile.new program begin tmpfile.write input if input tmpfile.close system("#{editor} #{tmpfile.path.shellescape}") ? IO.read(tmpfile.path) : nil ensure tmpfile.unlink end end |
.available_editor(preferred = nil) ⇒ Object
Find an editor available in path. Optionally supply the preferred editor. Returns the name as a string, nil if none is available.
237 238 239 240 241 |
# File 'lib/commander/user_interaction.rb', line 237 def available_editor(preferred = nil) [preferred, ENV['EDITOR'], 'mate -w', 'vim', 'vi', 'emacs', 'nano', 'pico'] .compact .find { |name| system("hash #{name.split.first} 2>&-") } end |
.choose(message = nil, *choices, &block) ⇒ Object
Choose from a set array of choices.
43 44 45 46 |
# File 'lib/commander/user_interaction.rb', line 43 def choose( = nil, *choices, &block) say if super(*choices, &block) 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>
117 118 119 |
# File 'lib/commander/user_interaction.rb', line 117 def color(*args) say HighLine.default_instance.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
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/commander/user_interaction.rb', line 168 def converse(prompt, responses = {}) i, commands = 0, responses.map { |_key, value| value.inspect }.join(',') statement = responses.inject '' do |inner_statement, (key, value)| inner_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_paging ⇒ Object
Enable paging of output after called.
272 273 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 |
# File 'lib/commander/user_interaction.rb', line 272 def enable_paging return unless $stdout.tty? return unless Process.respond_to? :fork read, write = IO.pipe # Kernel.fork is not supported on all platforms and configurations. # As of Ruby 1.9, `Process.respond_to? :fork` should return false on # configurations that don't support it, but versions before 1.9 don't # seem to do this reliably and instead raise a NotImplementedError # (which is rescued below). if Kernel.fork $stdin.reopen read write.close read.close Kernel.select [$stdin] ENV['LESS'] = 'FSRX' unless ENV.key? 'LESS' pager = ENV['PAGER'] || 'less' exec pager rescue exec '/bin/sh', '-c', pager else # subprocess $stdout.reopen write $stderr.reopen write if $stderr.tty? write.close read.close end rescue NotImplementedError ensure write.close if write && !write.closed? read.close if read && !read.closed? 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, |
# or io(args.shift, args.shift)
io *args
str = $stdin.gets
puts 'input was: ' + str.inspect
end
end
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/commander/user_interaction.rb', line 222 def io(input = nil, output = nil, &block) orig_stdin, orig_stdout = $stdin, $stdout $stdin = File.new(input) if input $stdout = File.new(output, 'r+') if output return unless block yield $stdin, $stdout = orig_stdin, orig_stdout reset_io 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
57 58 59 |
# File 'lib/commander/user_interaction.rb', line 57 def log(action, *args) say format('%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 ‘*’.
34 35 36 37 38 |
# File 'lib/commander/user_interaction.rb', line 34 def password( = 'Password: ', mask = '*') pass = ask() { |q| q.echo = mask } pass = password , mask if pass.nil? || pass.empty? pass end |
.progress(arr, options = {}) ⇒ 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
316 317 318 319 320 |
# File 'lib/commander/user_interaction.rb', line 316 def progress(arr, = {}) = ProgressBar.new arr.length, .show arr.each { |v| .increment yield(v) } end |
.replace_tokens(str, hash) ⇒ Object
Substitute hash’s keys with their associated values in str.
374 375 376 377 378 |
# File 'lib/commander/user_interaction.rb', line 374 def replace_tokens(str, hash) #:nodoc: hash.inject(str) do |string, (key, value)| string.gsub ":#{key}", value.to_s end 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'
97 98 99 100 101 |
# File 'lib/commander/user_interaction.rb', line 97 def say_error(*args) args.each do |arg| say HighLine.default_instance.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'
69 70 71 72 73 |
# File 'lib/commander/user_interaction.rb', line 69 def say_ok(*args) args.each do |arg| say HighLine.default_instance.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'
83 84 85 86 87 |
# File 'lib/commander/user_interaction.rb', line 83 def say_warning(*args) args.each do |arg| say HighLine.default_instance.color(arg, :yellow) end end |
.speak(message, voice = :Alex, rate = 175) ⇒ Object
Speak message using voice at a speaking rate of rate
Voice defaults to ‘Alex’, which is one of the better voices. Speaking rate defaults to 175 words per minute
Examples
speak 'What is your favorite food? '
food = ask 'favorite food?: '
speak "Wow, I like #{food} too. We have so much in common."
speak "I like #{food} as well!", "Victoria", 190
Notes
-
MacOS only
139 140 141 |
# File 'lib/commander/user_interaction.rb', line 139 def speak(, voice = :Alex, rate = 175) Thread.new { applescript "say #{.inspect} using #{voice.to_s.inspect} speaking rate #{rate}" } end |