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

config: factor out control_d_handler to ControlDHandler

This commit is contained in:
Kyrylo Silin 2019-04-15 03:18:17 +03:00
parent f89d0eccac
commit 340f672f1d
4 changed files with 67 additions and 68 deletions

View file

@ -23,6 +23,7 @@ require 'pry/history'
require 'pry/color_printer'
require 'pry/exception_handler'
require 'pry/system_command_handler'
require 'pry/control_d_handler'
Pry::Commands = Pry::CommandSet.new unless defined?(Pry::Commands)

View file

@ -51,27 +51,7 @@ class Pry
should_load_requires: true,
should_load_plugins: true,
windows_console_warning: true,
# Deal with the ^D key being pressed. Different behaviour in different
# cases:
# 1. In an expression behave like `!` command.
# 2. At top-level session behave like `exit` command.
# 3. In a nested session behave like `cd ..`.
control_d_handler: proc do |eval_string, pry_instance|
if !eval_string.empty?
eval_string.replace('') # Clear input buffer.
elsif pry_instance.binding_stack.one?
pry_instance.binding_stack.clear
throw(:breakout)
else
# Otherwise, saves current binding stack as old stack and pops last
# binding out of binding stack (the old stack still has that binding).
pry_instance.command_state["cd"] ||= Pry::Config.from_hash({})
pry_instance.command_state['cd'].old_stack = pry_instance.binding_stack.dup
pry_instance.binding_stack.pop
end
end,
control_d_handler: Pry::ControlDHandler.method(:default),
memory_size: 100,
extra_sticky_locals: {},
command_completions: proc { defaults.commands.keys },

View file

@ -0,0 +1,25 @@
class Pry
# @api private
# @since ?.?.?
module ControlDHandler
# Deal with the ^D key being pressed. Different behaviour in different
# cases:
# 1. In an expression behave like `!` command.
# 2. At top-level session behave like `exit` command.
# 3. In a nested session behave like `cd ..`.
def self.default(eval_string, pry_instance)
if !eval_string.empty?
eval_string.replace('') # Clear input buffer.
elsif pry_instance.binding_stack.one?
pry_instance.binding_stack.clear
throw(:breakout)
else
# Otherwise, saves current binding stack as old stack and pops last
# binding out of binding stack (the old stack still has that binding).
pry_instance.command_state['cd'] ||= Pry::Config.from_hash({})
pry_instance.command_state['cd'].old_stack = pry_instance.binding_stack.dup
pry_instance.binding_stack.pop
end
end
end
end

View file

@ -1,56 +1,49 @@
describe 'Pry::Config.defaults.control_d_handler' do
describe "control-d press" do
before do
# Simulates a ^D press.
@control_d = "Pry::Config.defaults.control_d_handler.call('', pry_instance)"
RSpec.describe Pry::ControlDHandler do
context "when given eval string is non-empty" do
let(:eval_string) { 'hello' }
let(:pry_instance) { Pry.new }
it "clears input buffer" do
described_class.default(eval_string, pry_instance)
expect(eval_string).to be_empty
end
end
context "when given eval string is empty & pry instance has one binding" do
let(:eval_string) { '' }
let(:pry_instance) { Pry.new.tap { |p| p.binding_stack = [binding] } }
it "throws :breakout" do
expect { described_class.default(eval_string, pry_instance) }
.to throw_symbol(:breakout)
end
describe "in an expression" do
it "should clear out passed string" do
str = 'hello world'
Pry::Config.defaults.control_d_handler.call(str, nil)
expect(str).to eq ''
end
it "clears binding stack" do
expect { described_class.default(eval_string, pry_instance) }
.to throw_symbol
expect(pry_instance.binding_stack).to be_empty
end
end
context "when given eval string is empty & pry instance has 2+ bindings" do
let(:eval_string) { '' }
let(:binding1) { binding }
let(:binding2) { binding }
let(:binding_stack) { [binding1, binding2] }
let(:pry_instance) do
Pry.new.tap { |p| p.binding_stack = binding_stack }
end
describe 'at top-level session' do
it 'should break out of a REPL loop' do
instance = Pry.new
expect(instance.binding_stack).not_to be_empty
expect(instance.eval(nil)).to equal false
expect(instance.binding_stack).to be_empty
end
it "saves a dup of the current binding stack in the 'cd' command" do
described_class.default(eval_string, pry_instance)
cd_state = pry_instance.command_state['cd']
expect(cd_state.old_stack).to eq([binding1, binding2])
end
describe 'in a nested session' do
it 'should pop last binding from the binding stack' do
t = pry_tester
t.eval "cd Object.new"
expect(t.eval("pry_instance.binding_stack.size")).to eq 2
expect(t.eval("pry_instance.eval(nil)")).to equal true
expect(t.eval("pry_instance.binding_stack.size")).to eq 1
end
it "breaks out of the parent session" do
ReplTester.start do
input 'Pry::REPL.new(pry_instance, :target => 10).start'
output ''
prompt(/10.*> $/)
input 'self'
output '=> 10'
input nil # Ctrl-D
output ''
input 'self'
output '=> main'
input nil # Ctrl-D
output '=> nil' # Exit value of nested REPL.
assert_exited
end
end
it "pops the binding off the stack" do
described_class.default(eval_string, pry_instance)
expect(pry_instance.binding_stack).to eq([binding1])
end
end
end