Skip to content

Instantly share code, notes, and snippets.

@heftig
Created March 8, 2012 22:23
Show Gist options
  • Save heftig/2003850 to your computer and use it in GitHub Desktop.
Save heftig/2003850 to your computer and use it in GitHub Desktop.
# encoding: utf-8
require 'rubygems'
require 'yaml'
def maybe_gem(name)
gem name
rescue Gem::LoadError
nil
end
maybe_gem 'wirble'
maybe_gem 'awesome_print'
maybe_gem 'interactive_editor'
IRB.conf[:SINGLE_IRB] = true
class Object
def local_methods
(methods - Object.instance_methods).sort
end
end
ANSI = {}
ANSI[:RESET] = "\e[0m"
ANSI[:BOLD] = "\e[1m"
ANSI[:UNDERLINE] = "\e[4m"
ANSI[:LGRAY] = "\e[0;37m"
ANSI[:GRAY] = "\e[1;30m"
ANSI[:RED] = "\e[31m"
ANSI[:GREEN] = "\e[32m"
ANSI[:YELLOW] = "\e[33m"
ANSI[:BLUE] = "\e[34m"
ANSI[:MAGENTA] = "\e[35m"
ANSI[:CYAN] = "\e[36m"
ANSI[:WHITE] = "\e[37m"
# Build a simple colorful IRB prompt
IRB.conf[:PROMPT][:SIMPLE_COLOR] = {
:PROMPT_I => "#{ANSI[:BLUE]}>>#{ANSI[:RESET]} ",
:PROMPT_N => "#{ANSI[:BLUE]}>>#{ANSI[:RESET]} ",
:PROMPT_C => "#{ANSI[:RED]}?>#{ANSI[:RESET]} ",
:PROMPT_S => "#{ANSI[:YELLOW]}?>#{ANSI[:RESET]} ",
:RETURN => "#{ANSI[:GREEN]}=>#{ANSI[:RESET]} %s\n",
:AUTO_INDENT => true }
# Warning: May screw with readline's expected cursor position
#IRB.conf[:PROMPT_MODE] = :SIMPLE_COLOR
# Loading extensions of the console. This is wrapped
# because some might not be included in your Gemfile
# and errors will be raised
def extend_console(name, care = true, required = true)
if care
require name if required
yield if block_given?
$console_extensions << "#{ANSI[:GREEN]}#{name}#{ANSI[:RESET]}"
else
$console_extensions << "#{ANSI[:GRAY]}#{name}#{ANSI[:RESET]}"
end
rescue LoadError
$console_extensions << "#{ANSI[:RED]}#{name}#{ANSI[:RESET]}"
end
$console_extensions = []
# awesome_print is prints prettier than pretty_print
extend_console 'ap' do
alias pp ap
module AwesomePrint
# Custom settings
@defaults = {
:indent => 2,
:color => {
:module => :yellowish,
:string => :cyanish,
:symbol => :cyan,
:array => :pale,
:hash => :white,
:bignum => :blueish,
:bigdecimal => :blueish,
:complex => :blueish,
:rational => :blueish,
:vector => :blueish,
:matrix => :blueish
}
}
class Inspector
private
def merge_custom_defaults!
merge_options!(AwesomePrint.defaults.dup)
end
end
# Custom formats
class Formatter
private
def awesome_rational(n)
awesome_self n, :with => " ≈ #{n.to_f}"
end
CORE << :rational
def awesome_vector(v)
if @options[:multiline]
data = v.inject([]) do |arr, item|
i = colorize(indent, :vector)
indented do
arr << (i << @inspector.awesome(item))
end
end
colorize("Vector", :vector) << "[\n" << data.join("\n") << "\n#{outdent}]"
else
colorize("Vector", :vector) << "[ " << v.to_a.map{ |item| @inspector.awesome(item) }.join(", ") << " ]"
end
end
CORE << :vector
def single_line
multiline = @options[:multiline]
@options[:multiline] = false
yield
ensure
@options[:multiline] = multiline
end
def awesome_matrix(m)
data = m.map do |val|
single_line { @inspector.awesome(val) }
end
if @options[:multiline]
plain_data = m.map do |val|
plain_single_line { @inspector.awesome(val) }
end
column_widths = plain_data.column_vectors.map do |col|
col.map { |val| val.size }.max || 0
end
data = data.to_a.map!.with_index do |line,idx|
if @options[:multiline]
line.map!.with_index do |val,col|
" " * (column_widths[col] - plain_data[idx,col].size) + val
end
i = colorize(indent, :matrix)
indented do
i << line.join(", ")
end
else
"[" << line.join(", ") << "]"
end
end
colorize("Matrix", :matrix) << "[\n" << data.join("\n") << "\n#{outdent}]"
else
data = data.to_a.map! do |line|
"[" << line.join(", ") << "]"
end
colorize("Matrix", :matrix) << "[" << data.join(", ") << "]"
end
end
CORE << :matrix
if defined?(Rubinius)
alias_method :ap_method_tuple, :method_tuple
def method_tuple(method)
name, args, owner = ap_method_tuple(method)
new_owner = owner.sub(/#.*$/, "")
new_owner += " (#{$1})" if owner =~ /defined in (\w+)/
[name, args, new_owner]
end
end
end
end
# Use awesome_print colorization
::IRB::Irb.class_eval do
alias :non_color_output_value :output_value
def output_value
if @context.inspect?
ap @context.last_value
else
non_color_output_value
end
end
end
end
=begin Disable hirb for now - doesn't cope with infinite enumerables, e.g. Prime.each
# Hirb makes tables easy.
extend_console 'hirb' do
Hirb.enable
extend Hirb::Console
# Disable pager by default
Hirb::View.toggle_pager
end
=end
# Wirble is a gem that handles coloring the IRB
# output and history
extend_console 'wirble' do
Wirble.init
# Disabled: Misdisplays symbols containing a =
#Wirble.colorize
end
# When you're using Rails 2 console, show queries in the console
extend_console 'rails2', (ENV.include?('RAILS_ENV') && !Object.const_defined?('RAILS_DEFAULT_LOGGER')), false do
require 'logger'
RAILS_DEFAULT_LOGGER = Logger.new(STDOUT)
end
# When you're using Rails 3 console, show queries in the console
extend_console 'rails3', defined?(ActiveSupport::Notifications), false do
$odd_or_even_queries = false
ActiveSupport::Notifications.subscribe('sql.active_record') do |*args|
$odd_or_even_queries = !$odd_or_even_queries
color = $odd_or_even_queries ? ANSI[:CYAN] : ANSI[:MAGENTA]
event = ActiveSupport::Notifications::Event.new(*args)
time = "%.1fms" % event.duration
name = event.payload[:name]
sql = event.payload[:sql].gsub("\n", " ").squeeze(" ")
puts " #{ANSI[:UNDERLINE]}#{color}#{name} (#{time})#{ANSI[:RESET]} #{sql}"
end
end
# Add a method pm that shows every method on an object
# Pass a regex to filter these
extend_console 'pm', true, false do
def pm(obj, *options) # Print methods
methods = obj.methods
methods -= Object.methods unless options.include? :more
filter = options.select {|opt| opt.kind_of? Regexp}.first
methods = methods.select {|name| name =~ filter} if filter
data = methods.sort.collect do |name|
method = obj.method(name)
if method.arity == 0
args = "()"
elsif method.arity > 0
n = method.arity
args = "(#{(1..n).collect {|i| "arg#{i}"}.join(", ")})"
elsif method.arity < 0
n = -method.arity
args = "(#{(1..n).collect {|i| "arg#{i}"}.join(", ")}, ...)"
end
klass = $1 if method.inspect =~ /Method: (.*?)#/
[name.to_s, args, klass]
end
max_name = data.collect {|item| item[0].size}.max
max_args = data.collect {|item| item[1].size}.max
data.each do |item|
print " #{ANSI[:YELLOW]}#{item[0].to_s.rjust(max_name)}#{ANSI[:RESET]}"
print "#{ANSI[:BLUE]}#{item[1].ljust(max_args)}#{ANSI[:RESET]}"
print " #{ANSI[:GRAY]}#{item[2]}#{ANSI[:RESET]}\n"
end
data.size
end
end
extend_console 'interactive_editor' do
alias vi vim
# Fix vim leaving colors around after exit
class InteractiveEditor
alias_method :original_edit, :edit
def edit(*args, &block)
ret = original_edit(*args, &block)
print ANSI[:RESET]
return ret
end
end
end
# Show results of all extension-loading
puts "#{ANSI[:BOLD]}~> Console extensions:#{ANSI[:RESET]} #{$console_extensions.join(' ')}#{ANSI[:RESET]}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment