1
0
Fork 0
mirror of https://github.com/pry/pry.git synced 2022-11-09 12:35:05 -05:00

now clearing :val rather than :eval_string in commands so that current expression context is not destroyed when running pry command. Also added !pry command to enter a pry session

This commit is contained in:
John Mair 2010-12-31 04:01:11 +13:00
parent 1e3539cfda
commit 42fe31e19e
4 changed files with 67 additions and 36 deletions

View file

@ -1,4 +1,11 @@
class Pry
# Default commands used by Pry.
# @notes
# If you plan to replace the default Commands class with a custom
# one then it must have a `commands` method that returns a Hash.
# The Hash should be set up so that the key is the command String
# (or Regexp)
class Commands
attr_accessor :out
@ -10,23 +17,28 @@ class Pry
@commands ||= {
"!" => proc do |opts|
out.puts "Refreshed REPL"
opts[:val].clear
opts[:eval_string].clear
end,
"!pry" => proc do |opts|
Pry.start(opts[:target])
opts[:val].clear
end,
["exit_program", "quit_program"] => proc do
exit
end,
/^help\s*(.+)?/ => proc do |opts|
param = opts[:captures].first
self.show_help(param)
opts[:eval_string].clear
opts[:val].clear
end,
"nesting" => proc do |opts|
self.show_nesting(opts[:nesting])
opts[:eval_string].clear
opts[:val].clear
end,
"status" => proc do |opts|
self.show_status(opts[:nesting], opts[:target])
opts[:eval_string].clear
opts[:val].clear
end,
"exit_all" => proc do
throw(:breakout, 0)
@ -36,39 +48,39 @@ class Pry
end,
"ls" => proc do |opts|
out.puts "#{opts[:target].eval('Pry.view(local_variables + instance_variables)')}"
opts[:eval_string].clear
opts[:val].clear
end,
/^cat\s+(.+)/ => proc do |opts|
obj = opts[:captures].first
out.puts opts[:target].eval("#{obj}.inspect")
opts[:eval_string].clear
opts[:val].clear
end,
/^cd\s+(.+)/ => proc do |opts|
obj = opts[:captures].first
opts[:target].eval("#{obj}.pry")
opts[:eval_string].clear
opts[:val].clear
end,
/^show_doc\s*(.+)/ => proc do |opts|
meth_name = opts[:captures].first
doc = opts[:target].eval("method(:#{meth_name})").comment
out.puts doc
opts[:eval_string].clear
opts[:val].clear
end,
/^show_idoc\s*(.+)/ => proc do |opts|
meth_name = opts[:captures].first
doc = opts[:target].eval("instance_method(:#{meth_name})").comment
opts[:eval_string].clear
opts[:val].clear
end,
/^show_method\s*(.+)/ => proc do |opts|
meth_name = opts[:captures].first
code = opts[:target].eval("method(:#{meth_name})").source
out.puts code
opts[:eval_string].clear
opts[:val].clear
end,
/^show_imethod\s*(.+)/ => proc do |opts|
meth_name = opts[:captures].first
code = opts[:target].eval("instance_method(:#{meth_name})").source
opts[:eval_string].clear
opts[:val].clear
end,
/^jump_to\s*(\d*)/ => proc do |opts|
break_level = opts[:captures].first.to_i
@ -77,22 +89,22 @@ class Pry
case break_level
when nesting.level
out.puts "Already at nesting level #{nesting.level}"
opts[:eval_string].clear
opts[:val].clear
when (0...nesting.level)
throw(:breakout, break_level + 1)
else
max_nest_level = nesting.level - 1
out.puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}."
opts[:eval_string].clear
opts[:val].clear
end
end,
"ls_methods" => proc do |opts|
out.puts "#{Pry.view(opts[:target].eval('public_methods(false)'))}"
opts[:eval_string].clear
opts[:val].clear
end,
"ls_imethods" => proc do |opts|
out.puts "#{Pry.view(opts[:target].eval('public_instance_methods(false)'))}"
opts[:eval_string].clear
opts[:val].clear
end
}
end
@ -100,6 +112,7 @@ class Pry
def command_info
@command_info ||= {
"!" => "Refresh the REPL.",
"!pry" => "Start a Pry session on current self; this even works mid-expression.",
["exit_program", "quit_program"] => "end the current program.",
"help" => "This menu.",
"nesting" => "Show nesting information.",

View file

@ -1,9 +1,28 @@
class Pry
module ObjectExtensions
# Start a Pry REPL.
# This method differs from `Pry.start` in that it does not
# support an options hash. Also, when no parameter is provided, the Pry
# session will start on the implied receiver rather than on
# top-level (as in the case of `Pry.start`).
# It has two forms of invocation. In the first form no parameter
# should be provided and it will start a pry session on the
# receiver. In the second form it should be invoked without an
# explicit receiver and one parameter; this will start a Pry
# session on the parameter.
# @param [Object, Binding] target The receiver of the Pry session.
# @example First form
# "dummy".pry
# @example Second form
# pry "dummy"
# @example Start a Pry session on current self (whatever that is)
# pry
def pry(target=self)
Pry.start(target)
end
# Return a binding object for the receiver.
def __binding__
if is_a?(Module)
return class_eval "binding"

View file

@ -19,45 +19,39 @@ class Pry
# @return [Pry] The active Pry instance.
attr_accessor :active_instance
# Set/Get the object to use for input by default by all Pry instances.
# (see input.rb)
# Get/Set the object to use for input by default by all Pry instances.
# @return [#read] The object to use for input by default by all
# Pry instances.
attr_accessor :input
# Set/Get the object to use for output by default by all Pry instances.
# (see: output.rb)
# Get/Set the object to use for output by default by all Pry instances.
# @return [#puts] The object to use for output by default by all
# Pry instances.
attr_accessor :output
# Set/Get the object to use for commands by default by all Pry instances.
# (see commands.rb)
# Get/Set the object to use for commands by default by all Pry instances.
# @return [#commands] The object to use for commands by default by all
# Pry instances.
attr_accessor :commands
# Set/Get the Proc to use for printing by default by all Pry
# Get/Set the Proc to use for printing by default by all Pry
# instances.
# This is the 'print' componenent of the REPL.
# (see print.rb)
# This is the 'print' component of the REPL.
# @return [Proc] The Proc to use for printing by default by all
# Pry instances.
attr_accessor :print
# Set/Get the Hash that defines Pry hooks used by default by all Pry
# Get/Set the Hash that defines Pry hooks used by default by all Pry
# instances.
# (see print.rb)
# @return [Hash] The hooks used by default by all Pry instances.
# @example
# Pry.hooks :before_session => proc { puts "hello" },
# :after_session => proc { puts "goodbye" }
attr_accessor :hooks
# Set/Get the array of Procs to be used for the prompts by default by
# Get/Set the array of Procs to be used for the prompts by default by
# all Pry instances.
# (see prompts.rb)
# @return [Array<Proc>] The array of Procs to be used for the
# prompts by default by all Pry instances.
attr_accessor :default_prompt
@ -65,7 +59,8 @@ class Pry
# Start a Pry REPL.
# @param [Object, Binding] target The receiver of the Pry session
# @param options (see Pry#initialize)
# @param [Hash] options
# @option options (see Pry#initialize)
# @example
# Pry.start(Object.new, :input => MyInput.new)
def self.start(target=TOPLEVEL_BINDING, options={})

View file

@ -14,11 +14,14 @@ class Pry
# commands. (see commands.rb)
# @option options [Hash] :hooks The defined hook Procs (see hooks.rb)
# @option options [Array<Proc>] :default_prompt The array of Procs
# to use for the prompts.
# @option options [Proc] :print The Proc to use for the 'print' componenent of the REPL
# to use for the prompts. (see prompts.rb)
# @option options [Proc] :print The Proc to use for the 'print'
# component of the REPL. (see print.rb)
def initialize(options={})
default_options = ConfigOptions.each_with_object({}) { |v, h| h[v] = Pry.send(v) }
h = {}
ConfigOptions.each { |v| h[v] = Pry.send(v) }
default_options = h
default_options.merge!(options)
ConfigOptions.each do |key|
@ -68,7 +71,7 @@ class Pry
target.eval("_ = Pry.last_result")
break_level = catch(:breakout) do
nesting << [nesting.size, target_self]
nesting.push [nesting.size, target_self]
loop do
rep(target)
end
@ -128,8 +131,8 @@ class Pry
eval_string = ""
loop do
val = input.read(prompt(eval_string, target))
eval_string << "#{val.chomp}\n"
process_commands(val, eval_string, target)
eval_string << "#{val.chomp}\n"
break eval_string if valid_expression?(eval_string)
end
@ -139,7 +142,7 @@ class Pry
# prior to Ruby expressions.
# Commands can be modified/configured by the user: see `Pry::Commands`
# This method should not need to be invoked directly - it is called
# by `Pry#r`
# by `Pry#r`.
# @param [String] val The current line of input.
# @param [String] eval_string The cumulative lines of input for
# multi-line input.
@ -150,8 +153,10 @@ class Pry
pattern, action = commands.commands.find { |k, v| Array(k).any? { |a| a === val } }
if pattern
last_match = Regexp.last_match
options = {
:captures => $~ ? $~.captures : nil,
:captures => last_match ? last_match.captures : nil,
:eval_string => eval_string,
:target => target,
:val => val,
@ -212,7 +217,6 @@ class Pry
end
end
# Return a `Binding` object for `target` or return `target` if it is
# already a `Binding`.
# In the case where `target` is top-level then return `TOPLEVEL_BINDING`