added process/parsing of comments

This commit is contained in:
John Mair 2011-03-14 23:55:22 +13:00
parent 43ff3593f9
commit 8016fb7e2a
5 changed files with 87 additions and 43 deletions

View File

@ -4,6 +4,7 @@
direc = File.dirname(__FILE__) direc = File.dirname(__FILE__)
$LOAD_PATH << File.expand_path(direc) $LOAD_PATH << File.expand_path(direc)
$LOAD_PATH << "."
require "method_source" require "method_source"
require 'shellwords' require 'shellwords'

View File

@ -35,6 +35,20 @@ class Pry
text.split.drop(1).join(' ') text.split.drop(1).join(' ')
end end
get_method_object = lambda do |meth_name, target, options|
if options[:M]
target.eval("instance_method(:#{meth_name})")
elsif options[:m]
target.eval("method(:#{meth_name})")
else
begin
target.eval("method(:#{meth_name})")
rescue
target.eval("instance_method(:#{meth_name})")
end
end
end
command "!", "Clear the input buffer. Useful if the parsing process goes wrong and you get stuck in the read loop." do command "!", "Clear the input buffer. Useful if the parsing process goes wrong and you get stuck in the read loop." do
output.puts "Input buffer cleared!" output.puts "Input buffer cleared!"
opts[:eval_string].clear opts[:eval_string].clear
@ -386,11 +400,22 @@ e.g: eval-file -c self "hello.rb"
if obj == "/" if obj == "/"
throw(:breakout, 1) if opts[:nesting].level > 0 throw(:breakout, 1) if opts[:nesting].level > 0
next next
end end
target.eval("#{obj}.pry") target.eval("#{obj}.pry")
end end
process_comment_markup = lambda do |comment, code_type|
comment.gsub(/<code>(?:\s*\n)?(.*?)\s*<\/code>/m) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }.
gsub(/<em>(?:\s*\n)?(.*?)\s*<\/em>/m) { Pry.color ? "\e[32m#{$1}\e[0m": $1 }.
gsub(/<i>(?:\s*\n)?(.*?)\s*<\/i>/m) { Pry.color ? "\e[34m#{$1}\e[0m" : $1 }.
gsub(/\B\+(.*)\+\B/) { Pry.color ? "\e[32m#{$1}\e[0m": $1 }
end
strip_leading_hash_from_ruby_comments = lambda do |comment|
comment.gsub /^\s*#\s*/, ''
end
command "show-doc", "Show the comments above METH. Type `show-doc --help` for more info." do |*args| command "show-doc", "Show the comments above METH. Type `show-doc --help` for more info." do |*args|
options = {} options = {}
target = target() target = target()
@ -430,41 +455,46 @@ e.g show-doc hello_method
end end
begin begin
if options[:M] meth = get_method_object.call(meth_name, target, options)
meth = target.eval("instance_method(:#{meth_name})")
elsif options[:m]
meth = target.eval("method(:#{meth_name})")
else
begin
meth = target.eval("method(:#{meth_name})")
rescue
meth = target.eval("instance_method(:#{meth_name})")
end
end
rescue rescue
output.puts "Invalid method name: #{meth_name}. Type `show-doc --help` for help" output.puts "Invalid method name: #{meth_name}. Type `show-doc --help` for help"
next next
end end
code_type = :ruby
if Pry.has_pry_doc if Pry.has_pry_doc
info = Pry::MethodInfo.info_for(meth) info = Pry::MethodInfo.info_for(meth)
if !info if !info
doc = meth.comment doc = meth.comment
else else
doc = info.docstring doc = info.docstring
code_type = info.source_type
end end
else else
doc = meth.comment doc = strip_leading_hash_from_ruby_comments.call(meth.comment)
end end
doc = process_comment_markup.call(doc, code_type)
file, line = meth.source_location file, line = meth.source_location
check_for_dynamically_defined_method.call(file) check_for_dynamically_defined_method.call(file)
output.puts "--\nFrom #{file} @ line ~#{line}:\n--" doc = case code_type
when :ruby
"--\nFrom #{file} @ line ~#{line}:\n--"
else
"--\nFrom Ruby Core (C Method):\n-"
end
output.puts doc output.puts doc
doc doc
end end
strip_comments_from_c_code = lambda do |code|
code.sub /\A\s*\/\*.*?\*\/\s*/m, ''
end
command "show-method", "Show the source for METH. Type `show-method --help` for more info." do |*args| command "show-method", "Show the source for METH. Type `show-method --help` for more info." do |*args|
options = {} options = {}
target = target() target = target()
@ -480,7 +510,7 @@ e.g: show-method hello_method
options[:M] = true options[:M] = true
end end
opts.on("-m", "--methods", "Operate on methods..") do opts.on("-m", "--methods", "Operate on methods.") do
options[:m] = true options[:m] = true
end end
@ -500,32 +530,19 @@ e.g: show-method hello_method
# If no method name is given then use current method, if it exists # If no method name is given then use current method, if it exists
meth_name = meth_name_from_binding.call(target) if !meth_name meth_name = meth_name_from_binding.call(target) if !meth_name
if !meth_name if !meth_name
output.puts "You need to specify a method. Type `show-method --help` for help" output.puts "You need to specify a method. Type `show-method --help` for help"
next next
end end
begin begin
if options[:M] meth = get_method_object.call(meth_name, target, options)
meth = target.eval("instance_method(:#{meth_name})")
elsif options[:m]
meth = target.eval("method(:#{meth_name})")
else
begin
meth = target.eval("method(:#{meth_name})")
rescue
meth = target.eval("instance_method(:#{meth_name})")
end
end
rescue rescue
target_self = target.eval('self')
output.puts "Invalid method name: #{meth_name}. Type `show-method --help` for help" output.puts "Invalid method name: #{meth_name}. Type `show-method --help` for help"
next next
end end
meth_type = :ruby code_type = :ruby
# Try to find source for C methods using MethodInfo (if possible) # Try to find source for C methods using MethodInfo (if possible)
if Pry.has_pry_doc && meth.source_location.nil? if Pry.has_pry_doc && meth.source_location.nil?
@ -536,7 +553,8 @@ e.g: show-method hello_method
next next
end end
code = info.source code = info.source
meth_type = :c code = strip_comments_from_c_code.call(code)
code_type = :c
else else
code = meth.source code = meth.source
end end
@ -544,10 +562,15 @@ e.g: show-method hello_method
file, line = meth.source_location file, line = meth.source_location
check_for_dynamically_defined_method.call(file) check_for_dynamically_defined_method.call(file)
output.puts "--\nFrom #{file} @ line #{line}:\n--" code = case code_type
when :ruby
"--\nFrom #{file} @ line #{line}:\n--"
else
"--\nFrom Ruby Core (C Method):\n--"
end
if Pry.color if Pry.color
code = CodeRay.scan(code, meth_type).term code = CodeRay.scan(code, code_type).term
end end
output.puts code output.puts code

View File

@ -17,6 +17,11 @@ class Pry
# @return [Object] The last result. # @return [Object] The last result.
attr_accessor :last_result attr_accessor :last_result
# Get last exception raised.
# This method should not need to be accessed directly.
# @return [Exception] The last exception.
attr_accessor :last_exception
# Get the active Pry instance that manages the active Pry session. # Get the active Pry instance that manages the active Pry session.
# This method should not need to be accessed directly. # This method should not need to be accessed directly.
# @return [Pry] The active Pry instance. # @return [Pry] The active Pry instance.

View File

@ -135,21 +135,20 @@ class Pry
Readline.completion_proc = Pry::InputCompleter.build_completion_proc(target, commands.commands.keys) Readline.completion_proc = Pry::InputCompleter.build_completion_proc(target, commands.commands.keys)
end end
# eval the expression and save to last_result
# Do not want __FILE__, __LINE__ here because we need to distinguish
# (eval) methods for show-method and friends.
Pry.last_result = target.eval r(target)
# save the pry instance to active_instance # save the pry instance to active_instance
Pry.active_instance = self Pry.active_instance = self
# define locals _pry_ and _ (active instance and last expression)
target.eval("_pry_ = Pry.active_instance") target.eval("_pry_ = Pry.active_instance")
target.eval("_ = Pry.last_result")
# eval the expression and save to last_result
# Do not want __FILE__, __LINE__ here because we need to distinguish
# (eval) methods for show-method and friends.
# This also sets the `_` local for the session.
set_last_result(target.eval(r(target)), target)
rescue SystemExit => e rescue SystemExit => e
exit exit
rescue Exception => e rescue Exception => e
e set_last_exception(e, target)
end end
# Perform a read. # Perform a read.
@ -190,6 +189,22 @@ class Pry
end end
end end
# Set the last result of an eval.
# @param [Object] result The result.
# @param [Binding] target The binding to set `_` on.
def set_last_result(result, target)
Pry.last_result = result
target.eval("_ = Pry.last_result")
end
# Set the last exception for a session.
# @param [Exception] ex The exception.
# @param [Binding] target The binding to set `_ex_` on.
def set_last_exception(ex, target)
Pry.last_exception = ex
target.eval("_ex_ = Pry.last_exception")
end
# Process Pry commands. Pry commands are not Ruby methods and are evaluated # Process Pry commands. Pry commands are not Ruby methods and are evaluated
# prior to Ruby expressions. # prior to Ruby expressions.
# Commands can be modified/configured by the user: see `Pry::Commands` # Commands can be modified/configured by the user: see `Pry::Commands`

View File

@ -1,3 +1,3 @@
class Pry class Pry
VERSION = "0.7.0pre2" VERSION = "0.7.0pre3"
end end