akitaonrails-utility_belt 1.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +5 -0
- data/Manifest.txt +7 -0
- data/README +348 -0
- data/bin/amazon +16 -0
- data/bin/google +7 -0
- data/bin/pastie +7 -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 +68 -0
- data/lib/utility_belt/command_history.rb +129 -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 +26 -0
- data/lib/utility_belt/hash_math.rb +13 -0
- data/lib/utility_belt/interactive_editor.rb +81 -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 +29 -0
- data/lib/utility_belt/pipe.rb +24 -0
- data/lib/utility_belt/print_methods.rb +72 -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/webbrowser.rb +37 -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 +22 -0
- metadata +136 -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 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,68 @@
|
|
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
|
+
when :linux
|
46
|
+
#test execute xsel
|
47
|
+
`xsel`
|
48
|
+
if $?.exitstatus != 0
|
49
|
+
raise "You need to install xsel for clipboard functionality!"
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.read
|
53
|
+
`xsel`
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.write(stuff)
|
57
|
+
`echo '#{stuff}' | xsel -i`
|
58
|
+
end
|
59
|
+
@@implemented = true
|
60
|
+
|
61
|
+
else
|
62
|
+
raise "No suitable clipboard implementation for your platform found!"
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
Clipboard = UtilityBelt::Clipboard if Object.const_defined? :IRB
|
@@ -0,0 +1,129 @@
|
|
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
|
+
def history_to_textmate
|
85
|
+
handling_jruby_bug do
|
86
|
+
file = Tempfile.new("irb_tempfile")
|
87
|
+
get_lines(0..(Readline::HISTORY.size - 1)).each do |line|
|
88
|
+
file << "#{line}\n"
|
89
|
+
end
|
90
|
+
file.close
|
91
|
+
system("mate #{file.path}")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
alias :hmate :history_to_textmate
|
95
|
+
|
96
|
+
def clear_history()
|
97
|
+
while true
|
98
|
+
Readline::HISTORY.delete_at(0)
|
99
|
+
end
|
100
|
+
rescue IndexError
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
def get_line(line_number)
|
105
|
+
Readline::HISTORY[line_number] rescue ""
|
106
|
+
end
|
107
|
+
|
108
|
+
def get_lines(lines = [])
|
109
|
+
return [get_line(lines)] if lines.is_a? Fixnum
|
110
|
+
out = []
|
111
|
+
lines = lines.to_a if lines.is_a? Range
|
112
|
+
lines.each do |l|
|
113
|
+
out << Readline::HISTORY[l] rescue IndexError
|
114
|
+
end
|
115
|
+
out
|
116
|
+
end
|
117
|
+
|
118
|
+
def print_line(line_number, show_line_numbers = true)
|
119
|
+
print line_number.to_s + ": " if show_line_numbers
|
120
|
+
puts get_line(line_number)
|
121
|
+
end
|
122
|
+
|
123
|
+
def irb_eval(lines)
|
124
|
+
to_eval = get_lines(lines)
|
125
|
+
to_eval.each {|l| Readline::HISTORY << l}
|
126
|
+
eval to_eval.join("\n")
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
@@ -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,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
%w{rubygems platform cgi}.each {|library| require library}
|
3
|
+
|
4
|
+
UtilityBelt.equip(:clipboard)
|
5
|
+
UtilityBelt.equip(:webbrowser)
|
6
|
+
|
7
|
+
module UtilityBelt
|
8
|
+
module Google
|
9
|
+
def google(search_term = nil)
|
10
|
+
search_term ||= Clipboard.read if Clipboard.available?
|
11
|
+
if search_term.empty?
|
12
|
+
puts "Usage: google search_term_without_spaces (Unix command line only)"
|
13
|
+
puts " google 'search term with spaces' (Unix or IRB)"
|
14
|
+
puts " google (Unix or IRB)"
|
15
|
+
puts " (if invoking without args, must have text in clipboard)"
|
16
|
+
else
|
17
|
+
url = "http://google.com/search?q=#{CGI.escape(search_term)}"
|
18
|
+
WebBrowser.open(url)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Object
|
25
|
+
include UtilityBelt::Google
|
26
|
+
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,81 @@
|
|
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
|
+
elsif @editor == "vim"
|
29
|
+
@editor = 'vim -c ":set ft=ruby"'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
def edit_interactively
|
33
|
+
unless @file
|
34
|
+
@file = Tempfile.new("irb_tempfile")
|
35
|
+
end
|
36
|
+
system("#{@editor} #{@file.path}")
|
37
|
+
Object.class_eval(File.read(@file.path).gsub("\r", "\n"))
|
38
|
+
rescue Exception => error
|
39
|
+
puts @file.path
|
40
|
+
puts error
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
module InteractiveEditing
|
45
|
+
def edit_interactively(editor = InteractiveEditor.sensible_editor)
|
46
|
+
unless IRB.conf[:interactive_editors] && IRB.conf[:interactive_editors][editor]
|
47
|
+
IRB.conf[:interactive_editors] ||= {}
|
48
|
+
IRB.conf[:interactive_editors][editor] = InteractiveEditor.new(editor)
|
49
|
+
end
|
50
|
+
IRB.conf[:interactive_editors][editor].edit_interactively
|
51
|
+
end
|
52
|
+
|
53
|
+
def handling_jruby_bug(&block)
|
54
|
+
if RUBY_PLATFORM =~ /java/
|
55
|
+
puts "JRuby IRB has a bug which prevents successful IRB vi/emacs editing."
|
56
|
+
puts "The JRuby team is aware of this and working on it. But it might be unfixable."
|
57
|
+
puts "(http://jira.codehaus.org/browse/JRUBY-2049)"
|
58
|
+
else
|
59
|
+
yield
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def vi
|
64
|
+
handling_jruby_bug {edit_interactively(:vim)}
|
65
|
+
end
|
66
|
+
|
67
|
+
def mate
|
68
|
+
edit_interactively(:mate)
|
69
|
+
end
|
70
|
+
|
71
|
+
# TODO: Hardcore Emacs users use emacsclient or gnuclient to open documents in
|
72
|
+
# their existing sessions, rather than starting a brand new Emacs process.
|
73
|
+
def emacs
|
74
|
+
handling_jruby_bug {edit_interactively(:emacs)}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Since we only intend to use this from the IRB command line, I see no reason to
|
79
|
+
# extend the entire Object class with this module when we can just extend the
|
80
|
+
# IRB main object.
|
81
|
+
self.extend InteractiveEditing if Object.const_defined? :IRB
|