utility_belt 1.0.6 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. data/bin/amazon +4 -5
  2. data/bin/google +5 -16
  3. data/bin/pastie +6 -0
  4. data/lib/utility_belt.rb +13 -30
  5. data/lib/utility_belt/amazon_upload_shortcut.rb +25 -0
  6. data/lib/utility_belt/clipboard.rb +52 -0
  7. data/lib/{command_history.rb → utility_belt/command_history.rb} +20 -5
  8. data/lib/utility_belt/convertable_to_file.rb +34 -0
  9. data/lib/utility_belt/equipper.rb +72 -0
  10. data/lib/utility_belt/google.rb +33 -0
  11. data/lib/utility_belt/hash_math.rb +10 -0
  12. data/lib/utility_belt/interactive_editor.rb +78 -0
  13. data/lib/{irb_options.rb → utility_belt/irb_options.rb} +0 -0
  14. data/lib/{irb_verbosity_control.rb → utility_belt/irb_verbosity_control.rb} +0 -0
  15. data/lib/{is_an.rb → utility_belt/is_an.rb} +0 -0
  16. data/lib/{language_greps.rb → utility_belt/language_greps.rb} +0 -0
  17. data/lib/{not.rb → utility_belt/not.rb} +0 -0
  18. data/lib/utility_belt/pastie.rb +33 -0
  19. data/lib/utility_belt/pipe.rb +24 -0
  20. data/lib/utility_belt/prompt.rb +1 -0
  21. data/lib/{rails_finder_shortcut.rb → utility_belt/rails_finder_shortcut.rb} +0 -0
  22. data/lib/{rails_verbosity_control.rb → utility_belt/rails_verbosity_control.rb} +0 -0
  23. data/lib/{string_to_proc.rb → utility_belt/string_to_proc.rb} +0 -0
  24. data/lib/{symbol_to_proc.rb → utility_belt/symbol_to_proc.rb} +0 -0
  25. data/lib/{themes.rb → utility_belt/wirble.rb} +4 -0
  26. data/lib/{with.rb → utility_belt/with.rb} +0 -0
  27. data/spec/convertable_to_file_spec.rb +31 -0
  28. data/spec/equipper_spec.rb +70 -0
  29. data/spec/hash_math_spec.rb +32 -0
  30. data/spec/interactive_editor_spec.rb +146 -0
  31. data/{test → spec}/language_greps_spec.rb +3 -2
  32. data/spec/pastie_spec.rb +92 -0
  33. data/spec/pipe_spec.rb +30 -0
  34. data/spec/spec_helper.rb +8 -0
  35. data/{test → spec}/string_to_proc_spec.rb +2 -1
  36. data/{test → spec}/utility_belt_spec.rb +1 -0
  37. data/utility_belt.gemspec +5 -5
  38. metadata +42 -29
  39. data/Rakefile +0 -20
  40. data/lib/amazon_upload_shortcut.rb +0 -18
  41. data/lib/hash_math.rb +0 -13
  42. data/lib/interactive_editor.rb +0 -42
  43. data/lib/mac_clipboard.rb +0 -15
  44. data/lib/pastie.rb +0 -15
  45. data/test/hash_math_spec.rb +0 -16
data/bin/amazon CHANGED
@@ -8,11 +8,10 @@ filenames = option_parser.parse(ARGV)
8
8
  abort "Usage: amazon -b bucket_name file_name" unless @bucket && filenames
9
9
 
10
10
  # require files, populate hash
11
- UTILITY_BELT_IRB_STARTUP_PROCS = {}
12
- utility_belt_lib = File.dirname(__FILE__) + '/../lib'
13
- require "#{utility_belt_lib}/mac_clipboard"
14
- require "#{utility_belt_lib}/amazon_upload_shortcut"
15
- UTILITY_BELT_IRB_STARTUP_PROCS[:define_s3_convenience_methods].call
11
+ require 'utility_belt'
12
+ UtilityBelt.equip(:amazon_upload_shortcut)
13
+ UtilityBelt.equip(:clipboard)
14
+ include UtilityBelt::AmazonUploadShortcut
16
15
 
17
16
  # baddabing, baddaboom
18
17
  filenames.each {|filename| puts aws_upload(@bucket, filename)}
data/bin/google CHANGED
@@ -1,18 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
- %w{rubygems platform cgi}.each {|library| require library}
2
+ %w{rubygems platform net/http utility_belt}.each {|library| require library}
3
3
 
4
- if :macosx != Platform::IMPL
5
- abort "Utility Belt's command-line Google shortcut only works on OS X. Sorry."
6
- else
7
- require "#{File.dirname(__FILE__) + '/../lib'}/mac_clipboard"
8
- search_term = ARGV[0] || MacClipboard.read
9
- if search_term.empty?
10
- puts "Usage: google search_term_without_spaces"
11
- puts " google 'search term with spaces'"
12
- puts " google"
13
- puts " (if invoking without command-line args, must have text in clipboard)"
14
- puts " (if you're seeing this there's a good chance you copied an image or something)"
15
- exit
16
- end
17
- system("open http://google.com/search?q=#{CGI.escape(search_term)}")
18
- end
4
+ UtilityBelt.equip(:google)
5
+ include UtilityBelt::Google
6
+
7
+ google(ARGV[0])
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ %w{rubygems utility_belt}.each {|library| require library}
3
+ UtilityBelt.equip(:pastie)
4
+ include UtilityBelt::Pastie
5
+
6
+ pastie(ARGV[0])
@@ -3,37 +3,20 @@
3
3
  # Check that file for usage information, authorship, copyright, and extensive details. You can also find a
4
4
  # nice, HTMLified version of the README content at http://utilitybelt.rubyforge.org.
5
5
 
6
- UTILITY_BELT_IRB_STARTUP_PROCS = {}
6
+ UTILITY_BELT_IRB_STARTUP_PROCS = {} unless Object.const_defined? :UTILITY_BELT_IRB_STARTUP_PROCS
7
7
 
8
- %w{rubygems
9
- platform
10
- wirble
11
- net/http
12
- tempfile}.each {|library| require library}
13
- %w{init colorize}.each {|message| Wirble.send(message)}
14
- %w{mac_clipboard
15
- is_an
16
- pastie
17
- themes
18
- irb_verbosity_control
19
- rails_verbosity_control
20
- command_history
21
- not
22
- language_greps
23
- rails_finder_shortcut
24
- amazon_upload_shortcut
25
- irb_options
26
- interactive_editor
27
- string_to_proc
28
- symbol_to_proc
29
- hash_math
30
- with}.each {|internal_library| require internal_library}
8
+ %w{rubygems utility_belt/equipper}.each {|internal_library| require internal_library}
31
9
 
32
- # default: dark background
33
- UtilityBelt::Themes.background(:dark)
10
+ if Object.const_defined? :IRB
34
11
 
35
- # Called when the irb session is ready, after any external libraries have been loaded. I can't
36
- # remember why I did this. it might be a cargo cult thing.
37
- IRB.conf[:IRB_RC] = lambda do
38
- UTILITY_BELT_IRB_STARTUP_PROCS.each {|symbol, proc| proc.call}
12
+ # Called when the irb session is ready, after any external libraries have been loaded. This
13
+ # allows the user to specify which gadgets in the utility belt to equip. (Kind of pushing the
14
+ # metaphor, but hey, what the hell.)
15
+ IRB.conf[:IRB_RC] = lambda do
16
+ UtilityBelt.equip(:defaults) unless UtilityBelt.equipped?
17
+ UTILITY_BELT_IRB_STARTUP_PROCS.each {|symbol, proc| proc.call}
18
+ end
19
+
20
+ # default: dark background
21
+ UtilityBelt::Themes.background(:dark) if defined? UtilityBelt::Themes
39
22
  end
@@ -0,0 +1,25 @@
1
+ # S3 (http://amazon.rubyforge.org/)
2
+ %w{aws/s3 cgi platform}.each {|lib| require lib}
3
+
4
+ module UtilityBelt
5
+ module AmazonUploadShortcut
6
+ def aws_upload(bucket,filename)
7
+ AWS::S3::Base.establish_connection!(:access_key_id => ENV['AMAZON_ACCESS_KEY_ID'],
8
+ :secret_access_key => ENV['AMAZON_SECRET_ACCESS_KEY'])
9
+ AWS::S3::S3Object.store(filename, open(filename), bucket, :access => :public_read)
10
+ url = "http://s3.amazonaws.com/#{bucket}/#{filename}".gsub(/ /, "%20")
11
+ Clipboard.write(url) if Clipboard.available?
12
+ url
13
+ end
14
+ end
15
+ end
16
+
17
+ class Object
18
+ include UtilityBelt::AmazonUploadShortcut
19
+ end if Object.const_defined? :IRB
20
+
21
+ # a quick note: the "google" command uses CGI.escape, but the URLs produced by CGI.escape
22
+ # don't seem to succeed here, in practice. this may differ by OS and/or browser. Let me
23
+ # know if you see something weird -- the Utility Belt mailing list is here:
24
+ #
25
+ # http://rubyforge.org/mailman/listinfo/utilitybelt-tinkering
@@ -0,0 +1,52 @@
1
+ # original clipboard code: http://project.ioni.st/post/1334#snippet_1334
2
+ # turned it into a class to make it flexxy:
3
+ # http://gilesbowkett.blogspot.com/2007/09/improved-auto-pastie-irb-code.html
4
+ # Extended to handle windows and linux as well
5
+ require 'platform'
6
+
7
+ module UtilityBelt
8
+ class Clipboard
9
+
10
+ def self.available?
11
+ @@implemented || false
12
+ end
13
+
14
+ case Platform::IMPL
15
+ when :macosx
16
+
17
+ def self.read
18
+ IO.popen('pbpaste') {|clipboard| clipboard.read}
19
+ end
20
+
21
+ def self.write(stuff)
22
+ IO.popen('pbcopy', 'w+') {|clipboard| clipboard.write(stuff)}
23
+ end
24
+ @@implemented = true
25
+
26
+ when :mswin
27
+
28
+ begin
29
+ # Try loading the win32-clipboard gem
30
+ require 'win32/clipboard'
31
+
32
+ def self.read
33
+ Win32::Clipboard.data
34
+ end
35
+
36
+ def self.write(stuff)
37
+ Win32::Clipboard.set_data(stuff)
38
+ end
39
+ @@implemented = true
40
+
41
+ rescue LoadError
42
+ raise "You need the win32-clipboard gem for clipboard functionality!"
43
+ end
44
+
45
+ else
46
+ raise "No suitable clipboard implementation for your platform found!"
47
+ end
48
+
49
+ end
50
+ end
51
+
52
+ Clipboard = UtilityBelt::Clipboard if Object.const_defined? :IRB
@@ -23,6 +23,8 @@
23
23
  # $Id: history.rb 50 2007-07-30 18:55:09Z ben $
24
24
  #
25
25
 
26
+ require 'tempfile'
27
+
26
28
  class Object
27
29
  def history(how_many = 50)
28
30
  history_size = Readline::HISTORY.size
@@ -54,15 +56,28 @@ class Object
54
56
  end
55
57
  file.close
56
58
  end
59
+
60
+ # hack to handle JRuby bug
61
+ def handling_jruby_bug(&block)
62
+ if RUBY_PLATFORM =~ /java/
63
+ puts "JRuby IRB has a bug which prevents successful IRB vi interoperation."
64
+ puts "The JRuby team is aware of this and working on it."
65
+ puts "(http://jira.codehaus.org/browse/JRUBY-2049)"
66
+ else
67
+ yield
68
+ end
69
+ end
57
70
 
58
71
  # TODO: history_write should go to a file, or the clipboard, or a file which opens in an application
59
72
  def history_to_vi
60
- file = Tempfile.new("irb_tempfile")
61
- get_lines(0..(Readline::HISTORY.size - 1)).each do |line|
62
- file << "#{line}\n"
73
+ handling_jruby_bug do
74
+ file = Tempfile.new("irb_tempfile")
75
+ get_lines(0..(Readline::HISTORY.size - 1)).each do |line|
76
+ file << "#{line}\n"
77
+ end
78
+ file.close
79
+ system("vim #{file.path}")
63
80
  end
64
- file.close
65
- system("vim #{file.path}")
66
81
  end
67
82
  alias :hvi :history_to_vi
68
83
 
@@ -0,0 +1,34 @@
1
+ require 'tempfile'
2
+
3
+ # This module adds a method, #to_file, which dumps the contents of self into a
4
+ # temp file and then returns the path of that file. This is particularly useful
5
+ # when calling out to shell commands which expect their input in the form of
6
+ # files.
7
+ #
8
+ # Example: use UNIX 'diff' to compare two objects:
9
+ #
10
+ # >> a = ["foo", "bar", "baz"].join("\n")
11
+ # => "foo\nbar\nbaz"
12
+ # >> b = ["foo", "buz", "baz"].join("\n")
13
+ # => "foo\nbuz\nbaz"
14
+ # >> puts `diff #{a.to_file} #{b.to_file}`
15
+ # 2c2
16
+ # < bar
17
+ # ---
18
+ # > buz
19
+ # => nil
20
+ #
21
+ module ConvertableToFile
22
+ def to_file
23
+ path = nil
24
+ Tempfile.open(object_id.to_s) do |tempfile|
25
+ tempfile << self
26
+ path = tempfile.path
27
+ end
28
+ path
29
+ end
30
+ end
31
+
32
+ class Object
33
+ include ConvertableToFile
34
+ end
@@ -0,0 +1,72 @@
1
+ # Allow to select which gadgets to equip
2
+ #
3
+ # Author: Markus Prinz <markus.prinz@qsig.org>
4
+
5
+ module UtilityBelt
6
+ class << self
7
+ def equip(*args)
8
+ Equipper.equip(*args)
9
+ end
10
+ def equipped?
11
+ Equipper.equipped?
12
+ end
13
+ end
14
+ module Equipper
15
+ GADGETS = Dir[File.join(File.dirname(__FILE__), '*.rb')].map{|file| File.basename(file)[0..-4]}.reject{|gadget| "equipper" == gadget }
16
+
17
+ DEFAULTS = %w{wirble
18
+ hash_math
19
+ command_history
20
+ interactive_editor
21
+ irb_options
22
+ irb_verbosity_control}
23
+
24
+ @equipped = false
25
+
26
+ class << self
27
+ def equip(*args)
28
+ return if args.empty?
29
+
30
+ gadgets_to_equip = []
31
+
32
+ # Special case using :all or :none
33
+ if args[0].is_a?(Symbol) && [:all, :none, :defaults].include?(args[0])
34
+ what = args[0]
35
+
36
+ unless args[1].nil?
37
+ exceptions = args[1].has_key?(:except) ? args[1][:except] : []
38
+
39
+ # Handle special case where we get a string or a symbol instead of an array
40
+ exceptions = exceptions.to_s.to_a unless exceptions.is_a?( Array )
41
+ else
42
+ exceptions = []
43
+ end
44
+
45
+ case what
46
+ when :all
47
+ gadgets_to_equip.push(*(GADGETS - exceptions))
48
+ when :none
49
+ gadgets_to_equip.push(*exceptions)
50
+ when :defaults
51
+ gadgets_to_equip.push(*DEFAULTS)
52
+ end
53
+ # otherwise, args is a list of gadgets to equip
54
+ else
55
+ args.each do |arg|
56
+ gadget = arg.to_s
57
+
58
+ # Silently ignore unkown gadgets
59
+ gadgets_to_equip << gadget if GADGETS.include? gadget
60
+ end
61
+ end
62
+
63
+ gadgets_to_equip.each{|gadget| require "utility_belt/#{gadget}" }
64
+
65
+ @equipped ||= true
66
+ end
67
+ def equipped?
68
+ @equipped
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ %w{rubygems platform cgi}.each {|library| require library}
3
+
4
+ UtilityBelt.equip(:clipboard)
5
+
6
+ module UtilityBelt
7
+ module Google
8
+ def google(search_term = nil)
9
+ search_term ||= Clipboard.read if Clipboard.available?
10
+ if search_term.empty?
11
+ puts "Usage: google search_term_without_spaces (Unix command line only)"
12
+ puts " google 'search term with spaces' (Unix or IRB)"
13
+ puts " google (Unix or IRB)"
14
+ puts " (if invoking without args, must have text in clipboard)"
15
+ else
16
+ url = "http://google.com/search?q=#{CGI.escape(search_term)}"
17
+ case Platform::IMPL
18
+ when :macosx
19
+ Kernel.system("open #{url}")
20
+ when :windows
21
+ Kernel.system("start #{url}")
22
+ #when :linux
23
+ else
24
+ puts "Sorry, don't know how to open an URL from the command line on your platform"
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ class Object
32
+ include UtilityBelt::Google
33
+ end if Object.const_defined? :IRB
@@ -0,0 +1,10 @@
1
+ class Hash
2
+ alias :+ :merge
3
+ def -(other)
4
+ if other.is_a? Hash
5
+ reject { |k,v| other[k] == v }
6
+ else
7
+ reject { |k,v| k == other }
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,78 @@
1
+ # Giles Bowkett, Greg Brown, and several audience members from Giles' Ruby East presentation.
2
+ require 'tempfile'
3
+ class InteractiveEditor
4
+ DEBIAN_SENSIBLE_EDITOR = "/usr/bin/sensible-editor"
5
+ MACOSX_OPEN_CMD = "open"
6
+ XDG_OPEN = "/usr/bin/xdg-open"
7
+
8
+ def self.sensible_editor
9
+ return ENV["VISUAL"] if ENV["VISUAL"]
10
+ return ENV["EDITOR"] if ENV["EDITOR"]
11
+ return MACOSX_OPEN_CMD if Platform::IMPL == :macosx
12
+ if Platform::IMPL == :linux
13
+ if File.executable?(XDG_OPEN)
14
+ return XDG_OPEN
15
+ end
16
+ if File.executable?(DEBIAN_SENSIBLE_EDITOR)
17
+ return DEBIAN_SENSIBLE_EDITOR
18
+ end
19
+ end
20
+ raise "Could not determine what editor to use. Please specify."
21
+ end
22
+
23
+ attr_accessor :editor
24
+ def initialize(editor = :vim)
25
+ @editor = editor.to_s
26
+ if @editor == "mate"
27
+ @editor = "mate -w"
28
+ end
29
+ end
30
+ def edit_interactively
31
+ unless @file
32
+ @file = Tempfile.new("irb_tempfile")
33
+ end
34
+ system("#{@editor} #{@file.path}")
35
+ Object.class_eval(`cat #{@file.path}`)
36
+ rescue Exception => error
37
+ puts error
38
+ end
39
+ end
40
+
41
+ module InteractiveEditing
42
+ def edit_interactively(editor = InteractiveEditor.sensible_editor)
43
+ unless IRB.conf[:interactive_editors] && IRB.conf[:interactive_editors][editor]
44
+ IRB.conf[:interactive_editors] ||= {}
45
+ IRB.conf[:interactive_editors][editor] = InteractiveEditor.new(editor)
46
+ end
47
+ IRB.conf[:interactive_editors][editor].edit_interactively
48
+ end
49
+
50
+ def handling_jruby_bug(&block)
51
+ if RUBY_PLATFORM =~ /java/
52
+ puts "JRuby IRB has a bug which prevents successful IRB vi/emacs editing."
53
+ puts "The JRuby team is aware of this and working on it."
54
+ puts "(http://jira.codehaus.org/browse/JRUBY-2049)"
55
+ else
56
+ yield
57
+ end
58
+ end
59
+
60
+ def vi
61
+ handling_jruby_bug {edit_interactively(:vim)}
62
+ end
63
+
64
+ def mate
65
+ edit_interactively(:mate)
66
+ end
67
+
68
+ # TODO: Hardcore Emacs users use emacsclient or gnuclient to open documents in
69
+ # their existing sessions, rather than starting a brand new Emacs process.
70
+ def emacs
71
+ handling_jruby_bug {edit_interactively(:emacs)}
72
+ end
73
+ end
74
+
75
+ # Since we only intend to use this from the IRB command line, I see no reason to
76
+ # extend the entire Object class with this module when we can just extend the
77
+ # IRB main object.
78
+ self.extend InteractiveEditing if Object.const_defined? :IRB