mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
added basic skeleton for hooks system (yet to add many hook callsites)
This commit is contained in:
commit
c02772af19
9 changed files with 167 additions and 31 deletions
18
lib/pry.rb
18
lib/pry.rb
|
@ -4,19 +4,19 @@
|
|||
|
||||
require 'pp'
|
||||
require 'pry/helpers/base_helpers'
|
||||
require 'pry/hooks'
|
||||
|
||||
class Pry
|
||||
# The default hooks - display messages when beginning and ending Pry sessions.
|
||||
DEFAULT_HOOKS = {
|
||||
:before_session => proc do |out, target, _pry_|
|
||||
# ensure we're actually in a method
|
||||
file = target.eval('__FILE__')
|
||||
DEFAULT_HOOKS = Pry::Hooks.new.add_hook(:before_session) do |out, target, _pry_|
|
||||
# ensure we're actually in a method
|
||||
file = target.eval('__FILE__')
|
||||
|
||||
# /unknown/ for rbx
|
||||
if file == Pry.eval_path || (file !~ /(\(.*\))|<.*>/ && file !~ /__unknown__/ && file != "" && file != "-e")
|
||||
_pry_.process_line("whereami 5", "", target)
|
||||
end
|
||||
# /unknown/ for rbx
|
||||
if file !~ /(\(.*\))|<.*>/ && file !~ /__unknown__/ && file != "" && file != "-e"
|
||||
_pry_.process_line("whereami 5", "", target)
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
# The default print
|
||||
DEFAULT_PRINT = proc do |output, value|
|
||||
|
|
52
lib/pry/hooks.rb
Normal file
52
lib/pry/hooks.rb
Normal file
|
@ -0,0 +1,52 @@
|
|||
class Pry
|
||||
class Hooks
|
||||
|
||||
def initialize
|
||||
@hooks = {}
|
||||
end
|
||||
|
||||
# Add a new callable to be executed for the `name` hook.
|
||||
# @param [Symbol] name The name of the hook.
|
||||
# @param [#call] callable The callable.
|
||||
# @yield The block to use as the callable (if `callable` parameter not provided)
|
||||
def add_hook(name, callable=nil, &block)
|
||||
@hooks[name] ||= []
|
||||
|
||||
if block
|
||||
@hooks[name] << block
|
||||
elsif callable
|
||||
@hooks[name] << callable
|
||||
else
|
||||
raise ArgumentError, "Must provide a block or callable."
|
||||
end
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
# Execute the list of callables for the `name` hook.
|
||||
# @param [Symbol] name The name of the hook to execute.
|
||||
# @param [Array] args The arguments to pass to each callable.
|
||||
def exec_hook(name, *args, &block)
|
||||
Array(@hooks[name]).each { |v| v.call(*args, &block) }
|
||||
end
|
||||
|
||||
# Return the number of callables registered for the `name` hook.
|
||||
# @param [Symbol] name The name of the hook.
|
||||
def hook_count(name)
|
||||
@hooks[name] ||= []
|
||||
@hooks[name].size
|
||||
end
|
||||
|
||||
# Clear the list of callables for the `name` hook.
|
||||
# @param [Symbol] The name of the hook to delete.
|
||||
def delete_hook(name)
|
||||
@hooks[name] = []
|
||||
end
|
||||
|
||||
# Clear all hooks.
|
||||
def reset
|
||||
@hooks = {}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -1,3 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
class Pry
|
||||
class Method
|
||||
include RbxMethod if Helpers::BaseHelpers.rbx?
|
||||
|
@ -178,7 +179,7 @@ class Pry
|
|||
if Helpers::BaseHelpers.rbx? && core?
|
||||
code = core_code
|
||||
elsif pry_method?
|
||||
code = Pry.new(:input => StringIO.new(Pry.line_buffer[source_line..-1].join), :prompt => proc {""}, :hooks => {}).r
|
||||
code = Pry.new(:input => StringIO.new(Pry.line_buffer[source_line..-1].join), :prompt => proc {""}, :hooks => Pry::Hooks.new).r
|
||||
else
|
||||
code = @method.source
|
||||
end
|
||||
|
|
|
@ -165,7 +165,7 @@ class Pry
|
|||
|
||||
output = options[:show_output] ? options[:output] : StringIO.new
|
||||
|
||||
Pry.new(:output => output, :input => StringIO.new(command_string), :commands => options[:commands], :prompt => proc {""}, :hooks => {}).rep(options[:context])
|
||||
Pry.new(:output => output, :input => StringIO.new(command_string), :commands => options[:commands], :prompt => proc {""}, :hooks => Pry::Hooks.new).rep(options[:context])
|
||||
end
|
||||
|
||||
def self.default_editor_for_platform
|
||||
|
|
|
@ -149,7 +149,7 @@ class Pry
|
|||
# Initialize the repl session.
|
||||
# @param [Binding] target The target binding for the session.
|
||||
def repl_prologue(target)
|
||||
exec_hook :before_session, output, target, self
|
||||
hooks.exec_hook :before_session, output, target, self
|
||||
initialize_special_locals(target)
|
||||
|
||||
@input_array << nil # add empty input so _in_ and _out_ match
|
||||
|
@ -161,7 +161,7 @@ class Pry
|
|||
# Clean-up after the repl session.
|
||||
# @param [Binding] target The target binding for the session.
|
||||
def repl_epilogue(target)
|
||||
exec_hook :after_session, output, target, self
|
||||
hooks.exec_hook :after_session, output, target, self
|
||||
|
||||
Pry.active_sessions -= 1
|
||||
binding_stack.pop
|
||||
|
@ -235,9 +235,10 @@ class Pry
|
|||
result = set_last_result(target.eval(code, Pry.eval_path, Pry.current_line), target)
|
||||
result
|
||||
rescue RescuableException => e
|
||||
set_last_exception(e, target)
|
||||
result = set_last_exception(e, target)
|
||||
ensure
|
||||
update_input_history(code)
|
||||
hooks.exec_hook :after_eval, result, self
|
||||
end
|
||||
|
||||
# Perform a read.
|
||||
|
@ -270,6 +271,7 @@ class Pry
|
|||
|
||||
@suppress_output = true if eval_string =~ /;\Z/ || eval_string.empty?
|
||||
|
||||
hooks.exec_hook :after_read, eval_string, self
|
||||
eval_string
|
||||
end
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ class << Pry
|
|||
Pry.config.history.should_load = false
|
||||
Pry.config.history.should_save = false
|
||||
Pry.config.auto_indent = false
|
||||
Pry.config.hooks = { }
|
||||
Pry.config.hooks = Pry::Hooks.new
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ describe "Pry::DefaultCommands::Input" do
|
|||
b = binding
|
||||
b.eval('x = "\"hello\""')
|
||||
redirect_pry_io(InputTester.new("play x", "exit-all"), str_output = StringIO.new) do
|
||||
Pry.start b, :hooks => {}
|
||||
Pry.start b, :hooks => Pry::Hooks.new
|
||||
end
|
||||
str_output.string.should =~ /hello/
|
||||
end
|
||||
|
@ -163,7 +163,7 @@ describe "Pry::DefaultCommands::Input" do
|
|||
b = binding
|
||||
b.eval('x = "\"hello\"\n\"goodbye\"\n\"love\""')
|
||||
redirect_pry_io(InputTester.new("play x --lines 1", "exit-all"), str_output = StringIO.new) do
|
||||
Pry.start b, :hooks => {}
|
||||
Pry.start b, :hooks => Pry::Hooks.new
|
||||
end
|
||||
str_output.string.should =~ /hello/
|
||||
str_output.string.should.not =~ /love/
|
||||
|
|
85
test/test_hooks.rb
Normal file
85
test/test_hooks.rb
Normal file
|
@ -0,0 +1,85 @@
|
|||
require 'helper'
|
||||
|
||||
describe Pry::Hooks do
|
||||
before do
|
||||
@hooks = Pry::Hooks.new
|
||||
end
|
||||
|
||||
describe "adding a new hook" do
|
||||
it 'should not execute hook while adding it' do
|
||||
@hooks.add_hook(:test_hook) { @test_var = true }
|
||||
@test_var.should == nil
|
||||
end
|
||||
|
||||
it 'should return a count of 0 for an empty hook' do
|
||||
@hooks.hook_count(:test_hook).should == 0
|
||||
end
|
||||
|
||||
it 'should create a new hook with a block' do
|
||||
@hooks.add_hook(:test_hook) { }
|
||||
@hooks.hook_count(:test_hook).should == 1
|
||||
end
|
||||
|
||||
it 'should create a new hook with a callable' do
|
||||
@hooks.add_hook(:test_hook, proc { })
|
||||
@hooks.hook_count(:test_hook).should == 1
|
||||
end
|
||||
|
||||
it 'should use just block if given both block and callable' do
|
||||
@hooks.add_hook(:test_hook, proc { }) { }
|
||||
@hooks.hook_count(:test_hook).should == 1
|
||||
end
|
||||
|
||||
it 'should raise if not given a block or any other object' do
|
||||
lambda { @hooks.add_hook(:test_hook) }.should.raise ArgumentError
|
||||
end
|
||||
|
||||
it 'should create a hook with multiple callables' do
|
||||
@hooks.add_hook(:test_hook) {}
|
||||
@hooks.add_hook(:test_hook) {}
|
||||
@hooks.hook_count(:test_hook).should == 2
|
||||
end
|
||||
end
|
||||
|
||||
describe "executing a hook" do
|
||||
before do
|
||||
@test_var = nil
|
||||
end
|
||||
|
||||
it 'should execute block hook' do
|
||||
@hooks.add_hook(:test_hook) { @test_var = true }
|
||||
@hooks.exec_hook(:test_hook)
|
||||
@test_var.should == true
|
||||
end
|
||||
|
||||
it 'should execute proc hook' do
|
||||
@hooks.add_hook(:test_hook, proc { @test_var = true })
|
||||
@hooks.exec_hook(:test_hook)
|
||||
@test_var.should == true
|
||||
end
|
||||
|
||||
it 'should execute a general callable hook' do
|
||||
callable = Object.new.tap do |obj|
|
||||
obj.instance_variable_set(:@test_var, nil)
|
||||
class << obj
|
||||
attr_accessor :test_var
|
||||
def call() @test_var = true; end
|
||||
end
|
||||
end
|
||||
|
||||
@hooks.add_hook(:test_hook, callable)
|
||||
@hooks.exec_hook(:test_hook)
|
||||
callable.test_var.should == true
|
||||
end
|
||||
|
||||
it 'should execute multiple callables for a hook if more than one is defined' do
|
||||
x = nil
|
||||
y = nil
|
||||
@hooks.add_hook(:test_hook) { x = true }
|
||||
@hooks.add_hook(:test_hook) { y = true }
|
||||
@hooks.exec_hook(:test_hook)
|
||||
x.should == true
|
||||
y.should == true
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1281,10 +1281,9 @@ describe Pry do
|
|||
|
||||
it 'should set the hooks default, and the default should be overridable' do
|
||||
Pry.input = InputTester.new("exit-all")
|
||||
Pry.hooks = {
|
||||
:before_session => proc { |out,_,_| out.puts "HELLO" },
|
||||
:after_session => proc { |out,_,_| out.puts "BYE" }
|
||||
}
|
||||
Pry.hooks = Pry::Hooks.new.
|
||||
add_hook(:before_session) { |out,_,_| out.puts "HELLO" }.
|
||||
add_hook(:after_session) { |out,_,_| out.puts "BYE" }
|
||||
|
||||
str_output = StringIO.new
|
||||
Pry.new(:output => str_output).repl
|
||||
|
@ -1295,10 +1294,9 @@ describe Pry do
|
|||
|
||||
str_output = StringIO.new
|
||||
Pry.new(:output => str_output,
|
||||
:hooks => {
|
||||
:before_session => proc { |out,_,_| out.puts "MORNING" },
|
||||
:after_session => proc { |out,_,_| out.puts "EVENING" }
|
||||
}
|
||||
:hooks => Pry::Hooks.new.
|
||||
add_hook( :before_session) { |out,_,_| out.puts "MORNING" }.
|
||||
add_hook(:after_session) { |out,_,_| out.puts "EVENING" }
|
||||
).repl
|
||||
|
||||
str_output.string.should =~ /MORNING/
|
||||
|
@ -1308,9 +1306,8 @@ describe Pry do
|
|||
Pry.input.rewind
|
||||
str_output = StringIO.new
|
||||
Pry.new(:output => str_output,
|
||||
:hooks => {
|
||||
:before_session => proc { |out,_,_| out.puts "OPEN" }
|
||||
}
|
||||
:hooks => Pry::Hooks.new.
|
||||
add_hook(:before_session) { |out,_,_| out.puts "OPEN" }
|
||||
).repl
|
||||
|
||||
str_output.string.should =~ /OPEN/
|
||||
|
@ -1318,9 +1315,8 @@ describe Pry do
|
|||
Pry.input.rewind
|
||||
str_output = StringIO.new
|
||||
Pry.new(:output => str_output,
|
||||
:hooks => {
|
||||
:after_session => proc { |out,_,_| out.puts "CLOSE" }
|
||||
}
|
||||
:hooks => Pry::Hooks.new.
|
||||
add_hook(:after_session) { |out,_,_| out.puts "CLOSE" }
|
||||
).repl
|
||||
|
||||
str_output.string.should =~ /CLOSE/
|
||||
|
|
Loading…
Reference in a new issue