Skip to content

Commit

Permalink
add some awesome enhanced RI functionality for irb
Browse files Browse the repository at this point in the history
  • Loading branch information
ches committed Apr 9, 2009
1 parent f706da2 commit e7012b4
Showing 1 changed file with 89 additions and 0 deletions.
89 changes: 89 additions & 0 deletions .irbrc
Expand Up @@ -50,3 +50,92 @@ if ENV.include?('RAILS_ENV') && !Object.const_defined?('RAILS_DEFAULT_LOGGER')
require 'logger' require 'logger'
RAILS_DEFAULT_LOGGER = Logger.new(STDOUT) RAILS_DEFAULT_LOGGER = Logger.new(STDOUT)
end end

# The below adds nice ri documentation via obj.ri_* with completion,
# and supports the old Wirble way with `r 'String#count` and completion
# as well. Courtesy:
#
# http://eigenclass.org/hiki/irb+ri+completion
#
# The author recommends FastRI because RI is so slow.
module Kernel
def r(arg)
puts `ri "#{arg}"`
end
private :r
end

class Object
def puts_ri_documentation_for(obj, meth)
case self
when Module
candidates = ancestors.map{|klass| "#{klass}::#{meth}"}
candidates.concat(class << self; ancestors end.map{|k| "#{k}##{meth}"})
else
candidates = self.class.ancestors.map{|klass| "#{klass}##{meth}"}
end
candidates.each do |candidate|
#puts "TRYING #{candidate}"
# desc = `fri '#{candidate}'`
# unless desc.chomp == "nil"
# uncomment to use ri (and some patience)
desc = `ri -T '#{candidate}' 2>/dev/null`
unless desc.empty?
puts desc
return true
end
end
false
end
private :puts_ri_documentation_for

def method_missing(meth, *args, &block)
if md = /ri_(.*)/.match(meth.to_s)
unless puts_ri_documentation_for(self,md[1])
"Ri doesn't know about ##{meth}"
end
else
super
end
end

def ri_(meth)
unless puts_ri_documentation_for(self,meth.to_s)
"Ri doesn't know about ##{meth}"
end
end
end

RICompletionProc = proc{|input|
bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
case input
when /(\s*(.*)\.ri_)(.*)/
pre = $1
receiver = $2
meth = $3 ? /\A#{Regexp.quote($3)}/ : /./ #}
begin
candidates = eval("#{receiver}.methods", bind).map do |m|
case m
when /[A-Za-z_]/; m
else # needs escaping
%{"#{m}"}
end
end
candidates = candidates.grep(meth)
candidates.map{|s| pre + s }
rescue Exception
candidates = []
end
when /([A-Z]\w+)#(\w*)/ #}
klass = $1
meth = $2 ? /\A#{Regexp.quote($2)}/ : /./
candidates = eval("#{klass}.instance_methods(false)", bind)
candidates = candidates.grep(meth)
candidates.map{|s| "'" + klass + '#' + s + "'"}
else
IRB::InputCompletor::CompletionProc.call(input)
end
}
#Readline.basic_word_break_characters= " \t\n\"\\'`><=;|&{("
Readline.basic_word_break_characters= " \t\n\\><=;|&"
Readline.completion_proc = RICompletionProc

0 comments on commit e7012b4

Please sign in to comment.