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:
parent
1e3539cfda
commit
42fe31e19e
4 changed files with 67 additions and 36 deletions
|
@ -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.",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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={})
|
||||
|
|
|
@ -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`
|
||||
|
|
Loading…
Reference in a new issue