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
|
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
|
class Commands
|
||||||
attr_accessor :out
|
attr_accessor :out
|
||||||
|
|
||||||
|
@ -10,23 +17,28 @@ class Pry
|
||||||
@commands ||= {
|
@commands ||= {
|
||||||
"!" => proc do |opts|
|
"!" => proc do |opts|
|
||||||
out.puts "Refreshed REPL"
|
out.puts "Refreshed REPL"
|
||||||
|
opts[:val].clear
|
||||||
opts[:eval_string].clear
|
opts[:eval_string].clear
|
||||||
end,
|
end,
|
||||||
|
"!pry" => proc do |opts|
|
||||||
|
Pry.start(opts[:target])
|
||||||
|
opts[:val].clear
|
||||||
|
end,
|
||||||
["exit_program", "quit_program"] => proc do
|
["exit_program", "quit_program"] => proc do
|
||||||
exit
|
exit
|
||||||
end,
|
end,
|
||||||
/^help\s*(.+)?/ => proc do |opts|
|
/^help\s*(.+)?/ => proc do |opts|
|
||||||
param = opts[:captures].first
|
param = opts[:captures].first
|
||||||
self.show_help(param)
|
self.show_help(param)
|
||||||
opts[:eval_string].clear
|
opts[:val].clear
|
||||||
end,
|
end,
|
||||||
"nesting" => proc do |opts|
|
"nesting" => proc do |opts|
|
||||||
self.show_nesting(opts[:nesting])
|
self.show_nesting(opts[:nesting])
|
||||||
opts[:eval_string].clear
|
opts[:val].clear
|
||||||
end,
|
end,
|
||||||
"status" => proc do |opts|
|
"status" => proc do |opts|
|
||||||
self.show_status(opts[:nesting], opts[:target])
|
self.show_status(opts[:nesting], opts[:target])
|
||||||
opts[:eval_string].clear
|
opts[:val].clear
|
||||||
end,
|
end,
|
||||||
"exit_all" => proc do
|
"exit_all" => proc do
|
||||||
throw(:breakout, 0)
|
throw(:breakout, 0)
|
||||||
|
@ -36,39 +48,39 @@ class Pry
|
||||||
end,
|
end,
|
||||||
"ls" => proc do |opts|
|
"ls" => proc do |opts|
|
||||||
out.puts "#{opts[:target].eval('Pry.view(local_variables + instance_variables)')}"
|
out.puts "#{opts[:target].eval('Pry.view(local_variables + instance_variables)')}"
|
||||||
opts[:eval_string].clear
|
opts[:val].clear
|
||||||
end,
|
end,
|
||||||
/^cat\s+(.+)/ => proc do |opts|
|
/^cat\s+(.+)/ => proc do |opts|
|
||||||
obj = opts[:captures].first
|
obj = opts[:captures].first
|
||||||
out.puts opts[:target].eval("#{obj}.inspect")
|
out.puts opts[:target].eval("#{obj}.inspect")
|
||||||
opts[:eval_string].clear
|
opts[:val].clear
|
||||||
end,
|
end,
|
||||||
/^cd\s+(.+)/ => proc do |opts|
|
/^cd\s+(.+)/ => proc do |opts|
|
||||||
obj = opts[:captures].first
|
obj = opts[:captures].first
|
||||||
opts[:target].eval("#{obj}.pry")
|
opts[:target].eval("#{obj}.pry")
|
||||||
opts[:eval_string].clear
|
opts[:val].clear
|
||||||
end,
|
end,
|
||||||
/^show_doc\s*(.+)/ => proc do |opts|
|
/^show_doc\s*(.+)/ => proc do |opts|
|
||||||
meth_name = opts[:captures].first
|
meth_name = opts[:captures].first
|
||||||
doc = opts[:target].eval("method(:#{meth_name})").comment
|
doc = opts[:target].eval("method(:#{meth_name})").comment
|
||||||
out.puts doc
|
out.puts doc
|
||||||
opts[:eval_string].clear
|
opts[:val].clear
|
||||||
end,
|
end,
|
||||||
/^show_idoc\s*(.+)/ => proc do |opts|
|
/^show_idoc\s*(.+)/ => proc do |opts|
|
||||||
meth_name = opts[:captures].first
|
meth_name = opts[:captures].first
|
||||||
doc = opts[:target].eval("instance_method(:#{meth_name})").comment
|
doc = opts[:target].eval("instance_method(:#{meth_name})").comment
|
||||||
opts[:eval_string].clear
|
opts[:val].clear
|
||||||
end,
|
end,
|
||||||
/^show_method\s*(.+)/ => proc do |opts|
|
/^show_method\s*(.+)/ => proc do |opts|
|
||||||
meth_name = opts[:captures].first
|
meth_name = opts[:captures].first
|
||||||
code = opts[:target].eval("method(:#{meth_name})").source
|
code = opts[:target].eval("method(:#{meth_name})").source
|
||||||
out.puts code
|
out.puts code
|
||||||
opts[:eval_string].clear
|
opts[:val].clear
|
||||||
end,
|
end,
|
||||||
/^show_imethod\s*(.+)/ => proc do |opts|
|
/^show_imethod\s*(.+)/ => proc do |opts|
|
||||||
meth_name = opts[:captures].first
|
meth_name = opts[:captures].first
|
||||||
code = opts[:target].eval("instance_method(:#{meth_name})").source
|
code = opts[:target].eval("instance_method(:#{meth_name})").source
|
||||||
opts[:eval_string].clear
|
opts[:val].clear
|
||||||
end,
|
end,
|
||||||
/^jump_to\s*(\d*)/ => proc do |opts|
|
/^jump_to\s*(\d*)/ => proc do |opts|
|
||||||
break_level = opts[:captures].first.to_i
|
break_level = opts[:captures].first.to_i
|
||||||
|
@ -77,22 +89,22 @@ class Pry
|
||||||
case break_level
|
case break_level
|
||||||
when nesting.level
|
when nesting.level
|
||||||
out.puts "Already at nesting level #{nesting.level}"
|
out.puts "Already at nesting level #{nesting.level}"
|
||||||
opts[:eval_string].clear
|
opts[:val].clear
|
||||||
when (0...nesting.level)
|
when (0...nesting.level)
|
||||||
throw(:breakout, break_level + 1)
|
throw(:breakout, break_level + 1)
|
||||||
else
|
else
|
||||||
max_nest_level = nesting.level - 1
|
max_nest_level = nesting.level - 1
|
||||||
out.puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}."
|
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
|
||||||
end,
|
end,
|
||||||
"ls_methods" => proc do |opts|
|
"ls_methods" => proc do |opts|
|
||||||
out.puts "#{Pry.view(opts[:target].eval('public_methods(false)'))}"
|
out.puts "#{Pry.view(opts[:target].eval('public_methods(false)'))}"
|
||||||
opts[:eval_string].clear
|
opts[:val].clear
|
||||||
end,
|
end,
|
||||||
"ls_imethods" => proc do |opts|
|
"ls_imethods" => proc do |opts|
|
||||||
out.puts "#{Pry.view(opts[:target].eval('public_instance_methods(false)'))}"
|
out.puts "#{Pry.view(opts[:target].eval('public_instance_methods(false)'))}"
|
||||||
opts[:eval_string].clear
|
opts[:val].clear
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -100,6 +112,7 @@ class Pry
|
||||||
def command_info
|
def command_info
|
||||||
@command_info ||= {
|
@command_info ||= {
|
||||||
"!" => "Refresh the REPL.",
|
"!" => "Refresh the REPL.",
|
||||||
|
"!pry" => "Start a Pry session on current self; this even works mid-expression.",
|
||||||
["exit_program", "quit_program"] => "end the current program.",
|
["exit_program", "quit_program"] => "end the current program.",
|
||||||
"help" => "This menu.",
|
"help" => "This menu.",
|
||||||
"nesting" => "Show nesting information.",
|
"nesting" => "Show nesting information.",
|
||||||
|
|
|
@ -1,9 +1,28 @@
|
||||||
class Pry
|
class Pry
|
||||||
module ObjectExtensions
|
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)
|
def pry(target=self)
|
||||||
Pry.start(target)
|
Pry.start(target)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Return a binding object for the receiver.
|
||||||
def __binding__
|
def __binding__
|
||||||
if is_a?(Module)
|
if is_a?(Module)
|
||||||
return class_eval "binding"
|
return class_eval "binding"
|
||||||
|
|
|
@ -19,45 +19,39 @@ class Pry
|
||||||
# @return [Pry] The active Pry instance.
|
# @return [Pry] The active Pry instance.
|
||||||
attr_accessor :active_instance
|
attr_accessor :active_instance
|
||||||
|
|
||||||
# Set/Get the object to use for input by default by all Pry instances.
|
# Get/Set the object to use for input by default by all Pry instances.
|
||||||
# (see input.rb)
|
|
||||||
# @return [#read] The object to use for input by default by all
|
# @return [#read] The object to use for input by default by all
|
||||||
# Pry instances.
|
# Pry instances.
|
||||||
attr_accessor :input
|
attr_accessor :input
|
||||||
|
|
||||||
# Set/Get the object to use for output by default by all Pry instances.
|
# Get/Set the object to use for output by default by all Pry instances.
|
||||||
# (see: output.rb)
|
|
||||||
# @return [#puts] The object to use for output by default by all
|
# @return [#puts] The object to use for output by default by all
|
||||||
# Pry instances.
|
# Pry instances.
|
||||||
attr_accessor :output
|
attr_accessor :output
|
||||||
|
|
||||||
# Set/Get the object to use for commands by default by all Pry instances.
|
# Get/Set the object to use for commands by default by all Pry instances.
|
||||||
# (see commands.rb)
|
|
||||||
# @return [#commands] The object to use for commands by default by all
|
# @return [#commands] The object to use for commands by default by all
|
||||||
# Pry instances.
|
# Pry instances.
|
||||||
attr_accessor :commands
|
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.
|
# instances.
|
||||||
# This is the 'print' componenent of the REPL.
|
# This is the 'print' component of the REPL.
|
||||||
# (see print.rb)
|
|
||||||
# @return [Proc] The Proc to use for printing by default by all
|
# @return [Proc] The Proc to use for printing by default by all
|
||||||
# Pry instances.
|
# Pry instances.
|
||||||
attr_accessor :print
|
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.
|
# instances.
|
||||||
# (see print.rb)
|
|
||||||
# @return [Hash] The hooks used by default by all Pry instances.
|
# @return [Hash] The hooks used by default by all Pry instances.
|
||||||
# @example
|
# @example
|
||||||
# Pry.hooks :before_session => proc { puts "hello" },
|
# Pry.hooks :before_session => proc { puts "hello" },
|
||||||
# :after_session => proc { puts "goodbye" }
|
# :after_session => proc { puts "goodbye" }
|
||||||
attr_accessor :hooks
|
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.
|
# all Pry instances.
|
||||||
# (see prompts.rb)
|
|
||||||
# @return [Array<Proc>] The array of Procs to be used for the
|
# @return [Array<Proc>] The array of Procs to be used for the
|
||||||
# prompts by default by all Pry instances.
|
# prompts by default by all Pry instances.
|
||||||
attr_accessor :default_prompt
|
attr_accessor :default_prompt
|
||||||
|
@ -65,7 +59,8 @@ class Pry
|
||||||
|
|
||||||
# Start a Pry REPL.
|
# Start a Pry REPL.
|
||||||
# @param [Object, Binding] target The receiver of the Pry session
|
# @param [Object, Binding] target The receiver of the Pry session
|
||||||
# @param options (see Pry#initialize)
|
# @param [Hash] options
|
||||||
|
# @option options (see Pry#initialize)
|
||||||
# @example
|
# @example
|
||||||
# Pry.start(Object.new, :input => MyInput.new)
|
# Pry.start(Object.new, :input => MyInput.new)
|
||||||
def self.start(target=TOPLEVEL_BINDING, options={})
|
def self.start(target=TOPLEVEL_BINDING, options={})
|
||||||
|
|
|
@ -14,11 +14,14 @@ class Pry
|
||||||
# commands. (see commands.rb)
|
# commands. (see commands.rb)
|
||||||
# @option options [Hash] :hooks The defined hook Procs (see hooks.rb)
|
# @option options [Hash] :hooks The defined hook Procs (see hooks.rb)
|
||||||
# @option options [Array<Proc>] :default_prompt The array of Procs
|
# @option options [Array<Proc>] :default_prompt The array of Procs
|
||||||
# to use for the prompts.
|
# to use for the prompts. (see prompts.rb)
|
||||||
# @option options [Proc] :print The Proc to use for the 'print' componenent of the REPL
|
# @option options [Proc] :print The Proc to use for the 'print'
|
||||||
|
# component of the REPL. (see print.rb)
|
||||||
def initialize(options={})
|
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)
|
default_options.merge!(options)
|
||||||
|
|
||||||
ConfigOptions.each do |key|
|
ConfigOptions.each do |key|
|
||||||
|
@ -68,7 +71,7 @@ class Pry
|
||||||
target.eval("_ = Pry.last_result")
|
target.eval("_ = Pry.last_result")
|
||||||
|
|
||||||
break_level = catch(:breakout) do
|
break_level = catch(:breakout) do
|
||||||
nesting << [nesting.size, target_self]
|
nesting.push [nesting.size, target_self]
|
||||||
loop do
|
loop do
|
||||||
rep(target)
|
rep(target)
|
||||||
end
|
end
|
||||||
|
@ -128,8 +131,8 @@ class Pry
|
||||||
eval_string = ""
|
eval_string = ""
|
||||||
loop do
|
loop do
|
||||||
val = input.read(prompt(eval_string, target))
|
val = input.read(prompt(eval_string, target))
|
||||||
eval_string << "#{val.chomp}\n"
|
|
||||||
process_commands(val, eval_string, target)
|
process_commands(val, eval_string, target)
|
||||||
|
eval_string << "#{val.chomp}\n"
|
||||||
|
|
||||||
break eval_string if valid_expression?(eval_string)
|
break eval_string if valid_expression?(eval_string)
|
||||||
end
|
end
|
||||||
|
@ -139,7 +142,7 @@ class Pry
|
||||||
# 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`
|
||||||
# This method should not need to be invoked directly - it is called
|
# 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] val The current line of input.
|
||||||
# @param [String] eval_string The cumulative lines of input for
|
# @param [String] eval_string The cumulative lines of input for
|
||||||
# multi-line input.
|
# multi-line input.
|
||||||
|
@ -150,8 +153,10 @@ class Pry
|
||||||
pattern, action = commands.commands.find { |k, v| Array(k).any? { |a| a === val } }
|
pattern, action = commands.commands.find { |k, v| Array(k).any? { |a| a === val } }
|
||||||
|
|
||||||
if pattern
|
if pattern
|
||||||
|
last_match = Regexp.last_match
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
:captures => $~ ? $~.captures : nil,
|
:captures => last_match ? last_match.captures : nil,
|
||||||
:eval_string => eval_string,
|
:eval_string => eval_string,
|
||||||
:target => target,
|
:target => target,
|
||||||
:val => val,
|
:val => val,
|
||||||
|
@ -212,7 +217,6 @@ class Pry
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# Return a `Binding` object for `target` or return `target` if it is
|
# Return a `Binding` object for `target` or return `target` if it is
|
||||||
# already a `Binding`.
|
# already a `Binding`.
|
||||||
# In the case where `target` is top-level then return `TOPLEVEL_BINDING`
|
# In the case where `target` is top-level then return `TOPLEVEL_BINDING`
|
||||||
|
|
Loading…
Reference in a new issue