mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
Add prompt stack to fix bug where prompt is not restored after returning from shell-mode
When returning from shell-mode, the prompt is not properly restored. The problem is that it gets clobbered by the new prompt, so we need somewhere to store it. This adds a prompt stack so you can push and pop prompts in order to temporarily change the current prompt and then later restore the previous prompt. prompt and prompt= are also overridden to have meaning in the context of the prompt stack.
This commit is contained in:
parent
fde297e05b
commit
94c618cbd1
3 changed files with 121 additions and 3 deletions
|
@ -270,10 +270,10 @@ e.g: gist -d my_method
|
||||||
command "shell-mode", "Toggle shell mode. Bring in pwd prompt and file completion." do
|
command "shell-mode", "Toggle shell mode. Bring in pwd prompt and file completion." do
|
||||||
case Pry.active_instance.prompt
|
case Pry.active_instance.prompt
|
||||||
when Pry::SHELL_PROMPT
|
when Pry::SHELL_PROMPT
|
||||||
Pry.active_instance.prompt = Pry::DEFAULT_PROMPT
|
Pry.active_instance.pop_prompt
|
||||||
Pry.active_instance.custom_completions = Pry::DEFAULT_CUSTOM_COMPLETIONS
|
Pry.active_instance.custom_completions = Pry::DEFAULT_CUSTOM_COMPLETIONS
|
||||||
else
|
else
|
||||||
Pry.active_instance.prompt = Pry::SHELL_PROMPT
|
Pry.active_instance.push_prompt Pry::SHELL_PROMPT
|
||||||
Pry.active_instance.custom_completions = Pry::FILE_COMPLETIONS
|
Pry.active_instance.custom_completions = Pry::FILE_COMPLETIONS
|
||||||
Readline.completion_proc = Pry::InputCompleter.build_completion_proc target,
|
Readline.completion_proc = Pry::InputCompleter.build_completion_proc target,
|
||||||
Pry.active_instance.instance_eval(&Pry::FILE_COMPLETIONS)
|
Pry.active_instance.instance_eval(&Pry::FILE_COMPLETIONS)
|
||||||
|
|
|
@ -30,7 +30,7 @@ class Pry
|
||||||
default_options.merge!(options)
|
default_options.merge!(options)
|
||||||
|
|
||||||
CONFIG_OPTIONS.each do |key|
|
CONFIG_OPTIONS.each do |key|
|
||||||
instance_variable_set("@#{key}", default_options[key])
|
send "#{key}=", default_options[key]
|
||||||
end
|
end
|
||||||
|
|
||||||
@command_processor = CommandProcessor.new(self)
|
@command_processor = CommandProcessor.new(self)
|
||||||
|
@ -320,6 +320,63 @@ class Pry
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# the array that the prompt stack is stored in
|
||||||
|
def prompt_stack
|
||||||
|
@prompt_stack ||= Array.new
|
||||||
|
end
|
||||||
|
private :prompt_stack
|
||||||
|
|
||||||
|
# The current prompt, this is the prompt at the top of the prompt stack.
|
||||||
|
# @return [Array<Proc>] Current prompt.
|
||||||
|
# @example
|
||||||
|
# push_prompt(Pry::SIMPLE_PROMPT)
|
||||||
|
# prompt # => Pry::SIMPLE_PROMPT
|
||||||
|
def prompt
|
||||||
|
prompt_stack.last
|
||||||
|
end
|
||||||
|
|
||||||
|
# Replaces the current prompt with the new prompt.
|
||||||
|
# Does not change the rest of the prompt stack.
|
||||||
|
# @param [Array<Proc>] new_prompt
|
||||||
|
# @return [Array<Proc>] new_prompt
|
||||||
|
# @example
|
||||||
|
# pry.prompt = Pry::SIMPLE_PROMPT # => Pry::SIMPLE_PROMPT
|
||||||
|
# pry.prompt # => Pry::SIMPLE_PROMPT
|
||||||
|
def prompt=(new_prompt)
|
||||||
|
if prompt_stack.empty?
|
||||||
|
push_prompt new_prompt
|
||||||
|
else
|
||||||
|
prompt_stack[-1] = new_prompt
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Pushes the current prompt onto a stack that it can be restored from later.
|
||||||
|
# Use this if you wish to temporarily change the prompt.
|
||||||
|
# @param [Array<Proc>] new_prompt
|
||||||
|
# @return [Array<Proc>] new_prompt
|
||||||
|
# @example
|
||||||
|
# new_prompt = [ proc { '>' }, proc { '>>' } ]
|
||||||
|
# push_prompt(new_prompt) # => new_prompt
|
||||||
|
def push_prompt(new_prompt)
|
||||||
|
prompt_stack.push new_prompt
|
||||||
|
end
|
||||||
|
|
||||||
|
# Pops the current prompt off of the prompt stack.
|
||||||
|
# If the prompt you are popping is the last prompt, it will not be popped.
|
||||||
|
# Use this to restore the previous prompt.
|
||||||
|
# @return [Array<Proc>] Prompt being popped.
|
||||||
|
# @example
|
||||||
|
# prompt1 = [ proc { '>' }, proc { '>>' } ]
|
||||||
|
# prompt2 = [ proc { '$' }, proc { '>' } ]
|
||||||
|
# pry = Pry.new :prompt => prompt1
|
||||||
|
# pry.push_prompt(prompt2)
|
||||||
|
# pry.pop_prompt # => prompt2
|
||||||
|
# pry.pop_prompt # => prompt1
|
||||||
|
# pry.pop_prompt # => prompt1
|
||||||
|
def pop_prompt
|
||||||
|
if prompt_stack.size > 1 then prompt_stack.pop else prompt end
|
||||||
|
end
|
||||||
|
|
||||||
if RUBY_VERSION =~ /1.9/ && RUBY_ENGINE == "ruby"
|
if RUBY_VERSION =~ /1.9/ && RUBY_ENGINE == "ruby"
|
||||||
require 'ripper'
|
require 'ripper'
|
||||||
|
|
||||||
|
|
61
test/test.rb
61
test/test.rb
|
@ -737,6 +737,67 @@ describe Pry do
|
||||||
Pry.new.select_prompt(true, 0).should == "test prompt> "
|
Pry.new.select_prompt(true, 0).should == "test prompt> "
|
||||||
Pry.new.select_prompt(false, 0).should == "test prompt* "
|
Pry.new.select_prompt(false, 0).should == "test prompt* "
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'storing and restoring the prompt' do
|
||||||
|
before do
|
||||||
|
make = lambda do |name,i|
|
||||||
|
prompt = [ proc { "#{i}>" } , proc { "#{i+1}>" } ]
|
||||||
|
(class << prompt; self; end).send(:define_method, :inspect) { "<Prompt-#{name}>" }
|
||||||
|
prompt
|
||||||
|
end
|
||||||
|
@a , @b , @c = make[:a,0] , make[:b,1] , make[:c,2]
|
||||||
|
@pry = Pry.new :prompt => @a
|
||||||
|
end
|
||||||
|
it 'should have a prompt stack' do
|
||||||
|
@pry.push_prompt @b
|
||||||
|
@pry.push_prompt @c
|
||||||
|
@pry.prompt.should == @c
|
||||||
|
@pry.pop_prompt
|
||||||
|
@pry.prompt.should == @b
|
||||||
|
@pry.pop_prompt
|
||||||
|
@pry.prompt.should == @a
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should restore overridden prompts when returning from file-mode' do
|
||||||
|
pry = Pry.new :input => InputTester.new('shell-mode', 'shell-mode'),
|
||||||
|
:prompt => [ proc { 'P>' } ] * 2
|
||||||
|
pry.select_prompt(true, 0).should == "P>"
|
||||||
|
pry.re
|
||||||
|
pry.select_prompt(true, 0).should =~ /\Apry .* \$ \z/
|
||||||
|
pry.re
|
||||||
|
pry.select_prompt(true, 0).should == "P>"
|
||||||
|
end
|
||||||
|
|
||||||
|
it '#pop_prompt should return the popped prompt' do
|
||||||
|
@pry.push_prompt @b
|
||||||
|
@pry.push_prompt @c
|
||||||
|
@pry.pop_prompt.should == @c
|
||||||
|
@pry.pop_prompt.should == @b
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not pop the last prompt' do
|
||||||
|
@pry.push_prompt @b
|
||||||
|
@pry.pop_prompt.should == @b
|
||||||
|
@pry.pop_prompt.should == @a
|
||||||
|
@pry.pop_prompt.should == @a
|
||||||
|
@pry.prompt.should == @a
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#prompt= should replace the current prompt with the new prompt' do
|
||||||
|
it 'when only one prompt on the stack' do
|
||||||
|
@pry.prompt = @b
|
||||||
|
@pry.prompt.should == @b
|
||||||
|
@pry.pop_prompt.should == @b
|
||||||
|
@pry.pop_prompt.should == @b
|
||||||
|
end
|
||||||
|
it 'when several prompts on the stack' do
|
||||||
|
@pry.push_prompt @b
|
||||||
|
@pry.prompt = @c
|
||||||
|
@pry.pop_prompt.should == @c
|
||||||
|
@pry.pop_prompt.should == @a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should set the hooks default, and the default should be overridable' do
|
it 'should set the hooks default, and the default should be overridable' do
|
||||||
|
|
Loading…
Reference in a new issue