FreedomCoder-utility_belt 1.1.1
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.
- data/History.txt +5 -0
- data/Manifest.txt +7 -0
- data/README +372 -0
- data/bin/amazon +16 -0
- data/bin/google +7 -0
- data/bin/pastie +7 -0
- data/bin/twitt +15 -0
- data/html/andreas00.css +449 -0
- data/html/authorship.html +86 -0
- data/html/bg.gif +0 -0
- data/html/front.jpg +0 -0
- data/html/index.html +81 -0
- data/html/menubg.gif +0 -0
- data/html/menubg2.gif +0 -0
- data/html/test.jpg +0 -0
- data/html/usage.html +298 -0
- data/lib/utility_belt.rb +22 -0
- data/lib/utility_belt/amazon_upload_shortcut.rb +25 -0
- data/lib/utility_belt/clipboard.rb +70 -0
- data/lib/utility_belt/command_history.rb +110 -0
- data/lib/utility_belt/convertable_to_file.rb +34 -0
- data/lib/utility_belt/equipper.rb +71 -0
- data/lib/utility_belt/google.rb +34 -0
- data/lib/utility_belt/hash_math.rb +13 -0
- data/lib/utility_belt/interactive_editor.rb +78 -0
- data/lib/utility_belt/irb_options.rb +3 -0
- data/lib/utility_belt/irb_verbosity_control.rb +30 -0
- data/lib/utility_belt/is_an.rb +4 -0
- data/lib/utility_belt/language_greps.rb +28 -0
- data/lib/utility_belt/not.rb +15 -0
- data/lib/utility_belt/pastie.rb +35 -0
- data/lib/utility_belt/pipe.rb +24 -0
- data/lib/utility_belt/rails_finder_shortcut.rb +18 -0
- data/lib/utility_belt/rails_verbosity_control.rb +8 -0
- data/lib/utility_belt/string_to_proc.rb +72 -0
- data/lib/utility_belt/symbol_to_proc.rb +30 -0
- data/lib/utility_belt/twitty.rb +58 -0
- data/lib/utility_belt/wirble.rb +83 -0
- data/lib/utility_belt/with.rb +21 -0
- data/spec/convertable_to_file_spec.rb +31 -0
- data/spec/equipper_spec.rb +70 -0
- data/spec/hash_math_spec.rb +17 -0
- data/spec/interactive_editor_spec.rb +146 -0
- data/spec/language_greps_spec.rb +9 -0
- data/spec/pastie_spec.rb +92 -0
- data/spec/pipe_spec.rb +30 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/string_to_proc_spec.rb +41 -0
- data/spec/utility_belt_spec.rb +4 -0
- data/utility-belt.gemspec +38 -0
- metadata +145 -0
data/lib/utility_belt.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# This started as my (Giles Bowkett's) .irbrc file, turned into a recipe on IRB for the Pragmatic Programmers,
|
2
|
+
# and soon became a scrapbook of cool code snippets from all over the place. All the RDoc lives in the README.
|
3
|
+
# Check that file for usage information, authorship, copyright, and extensive details. You can also find a
|
4
|
+
# nice, HTMLified version of the README content at http://utilitybelt.rubyforge.org.
|
5
|
+
|
6
|
+
UTILITY_BELT_IRB_STARTUP_PROCS = {} unless Object.const_defined? :UTILITY_BELT_IRB_STARTUP_PROCS
|
7
|
+
|
8
|
+
%w{rubygems active_support utility_belt/equipper}.each {|internal_library| require internal_library}
|
9
|
+
|
10
|
+
if Object.const_defined? :IRB
|
11
|
+
|
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
|
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,70 @@
|
|
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 :linux
|
27
|
+
|
28
|
+
if File.exist?('/usr/bin/xsel') || File.exist?('/usr/local/bin/xsel') || File.exist?('/usr/X11/bin/xsel')
|
29
|
+
|
30
|
+
def self.read
|
31
|
+
IO.popen('xsel') {|clipboard| clipboard.read}
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.write(stuff)
|
35
|
+
IO.popen('xsel -i', 'w+') {|clipboard| clipboard.write(stuff)}
|
36
|
+
end
|
37
|
+
@@implemented = true
|
38
|
+
else
|
39
|
+
raise "You need to install package xsel\n
|
40
|
+
ubuntu,debian: sudo apt-get install xsel\n
|
41
|
+
Gentoo: sudo emerge xsel\n
|
42
|
+
fedora,centos,opensuse: yum install xsel\n"
|
43
|
+
end
|
44
|
+
when :mswin
|
45
|
+
|
46
|
+
begin
|
47
|
+
# Try loading the win32-clipboard gem
|
48
|
+
require 'win32/clipboard'
|
49
|
+
|
50
|
+
def self.read
|
51
|
+
Win32::Clipboard.data
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.write(stuff)
|
55
|
+
Win32::Clipboard.set_data(stuff)
|
56
|
+
end
|
57
|
+
@@implemented = true
|
58
|
+
|
59
|
+
rescue LoadError
|
60
|
+
raise "You need the win32-clipboard gem for clipboard functionality!"
|
61
|
+
end
|
62
|
+
|
63
|
+
else
|
64
|
+
raise "No suitable clipboard implementation for your platform found!"
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
Clipboard = UtilityBelt::Clipboard if Object.const_defined? :IRB
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# history
|
2
|
+
# http://blog.bleything.net/pages
|
3
|
+
# http://gilesbowkett.blogspot.com/2007/06/irbrc-modifications.html
|
4
|
+
# Ben's history stuff, slightly modified, plus hvi method
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
# Adds shell-style history display and replay to irb. The magic happens in
|
9
|
+
# the h, h!, and hw methods.
|
10
|
+
#
|
11
|
+
# == Authors
|
12
|
+
#
|
13
|
+
# * Ben Bleything <ben@bleything.net>
|
14
|
+
#
|
15
|
+
# == Copyright
|
16
|
+
#
|
17
|
+
# Copyright (c) 2007 Ben Bleything
|
18
|
+
#
|
19
|
+
# This code released under the terms of the BSD license.
|
20
|
+
#
|
21
|
+
# == Version
|
22
|
+
#
|
23
|
+
# $Id: history.rb 50 2007-07-30 18:55:09Z ben $
|
24
|
+
#
|
25
|
+
|
26
|
+
require 'tempfile'
|
27
|
+
|
28
|
+
class Object
|
29
|
+
def history(how_many = 50)
|
30
|
+
history_size = Readline::HISTORY.size
|
31
|
+
# no lines, get out of here
|
32
|
+
puts "No history" and return if history_size == 0
|
33
|
+
start_index = 0
|
34
|
+
# not enough lines, only show what we have
|
35
|
+
if history_size <= how_many
|
36
|
+
how_many = history_size - 1
|
37
|
+
end_index = how_many
|
38
|
+
else
|
39
|
+
end_index = history_size - 1 # -1 to adjust for array offset
|
40
|
+
start_index = end_index - how_many
|
41
|
+
end
|
42
|
+
start_index.upto(end_index) {|i| print_line i}
|
43
|
+
end
|
44
|
+
alias :h :history
|
45
|
+
|
46
|
+
# -2 because -1 is ourself
|
47
|
+
def history_do(lines = (Readline::HISTORY.size - 2))
|
48
|
+
irb_eval lines
|
49
|
+
end
|
50
|
+
alias :h! :history_do
|
51
|
+
|
52
|
+
def history_write(filename, lines)
|
53
|
+
file = File.open(filename, 'w')
|
54
|
+
get_lines(lines).each do |l|
|
55
|
+
file << "#{l}\n"
|
56
|
+
end
|
57
|
+
file.close
|
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
|
70
|
+
|
71
|
+
# TODO: history_write should go to a file, or the clipboard, or a file which opens in an application
|
72
|
+
def history_to_vi
|
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}")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
alias :hvi :history_to_vi
|
83
|
+
|
84
|
+
private
|
85
|
+
def get_line(line_number)
|
86
|
+
Readline::HISTORY[line_number] rescue ""
|
87
|
+
end
|
88
|
+
|
89
|
+
def get_lines(lines = [])
|
90
|
+
return [get_line(lines)] if lines.is_a? Fixnum
|
91
|
+
out = []
|
92
|
+
lines = lines.to_a if lines.is_a? Range
|
93
|
+
lines.each do |l|
|
94
|
+
out << Readline::HISTORY[l]
|
95
|
+
end
|
96
|
+
out
|
97
|
+
end
|
98
|
+
|
99
|
+
def print_line(line_number, show_line_numbers = true)
|
100
|
+
print line_number.to_s + ": " if show_line_numbers
|
101
|
+
puts get_line(line_number)
|
102
|
+
end
|
103
|
+
|
104
|
+
def irb_eval(lines)
|
105
|
+
to_eval = get_lines(lines)
|
106
|
+
to_eval.each {|l| Readline::HISTORY << l}
|
107
|
+
eval to_eval.join("\n")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
@@ -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,71 @@
|
|
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
|
+
interactive_editor
|
20
|
+
irb_options
|
21
|
+
irb_verbosity_control}
|
22
|
+
|
23
|
+
@equipped = false
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def equip(*args)
|
27
|
+
return if args.empty?
|
28
|
+
|
29
|
+
gadgets_to_equip = []
|
30
|
+
|
31
|
+
# Special case using :all or :none
|
32
|
+
if args[0].is_a?(Symbol) && [:all, :none, :defaults].include?(args[0])
|
33
|
+
what = args[0]
|
34
|
+
|
35
|
+
unless args[1].nil?
|
36
|
+
exceptions = args[1].has_key?(:except) ? args[1][:except] : []
|
37
|
+
|
38
|
+
# Handle special case where we get a string or a symbol instead of an array
|
39
|
+
exceptions = exceptions.to_s.to_a unless exceptions.is_a?( Array )
|
40
|
+
else
|
41
|
+
exceptions = []
|
42
|
+
end
|
43
|
+
|
44
|
+
case what
|
45
|
+
when :all
|
46
|
+
gadgets_to_equip.push(*(GADGETS - exceptions))
|
47
|
+
when :none
|
48
|
+
gadgets_to_equip.push(*exceptions)
|
49
|
+
when :defaults
|
50
|
+
gadgets_to_equip.push(*DEFAULTS)
|
51
|
+
end
|
52
|
+
# otherwise, args is a list of gadgets to equip
|
53
|
+
else
|
54
|
+
args.each do |arg|
|
55
|
+
gadget = arg.to_s
|
56
|
+
|
57
|
+
# Silently ignore unkown gadgets
|
58
|
+
gadgets_to_equip << gadget if GADGETS.include? gadget
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
gadgets_to_equip.each{|gadget| require "utility_belt/#{gadget}" }
|
63
|
+
|
64
|
+
@equipped ||= true
|
65
|
+
end
|
66
|
+
def equipped?
|
67
|
+
@equipped
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,34 @@
|
|
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
|
+
Kernel.system("xdg-open #{url}")
|
24
|
+
else
|
25
|
+
puts "Sorry, don't know how to open an URL from the command line on your platform"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Object
|
33
|
+
include UtilityBelt::Google
|
34
|
+
end if Object.const_defined? :IRB
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Hash
|
2
|
+
alias :+ :merge
|
3
|
+
def -(thing_to_be_deleted)
|
4
|
+
if thing_to_be_deleted.is_a? Hash
|
5
|
+
thing_to_be_deleted.each do |key, value|
|
6
|
+
self.delete(key) if self[key] == value
|
7
|
+
end
|
8
|
+
elsif self.keys.include? thing_to_be_deleted
|
9
|
+
self.delete(thing_to_be_deleted)
|
10
|
+
end
|
11
|
+
self
|
12
|
+
end
|
13
|
+
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. But it might be unfixable."
|
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
|