version 0.6.8, added whereami command, made .pryrc run at the start of each runtime session, put syntax highlighting on by default

This commit is contained in:
John Mair 2011-03-06 03:17:54 +13:00
parent 1b65cf19d5
commit 4b9198d03c
13 changed files with 131 additions and 30 deletions

View File

@ -1,3 +1,8 @@
6/3/2011 version 0.6.8
* add whereami command, a la the `ir_b` gem
* make whereami run at the start of every session
* make .pryrc be loaded by run-time pry sessions
4/3/2011 version 0.6.7 4/3/2011 version 0.6.7
* color support * color support
* --simple-prompt for pry commandline * --simple-prompt for pry commandline

View File

@ -42,7 +42,7 @@ Example: Interacting with an object at runtime
With the `Object#pry` method we can pry (open an irb-like session) on With the `Object#pry` method we can pry (open an irb-like session) on
an object. In the example below we open a Pry session for the `Test` class and execute a method and add an object. In the example below we open a Pry session for the `Test` class and execute a method and add
an instance variable. The current thread is halted for the duration of the session. an instance variable. The current thread is taken over by the Pry REPL loop for the duration of the session.
require 'pry' require 'pry'
@ -164,7 +164,7 @@ end.
* Pry can be invoked at any time and on any object in the running program. * Pry can be invoked at any time and on any object in the running program.
* Pry sessions can nest arbitrarily deeply -- to go back one level of nesting type 'exit' or 'quit' or 'back' * Pry sessions can nest arbitrarily deeply -- to go back one level of nesting type 'exit' or 'quit' or 'back'
* Pry comes with syntax highlighting just use the `toggle-color` command to use it. * Pry comes with syntax highlighting on by default just use the `toggle-color` command to use it.
* Use `_` to recover last result. * Use `_` to recover last result.
* Use `_pry_` to reference the Pry instance managing the current session. * Use `_pry_` to reference the Pry instance managing the current session.
* Pry supports tab completion. * Pry supports tab completion.
@ -240,6 +240,7 @@ If you want to access a method of the same name, prefix the invocation by whites
getting you out of a situation where the parsing process getting you out of a situation where the parsing process
goes wrong and you get stuck in an endless read loop. goes wrong and you get stuck in an endless read loop.
* `status` shows status information about the current session. * `status` shows status information about the current session.
* `whereami` shows the code context of the session.
* `version` Show Pry version information * `version` Show Pry version information
* `help` shows the list of session commands with brief explanations. * `help` shows the list of session commands with brief explanations.
* `toggle-color` turns on and off syntax highlighting. * `toggle-color` turns on and off syntax highlighting.
@ -265,6 +266,14 @@ If you want to access a method of the same name, prefix the invocation by whites
current one with `obj` as the receiver of the new session. Very useful current one with `obj` as the receiver of the new session. Very useful
when exploring large or complicated runtime state. when exploring large or complicated runtime state.
Syntax Highlighting
--------------------
Syntax highlighting is on by default in Pry. You can toggle it on and
off in a session by using the `toggle-color` command. Alternatively,
you can turn it off permanently by putting the line `Pry.color =
false` in your `~/.pryrc` file.
Bindings and objects Bindings and objects
-------------------- --------------------

View File

@ -26,7 +26,7 @@ def apply_spec_defaults(s)
s.has_rdoc = 'yard' s.has_rdoc = 'yard'
s.executables = ["pry"] s.executables = ["pry"]
s.files = Dir["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "lib/**/*.rb", "examples/**/*.rb", s.files = Dir["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "lib/**/*.rb", "examples/**/*.rb",
"test/*.rb", "CHANGELOG", "LICENSE", "README.markdown", "Rakefile", ".gemtest"] "test/*.rb", "test/testrc", "CHANGELOG", "LICENSE", "README.markdown", "Rakefile", ".gemtest"]
end end
task :test do task :test do

View File

@ -35,8 +35,8 @@ See: `https://github.com/banister` for more information.
options[:loadrc] = false options[:loadrc] = false
end end
opts.on("--color", "Start session with syntax highlighting on.") do opts.on("--no-color", "Start session without syntax highlighting.") do
Pry.color = true Pry.color = false
end end
opts.on("--simple-prompt", "Simple prompt mode.") do opts.on("--simple-prompt", "Simple prompt mode.") do

View File

@ -4,8 +4,8 @@ require 'rubygems'
require "#{direc}/../lib/pry" require "#{direc}/../lib/pry"
my_hooks = { my_hooks = {
:before_session => proc { |out, obj| out.puts "Opening #{obj}." }, :before_session => proc { |out, target| out.puts "Opening #{target.eval('self')}." },
:after_session => proc { |out, obj| out.puts "Closing #{obj}." } :after_session => proc { |out, target| out.puts "Closing #{target.eval('self')}." }
} }
# Start a Pry session using the hooks hash defined in my_hooks # Start a Pry session using the hooks hash defined in my_hooks

View File

@ -28,19 +28,40 @@ class Pry
text.split.drop(1).join(' ') text.split.drop(1).join(' ')
end end
command "whereami" do command "whereami", "Show the code context for the session." do
file = target.eval '__FILE__' file = target.eval('__FILE__')
ir_b_line = target.eval '__LINE__' line_num = target.eval('__LINE__')
puts "#{file}:#{ir_b_line}" klass = target.eval('self.class')
meth_name = meth_name_from_binding.call(target)
if !meth_name
output.puts "Cannot find containing method. Did you remember to use \`binding.pry\` ?"
next
end
check_for_dynamically_defined_method.call(file)
output.puts "--\nFrom #{file} @ line #{line_num} in #{klass}##{meth_name}:\n--"
# This method inspired by http://rubygems.org/gems/ir_b
File.open(file).each_with_index do |line, index| File.open(file).each_with_index do |line, index|
line_n = index + 1 line_n = index + 1
next unless line_n > (ir_b_line - 6) next unless line_n > (line_num - 6)
break if line_n > (ir_b_line + 5) break if line_n > (line_num + 5)
if line_n == ir_b_line if line_n == line_num
puts " =>#{line_n.to_s.rjust(3)}: #{line.chomp}" code =" =>#{line_n.to_s.rjust(3)}: #{line.chomp}"
if Pry.color
code = CodeRay.scan(code, :ruby).term
end
output.puts code
code
else else
puts "#{line_n.to_s.rjust(6)}: #{line.chomp}" code = "#{line_n.to_s.rjust(6)}: #{line.chomp}"
if Pry.color
code = CodeRay.scan(code, :ruby).term
end
output.puts code
code
end end
end end
end end
@ -54,11 +75,12 @@ class Pry
Pry.start(target) Pry.start(target)
end end
command "exit-program", "End the current program. Aliases: quit-program" do command "exit-program", "End the current program. Aliases: quit-program, !!!" do
exit exit
end end
alias_command "quit-program", "exit-program", "" alias_command "quit-program", "exit-program", ""
alias_command "!!!", "exit-program", ""
command "toggle-color", "Toggle syntax highlighting." do command "toggle-color", "Toggle syntax highlighting." do
Pry.color = !Pry.color Pry.color = !Pry.color
@ -279,7 +301,7 @@ Shows local and instance variables by default.
next next
end end
contents = File.read(file_name) contents = File.read(File.expand_path(file_name))
output.puts contents output.puts contents
contents contents
end end
@ -318,10 +340,10 @@ e.g: eval-file -c self "hello.rb"
old_constants = Object.constants old_constants = Object.constants
if options[:c] if options[:c]
target_self = target.eval('self') target_self = target.eval('self')
target.eval(File.read(file_name)) target.eval(File.read(File.expand_path(file_name)))
output.puts "--\nEval'd '#{file_name}' in the `#{target_self}` context." output.puts "--\nEval'd '#{file_name}' in the `#{target_self}` context."
else else
TOPLEVEL_BINDING.eval(File.read(file_name)) TOPLEVEL_BINDING.eval(File.read(File.expand_path(file_name)))
output.puts "--\nEval'd '#{file_name}' at top-level." output.puts "--\nEval'd '#{file_name}' at top-level."
end end
new_constants = Object.constants - old_constants new_constants = Object.constants - old_constants

View File

@ -2,7 +2,18 @@ class Pry
# The default hooks - display messages when beginning and ending Pry sessions. # The default hooks - display messages when beginning and ending Pry sessions.
DEFAULT_HOOKS = { DEFAULT_HOOKS = {
:before_session => proc { |out, obj| out.puts "Beginning Pry session for #{Pry.view_clip(obj)}" },
:after_session => proc { |out, obj| out.puts "Ending Pry session for #{Pry.view_clip(obj)}" } :before_session => proc do |out, target|
out.puts "Beginning Pry session for #{Pry.view_clip(target.eval('self'))}"
# ensure we're actually in a method
meth_name = target.eval('__method__')
file = target.eval('__FILE__')
if ![nil, :__binding__, :__binding_impl__].include?(meth_name) && file !~ /(\(.*\))|<.*>/
Pry.run_command "whereami", :output => out, :show_output => true, :context => target, :commands => Pry::Commands
end
end,
:after_session => proc { |out, target| out.puts "Ending Pry session for #{Pry.view_clip(target.eval('self'))}" }
} }
end end

View File

@ -1,6 +1,7 @@
# @author John Mair (banisterfiend) # @author John Mair (banisterfiend)
class Pry class Pry
# The RC Files to load.
RC_FILES = ["~/.pryrc"] RC_FILES = ["~/.pryrc"]
# class accessors # class accessors
@ -151,13 +152,15 @@ class Pry
options = { options = {
:context => TOPLEVEL_BINDING, :context => TOPLEVEL_BINDING,
:show_output => false :show_output => false,
:output => Pry.output,
:commands => Pry.commands
}.merge!(options) }.merge!(options)
null_output = Object.new.tap { |v| v.instance_eval { def puts(*) end } } null_output = Object.new.tap { |v| v.instance_eval { def puts(*) end } }
commands = Pry.commands.clone commands = options[:commands].clone
commands.output = options[:show_output] ? Pry.output : null_output commands.output = options[:show_output] ? options[:output] : null_output
commands.target = Pry.binding_for(options[:context]) commands.target = Pry.binding_for(options[:context])
cmd = commands.commands[name] cmd = commands.commands[name]
@ -177,7 +180,7 @@ class Pry
@prompt = DEFAULT_PROMPT @prompt = DEFAULT_PROMPT
@print = DEFAULT_PRINT @print = DEFAULT_PRINT
@hooks = DEFAULT_HOOKS @hooks = DEFAULT_HOOKS
@color = false @color = true
@should_load_rc = true @should_load_rc = true
@rc_loaded = false @rc_loaded = false
@cli = false @cli = false

View File

@ -73,7 +73,7 @@ class Pry
target = Pry.binding_for(target) target = Pry.binding_for(target)
target_self = target.eval('self') target_self = target.eval('self')
exec_hook :before_session, output, target_self exec_hook :before_session, output, target
# cannot rely on nesting.level as # cannot rely on nesting.level as
# nesting.level changes with new sessions # nesting.level changes with new sessions
@ -94,7 +94,7 @@ class Pry
nesting.pop nesting.pop
exec_hook :after_session, output, target_self exec_hook :after_session, output, target
# If break_data is an array, then the last element is the return value # If break_data is an array, then the last element is the return value
break_level, return_value = Array(break_data) break_level, return_value = Array(break_data)
@ -136,7 +136,7 @@ class Pry
end end
# eval the expression and save to last_result # eval the expression and save to last_result
Pry.last_result = target.eval r(target) Pry.last_result = target.eval r(target), __FILE__, __LINE__
# save the pry instance to active_instance # save the pry instance to active_instance
Pry.active_instance = self Pry.active_instance = self

View File

@ -1,3 +1,3 @@
class Pry class Pry
VERSION = "0.6.8pre6" VERSION = "0.6.8"
end end

View File

@ -12,6 +12,8 @@ puts "--"
# Ensure we do not execute any rc files # Ensure we do not execute any rc files
Pry::RC_FILES.clear Pry::RC_FILES.clear
Pry.color = false
Pry.should_load_rc = false
describe Pry do describe Pry do
describe "open a Pry session on an object" do describe "open a Pry session on an object" do
@ -85,9 +87,43 @@ describe Pry do
end end
end end
describe "test loading rc files" do
after do
Pry::RC_FILES.clear
Pry.should_load_rc = false
end
it "should run the rc file only once" do
Pry.should_load_rc = true
Pry::RC_FILES << "#{direc}/testrc"
Pry.start(self, :input => StringIO.new("exit\n"), :output => Pry::NullOutput)
TEST_RC.should == [0]
Pry.start(self, :input => StringIO.new("exit\n"), :output => Pry::NullOutput)
TEST_RC.should == [0]
Object.remove_const(:TEST_RC)
end
it "should not run the rc file at all if Pry.should_load_rc is false" do
Pry.should_load_rc = false
Pry.start(self, :input => StringIO.new("exit\n"), :output => Pry::NullOutput)
Object.const_defined?(:TEST_RC).should == false
end
it "should not load the rc file if #repl method invoked" do
Pry.should_load_rc = true
Pry.new(:input => StringIO.new("exit\n"), :output => Pry::NullOutput).repl(self)
Object.const_defined?(:TEST_RC).should == false
Pry.should_load_rc = false
end
end
describe "nesting" do describe "nesting" do
after do after do
Pry.reset_defaults Pry.reset_defaults
Pry.color = false
end end
it 'should nest properly' do it 'should nest properly' do
@ -174,6 +210,7 @@ describe Pry do
after do after do
Pry.reset_defaults Pry.reset_defaults
Pry.color = false
end end
it "should start a pry session on the receiver (first form)" do it "should start a pry session on the receiver (first form)" do
@ -217,12 +254,14 @@ describe Pry do
after do after do
Pry.reset_defaults Pry.reset_defaults
Pry.color = false
end end
describe "input" do describe "input" do
after do after do
Pry.reset_defaults Pry.reset_defaults
Pry.color = false
end end
it 'should set the input default, and the default should be overridable' do it 'should set the input default, and the default should be overridable' do
@ -545,6 +584,7 @@ describe Pry do
Object.remove_const(:Command3) Object.remove_const(:Command3)
Pry.reset_defaults Pry.reset_defaults
Pry.color = false
end end
end end
@ -677,6 +717,7 @@ describe Pry do
str_output.string.should =~ /CLOSE/ str_output.string.should =~ /CLOSE/
Pry.reset_defaults Pry.reset_defaults
Pry.color = false
end end
end end
end end

View File

@ -2,6 +2,14 @@ class Module
public :remove_const public :remove_const
end end
class << Pry
alias_method :orig_reset_defaults, :reset_defaults
def reset_defaults
orig_reset_defaults
Pry.color = false
end
end
class InputTester class InputTester
def initialize(*actions) def initialize(*actions)
@orig_actions = actions.dup @orig_actions = actions.dup

2
test/testrc Normal file
View File

@ -0,0 +1,2 @@
TEST_RC = [] if !Object.const_defined?(:TEST_RC)
TEST_RC << 0