From c3d27d9f3123e6cf17143e2bee3a110268f3f4ca Mon Sep 17 00:00:00 2001 From: John Mair Date: Thu, 12 Jul 2012 23:13:13 +1200 Subject: [PATCH] passing extra prompt data via an OpenStruct --- lib/pry.rb | 12 ++++----- lib/pry/history.rb | 15 ++++++++++- lib/pry/indent.rb | 5 +++- lib/pry/pry_class.rb | 7 +---- lib/pry/pry_instance.rb | 25 ++++++++++++++--- pry.gemspec | 6 ++--- test/test_hooks.rb | 1 + test/test_prompt.rb | 60 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 110 insertions(+), 21 deletions(-) create mode 100644 test/test_prompt.rb diff --git a/lib/pry.rb b/lib/pry.rb index f846b8a9..3a6eb1bd 100644 --- a/lib/pry.rb +++ b/lib/pry.rb @@ -83,13 +83,13 @@ class Pry # A prompt that includes the full object path as well as # input/output (_in_ and _out_) information. Good for navigation. NAV_PROMPT = [ - proc do |_, level, pry| - tree = pry.binding_stack.map { |b| Pry.view_clip(b.eval("self")) }.join " / " - "[#{pry.input_array.size}] (pry) #{tree}: #{level}> " + proc do |conf| + tree = conf.binding_stack.map { |b| Pry.view_clip(b.eval("self")) }.join " / " + "[#{conf.input_array.size}] (pry) #{tree}: #{conf.nesting_level}> " end, - proc do |_, level, pry| - tree = pry.binding_stack.map { |b| Pry.view_clip(b.eval("self")) }.join " / " - "[#{pry.input_array.size}] (pry) #{tree}: #{level}* " + proc do |conf| + tree = conf.binding_stack.map { |b| Pry.view_clip(b.eval("self")) }.join " / " + "[#{conf.input_array.size}] (pry) #{tree}: #{conf.nesting_level}* " end, ] diff --git a/lib/pry/history.rb b/lib/pry/history.rb index a9b7f2a7..df50df21 100644 --- a/lib/pry/history.rb +++ b/lib/pry/history.rb @@ -4,9 +4,13 @@ class Pry class History attr_accessor :loader, :saver, :pusher, :clearer + # @return [Fixnum] Number of lines in history when Pry first loaded. + attr_reader :original_lines + def initialize @history = [] @saved_lines = 0 + @original_lines = 0 restore_default_behavior end @@ -25,7 +29,7 @@ class Pry @pusher.call(line.chomp) @history << line.chomp end - @saved_lines = @history.length + @saved_lines = @original_lines = @history.length end # Write this session's history using `History.saver`. @@ -58,6 +62,15 @@ class Pry @saved_lines = 0 end + # @return [Fixnum] The number of lines in history. + def history_line_count + @history.count + end + + def session_line_count + @history.count - @original_lines + end + # Return an Array containing all stored history. # @return [Array] An Array containing all lines of history loaded # or entered by the user in the current session. diff --git a/lib/pry/indent.rb b/lib/pry/indent.rb index 16138dd3..5d612701 100644 --- a/lib/pry/indent.rb +++ b/lib/pry/indent.rb @@ -17,8 +17,11 @@ class Pry class Indent include Helpers::BaseHelpers - # String containing the spaces to be inserted before the next line. + # @return [String] String containing the spaces to be inserted before the next line. attr_reader :indent_level + + # @return [Array] The stack of open tokens. + attr_reader :stack # The amount of spaces to insert for each indent level. SPACES = ' ' diff --git a/lib/pry/pry_class.rb b/lib/pry/pry_class.rb index 326d3a45..2e3a0c7e 100644 --- a/lib/pry/pry_class.rb +++ b/lib/pry/pry_class.rb @@ -136,12 +136,7 @@ class Pry pry_instance.backtrace.shift if pry_instance.backtrace.first =~ /pry.*core_extensions.*pry/ # yield the binding_stack to the hook for modification - pry_instance.exec_hook( - :when_started, - target, - options, - pry_instance - ) + pry_instance.exec_hook(:when_started, target, options, pry_instance) if !pry_instance.binding_stack.empty? head = pry_instance.binding_stack.pop diff --git a/lib/pry/pry_instance.rb b/lib/pry/pry_instance.rb index dadb81b7..b2382214 100644 --- a/lib/pry/pry_instance.rb +++ b/lib/pry/pry_instance.rb @@ -323,9 +323,9 @@ class Pry # Output the result or pass to an exception handler (if result is an exception). def show_result(result) if last_result_is_exception? - exception_handler.call output, result, self + exception_handler.call(output, result, self) else - print.call output, result + print.call(output, result) end rescue RescuableException => e # Being uber-paranoid here, given that this exception arose because we couldn't @@ -626,13 +626,30 @@ class Pry def select_prompt(eval_string, target) target_self = target.eval('self') + open_token = @indent.open_delimiters.any? ? @indent.open_delimiters.last : + @indent.stack.last + + c = OpenStruct.new( + :object => target_self, + :nesting_level => binding_stack.size - 1, + :open_token => open_token, + :session_line => Pry.history.session_line_count + 1, + :history_line => Pry.history.history_line_count + 1, + :expr_number => input_array.count, + :_pry_ => self, + :binding_stack => binding_stack, + :input_array => input_array, + :eval_string => eval_string, + :cont => !eval_string.empty?) + def c.to_ary() [object, nesting_level, _pry_] end + # If input buffer is empty then use normal prompt if eval_string.empty? - Array(prompt).first.call(target_self, binding_stack.size - 1, self) + Array(prompt).first.call(c) # Otherwise use the wait prompt (indicating multi-line expression) else - Array(prompt).last.call(target_self, binding_stack.size - 1, self) + Array(prompt).last.call(c) end end diff --git a/pry.gemspec b/pry.gemspec index 3001f65f..639c7a43 100644 --- a/pry.gemspec +++ b/pry.gemspec @@ -6,16 +6,16 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version= s.authors = ["John Mair (banisterfiend)", "Conrad Irwin"] - s.date = "2012-07-05" + s.date = "2012-07-13" s.description = "An IRB alternative and runtime developer console" s.email = ["jrmair@gmail.com", "conrad.irwin@gmail.com"] s.executables = ["pry"] - s.files = [".document", ".gemtest", ".gitignore", ".travis.yml", ".yardopts", "CHANGELOG", "CONTRIBUTORS", "Gemfile", "LICENSE", "README.markdown", "Rakefile", "TODO", "bin/pry", "examples/example_basic.rb", "examples/example_command_override.rb", "examples/example_commands.rb", "examples/example_hooks.rb", "examples/example_image_edit.rb", "examples/example_input.rb", "examples/example_input2.rb", "examples/example_output.rb", "examples/example_print.rb", "examples/example_prompt.rb", "examples/helper.rb", "lib/pry.rb", "lib/pry/cli.rb", "lib/pry/code.rb", "lib/pry/command.rb", "lib/pry/command_set.rb", "lib/pry/commands.rb", "lib/pry/completion.rb", "lib/pry/config.rb", "lib/pry/core_extensions.rb", "lib/pry/custom_completions.rb", "lib/pry/default_commands/cd.rb", "lib/pry/default_commands/commands.rb", "lib/pry/default_commands/context.rb", "lib/pry/default_commands/easter_eggs.rb", "lib/pry/default_commands/editing.rb", "lib/pry/default_commands/find_method.rb", "lib/pry/default_commands/gems.rb", "lib/pry/default_commands/gist.rb", "lib/pry/default_commands/help.rb", "lib/pry/default_commands/hist.rb", "lib/pry/default_commands/input_and_output.rb", "lib/pry/default_commands/introspection.rb", "lib/pry/default_commands/ls.rb", "lib/pry/default_commands/misc.rb", "lib/pry/default_commands/navigating_pry.rb", "lib/pry/default_commands/whereami.rb", "lib/pry/extended_commands/experimental.rb", "lib/pry/helpers.rb", "lib/pry/helpers/base_helpers.rb", "lib/pry/helpers/command_helpers.rb", "lib/pry/helpers/documentation_helpers.rb", "lib/pry/helpers/options_helpers.rb", "lib/pry/helpers/text.rb", "lib/pry/history.rb", "lib/pry/history_array.rb", "lib/pry/hooks.rb", "lib/pry/indent.rb", "lib/pry/method.rb", "lib/pry/module_candidate.rb", "lib/pry/plugins.rb", "lib/pry/pry_class.rb", "lib/pry/pry_instance.rb", "lib/pry/rbx_method.rb", "lib/pry/rbx_path.rb", "lib/pry/repl_file_loader.rb", "lib/pry/version.rb", "lib/pry/wrapped_module.rb", "man/pry.1", "man/pry.1.html", "man/pry.1.ronn", "pry.gemspec", "test/candidate_helper1.rb", "test/candidate_helper2.rb", "test/helper.rb", "test/test_cli.rb", "test/test_code.rb", "test/test_command.rb", "test/test_command_helpers.rb", "test/test_command_integration.rb", "test/test_command_set.rb", "test/test_completion.rb", "test/test_control_d_handler.rb", "test/test_default_commands/example.erb", "test/test_default_commands/test_cd.rb", "test/test_default_commands/test_context.rb", "test/test_default_commands/test_documentation.rb", "test/test_default_commands/test_find_method.rb", "test/test_default_commands/test_gems.rb", "test/test_default_commands/test_help.rb", "test/test_default_commands/test_input.rb", "test/test_default_commands/test_introspection.rb", "test/test_default_commands/test_ls.rb", "test/test_default_commands/test_shell.rb", "test/test_default_commands/test_show_source.rb", "test/test_exception_whitelist.rb", "test/test_history_array.rb", "test/test_hooks.rb", "test/test_indent.rb", "test/test_input_stack.rb", "test/test_method.rb", "test/test_pry.rb", "test/test_pry_defaults.rb", "test/test_pry_history.rb", "test/test_pry_output.rb", "test/test_sticky_locals.rb", "test/test_syntax_checking.rb", "test/test_wrapped_module.rb", "test/testrc", "test/testrcbad", "wiki/Customizing-pry.md", "wiki/Home.md"] + s.files = [".document", ".gemtest", ".gitignore", ".travis.yml", ".yardopts", "CHANGELOG", "CONTRIBUTORS", "Gemfile", "LICENSE", "README.markdown", "Rakefile", "TODO", "bin/pry", "examples/example_basic.rb", "examples/example_command_override.rb", "examples/example_commands.rb", "examples/example_hooks.rb", "examples/example_image_edit.rb", "examples/example_input.rb", "examples/example_input2.rb", "examples/example_output.rb", "examples/example_print.rb", "examples/example_prompt.rb", "examples/helper.rb", "lib/pry.rb", "lib/pry/cli.rb", "lib/pry/code.rb", "lib/pry/command.rb", "lib/pry/command_set.rb", "lib/pry/commands.rb", "lib/pry/completion.rb", "lib/pry/config.rb", "lib/pry/core_extensions.rb", "lib/pry/custom_completions.rb", "lib/pry/default_commands/cd.rb", "lib/pry/default_commands/commands.rb", "lib/pry/default_commands/context.rb", "lib/pry/default_commands/easter_eggs.rb", "lib/pry/default_commands/editing.rb", "lib/pry/default_commands/find_method.rb", "lib/pry/default_commands/gems.rb", "lib/pry/default_commands/gist.rb", "lib/pry/default_commands/help.rb", "lib/pry/default_commands/hist.rb", "lib/pry/default_commands/input_and_output.rb", "lib/pry/default_commands/introspection.rb", "lib/pry/default_commands/ls.rb", "lib/pry/default_commands/misc.rb", "lib/pry/default_commands/navigating_pry.rb", "lib/pry/default_commands/whereami.rb", "lib/pry/extended_commands/experimental.rb", "lib/pry/helpers.rb", "lib/pry/helpers/base_helpers.rb", "lib/pry/helpers/command_helpers.rb", "lib/pry/helpers/documentation_helpers.rb", "lib/pry/helpers/options_helpers.rb", "lib/pry/helpers/text.rb", "lib/pry/history.rb", "lib/pry/history_array.rb", "lib/pry/hooks.rb", "lib/pry/indent.rb", "lib/pry/method.rb", "lib/pry/module_candidate.rb", "lib/pry/plugins.rb", "lib/pry/pry_class.rb", "lib/pry/pry_instance.rb", "lib/pry/rbx_method.rb", "lib/pry/rbx_path.rb", "lib/pry/repl_file_loader.rb", "lib/pry/version.rb", "lib/pry/wrapped_module.rb", "man/pry.1", "man/pry.1.html", "man/pry.1.ronn", "pry.gemspec", "test/candidate_helper1.rb", "test/candidate_helper2.rb", "test/helper.rb", "test/test_cli.rb", "test/test_code.rb", "test/test_command.rb", "test/test_command_helpers.rb", "test/test_command_integration.rb", "test/test_command_set.rb", "test/test_completion.rb", "test/test_control_d_handler.rb", "test/test_default_commands/example.erb", "test/test_default_commands/test_cd.rb", "test/test_default_commands/test_context.rb", "test/test_default_commands/test_documentation.rb", "test/test_default_commands/test_find_method.rb", "test/test_default_commands/test_gems.rb", "test/test_default_commands/test_help.rb", "test/test_default_commands/test_input.rb", "test/test_default_commands/test_introspection.rb", "test/test_default_commands/test_ls.rb", "test/test_default_commands/test_shell.rb", "test/test_default_commands/test_show_source.rb", "test/test_exception_whitelist.rb", "test/test_history_array.rb", "test/test_hooks.rb", "test/test_indent.rb", "test/test_input_stack.rb", "test/test_method.rb", "test/test_prompt.rb", "test/test_pry.rb", "test/test_pry_defaults.rb", "test/test_pry_history.rb", "test/test_pry_output.rb", "test/test_sticky_locals.rb", "test/test_syntax_checking.rb", "test/test_wrapped_module.rb", "test/testrc", "test/testrcbad", "wiki/Customizing-pry.md", "wiki/Home.md"] s.homepage = "http://pry.github.com" s.require_paths = ["lib"] s.rubygems_version = "1.8.24" s.summary = "An IRB alternative and runtime developer console" - s.test_files = ["test/candidate_helper1.rb", "test/candidate_helper2.rb", "test/helper.rb", "test/test_cli.rb", "test/test_code.rb", "test/test_command.rb", "test/test_command_helpers.rb", "test/test_command_integration.rb", "test/test_command_set.rb", "test/test_completion.rb", "test/test_control_d_handler.rb", "test/test_default_commands/example.erb", "test/test_default_commands/test_cd.rb", "test/test_default_commands/test_context.rb", "test/test_default_commands/test_documentation.rb", "test/test_default_commands/test_find_method.rb", "test/test_default_commands/test_gems.rb", "test/test_default_commands/test_help.rb", "test/test_default_commands/test_input.rb", "test/test_default_commands/test_introspection.rb", "test/test_default_commands/test_ls.rb", "test/test_default_commands/test_shell.rb", "test/test_default_commands/test_show_source.rb", "test/test_exception_whitelist.rb", "test/test_history_array.rb", "test/test_hooks.rb", "test/test_indent.rb", "test/test_input_stack.rb", "test/test_method.rb", "test/test_pry.rb", "test/test_pry_defaults.rb", "test/test_pry_history.rb", "test/test_pry_output.rb", "test/test_sticky_locals.rb", "test/test_syntax_checking.rb", "test/test_wrapped_module.rb", "test/testrc", "test/testrcbad"] + s.test_files = ["test/candidate_helper1.rb", "test/candidate_helper2.rb", "test/helper.rb", "test/test_cli.rb", "test/test_code.rb", "test/test_command.rb", "test/test_command_helpers.rb", "test/test_command_integration.rb", "test/test_command_set.rb", "test/test_completion.rb", "test/test_control_d_handler.rb", "test/test_default_commands/example.erb", "test/test_default_commands/test_cd.rb", "test/test_default_commands/test_context.rb", "test/test_default_commands/test_documentation.rb", "test/test_default_commands/test_find_method.rb", "test/test_default_commands/test_gems.rb", "test/test_default_commands/test_help.rb", "test/test_default_commands/test_input.rb", "test/test_default_commands/test_introspection.rb", "test/test_default_commands/test_ls.rb", "test/test_default_commands/test_shell.rb", "test/test_default_commands/test_show_source.rb", "test/test_exception_whitelist.rb", "test/test_history_array.rb", "test/test_hooks.rb", "test/test_indent.rb", "test/test_input_stack.rb", "test/test_method.rb", "test/test_prompt.rb", "test/test_pry.rb", "test/test_pry_defaults.rb", "test/test_pry_history.rb", "test/test_pry_output.rb", "test/test_sticky_locals.rb", "test/test_syntax_checking.rb", "test/test_wrapped_module.rb", "test/testrc", "test/testrcbad"] if s.respond_to? :specification_version then s.specification_version = 3 diff --git a/test/test_hooks.rb b/test/test_hooks.rb index 50814ae2..5a25951e 100644 --- a/test/test_hooks.rb +++ b/test/test_hooks.rb @@ -316,6 +316,7 @@ describe Pry::Hooks do redirect_pry_io(StringIO.new("exit"), out=StringIO.new) do Pry.start binding, :hello => :baby end + options[:hello].should == :baby Pry.config.hooks.delete_hook(:when_started, :test_hook) diff --git a/test/test_prompt.rb b/test/test_prompt.rb new file mode 100644 index 00000000..820b3616 --- /dev/null +++ b/test/test_prompt.rb @@ -0,0 +1,60 @@ +require 'helper' + +describe "Prompts" do + describe "one-parameter prompt proc" do + it 'should get full config object' do + config = nil + redirect_pry_io(InputTester.new("exit-all")) do + Pry.start(self, :prompt => proc { |v| config = v }) + end + config.is_a?(OpenStruct).should == true + end + + it 'should get full config object, when using a proc array' do + config1 = nil + redirect_pry_io(InputTester.new("exit-all")) do + Pry.start(self, :prompt => [proc { |v| config1 = v }, proc { |v| config2 = v }]) + end + config1.is_a?(OpenStruct).should == true + end + + it 'should receive correct data in the config object' do + config = nil + redirect_pry_io(InputTester.new("def hello", "exit-all")) do + Pry.start(self, :prompt => proc { |v| config = v }) + end + config.eval_string.should =~ /def hello/ + config.nesting_level.should == 0 + config.expr_number.should == 1 + config.cont.should == true + config._pry_.is_a?(Pry).should == true + config.object.should == self + end + end + + describe "BACKWARDS COMPATIBILITY: 3 parameter prompt proc" do + it 'should get 3 parameters' do + o = n = p = nil + redirect_pry_io(InputTester.new("exit-all")) do + Pry.start(:test, :prompt => proc { |obj, nesting, _pry_| + o, n, p = obj, nesting, _pry_ }) + end + o.should == :test + n.should == 0 + p.is_a?(Pry).should == true + end + + it 'should get 3 parameters, when using proc array' do + o1 = n1 = p1 = nil + redirect_pry_io(InputTester.new("exit-all")) do + Pry.start(:test, :prompt => [proc { |obj, nesting, _pry_| + o1, n1, p1 = obj, nesting, _pry_ }, + proc { |obj, nesting, _pry_| + o2, n2, p2 = obj, nesting, _pry_ }]) + end + o1.should == :test + n1.should == 0 + p1.is_a?(Pry).should == true + end + end +end