diff --git a/lib/pry/command_context.rb b/lib/pry/command_context.rb index d69a21cd..7807a1fc 100644 --- a/lib/pry/command_context.rb +++ b/lib/pry/command_context.rb @@ -11,8 +11,9 @@ class Pry attr_accessor :command_set attr_accessor :command_processor - def run(name, *args) - command_set.run_command(self, name, *args) + def run(command_string, *args) + complete_string = "#{command_string} #{args.join(" ")}" + command_processor.process_commands(complete_string, eval_string, target) end def commands diff --git a/lib/pry/command_set.rb b/lib/pry/command_set.rb index 710384f7..7e7a2c95 100644 --- a/lib/pry/command_set.rb +++ b/lib/pry/command_set.rb @@ -112,8 +112,8 @@ class Pry gems_not_installed = gems_needed.select { |g| !gem_installed?(g) } options[:stub_info] = proc do - output.puts "\n#{name} requires the following gems to be installed: #{(gems_needed.join(", "))}" - output.puts "Command not available due to dependency on gems: `#{gems_not_installed.join(", ")}` not being met." + output.puts "\nThe command '#{name}' is unavailable because it requires the following gems to be installed: #{(gems_not_installed.join(", "))}" + output.puts "-" output.puts "Type `install #{name}` to install the required gems and activate this command." end end @@ -257,6 +257,16 @@ class Pry next if gem_install_failed Gem.refresh + gems_to_install.each do |g| + begin + require g + rescue LoadError + output.puts "Required Gem: `#{g}` installed but not found?!. Aborting command installation." + gem_install_failed = true + end + end + next if gem_install_failed + command.options.delete :stub_info output.puts "Installation of `#{name}` successful! Type `help #{name}` for information" end diff --git a/lib/pry/config.rb b/lib/pry/config.rb index f75629ec..bcd9370d 100644 --- a/lib/pry/config.rb +++ b/lib/pry/config.rb @@ -70,6 +70,17 @@ class Pry # Determines whether plugins should be loaded. # @return [Boolean] attr_accessor :should_load_plugins + + # Config option for history. + # sub-options include hist.file, hist.load, and hist.save + # hist.file is the file to save/load history too, e.g + # Pry.config.history.file = "~/.pry_history". + # hist.load is a boolean that determines whether history will be + # loaded from hist.file at session start. + # hist.save is a boolean that determines whether history will be + # saved to hist.file at session end. + # @return [OpenStruct] + attr_accessor :history end end diff --git a/lib/pry/core_extensions.rb b/lib/pry/core_extensions.rb index 7e1ef63c..1bd294e8 100644 --- a/lib/pry/core_extensions.rb +++ b/lib/pry/core_extensions.rb @@ -30,13 +30,13 @@ class Object begin instance_eval %{ def __binding_impl__ - binding + Kernel.binding end } rescue TypeError self.class.class_eval %{ def __binding_impl__ - binding + Kernel.binding end } end diff --git a/lib/pry/default_commands/basic.rb b/lib/pry/default_commands/basic.rb index eda53a7f..124a75d1 100644 --- a/lib/pry/default_commands/basic.rb +++ b/lib/pry/default_commands/basic.rb @@ -10,9 +10,9 @@ class Pry command "simple-prompt", "Toggle the simple prompt." do case Pry.active_instance.prompt when Pry::SIMPLE_PROMPT - Pry.active_instance.prompt = Pry::DEFAULT_PROMPT + Pry.active_instance.pop_prompt else - Pry.active_instance.prompt = Pry::SIMPLE_PROMPT + Pry.active_instance.push_prompt Pry::SIMPLE_PROMPT end end diff --git a/lib/pry/default_commands/context.rb b/lib/pry/default_commands/context.rb index 3ecf8345..618c60cb 100644 --- a/lib/pry/default_commands/context.rb +++ b/lib/pry/default_commands/context.rb @@ -20,7 +20,7 @@ class Pry TOPLEVEL_BINDING.pry next else - Pry.start target.eval(opts[:arg_string]) + Pry.start target.eval(arg_string) end end @@ -54,16 +54,14 @@ class Pry end command "exit", "End the current Pry session. Accepts optional return value. Aliases: quit, back" do - str = remove_first_word(opts[:val]) - throw(:breakout, [opts[:nesting].level, target.eval(str)]) + throw(:breakout, [opts[:nesting].level, target.eval(arg_string)]) end alias_command "quit", "exit", "" alias_command "back", "exit", "" command "exit-all", "End all nested Pry sessions. Accepts optional return value. Aliases: !!@" do - str = remove_first_word(opts[:val]) - throw(:breakout, [0, target.eval(str)]) + throw(:breakout, [0, target.eval(arg_string)]) end alias_command "!!@", "exit-all", "" @@ -76,7 +74,7 @@ class Pry alias_command "!!!", "exit-program", "" command "!pry", "Start a Pry session on current self; this even works mid-expression." do - Pry.start(target) + target.pry end command "whereami", "Show the code context for the session. (whereami shows extra lines of code around the invocation line. Default: 5)" do |num| diff --git a/lib/pry/default_commands/input.rb b/lib/pry/default_commands/input.rb index 89ad3042..b4896cdf 100644 --- a/lib/pry/default_commands/input.rb +++ b/lib/pry/default_commands/input.rb @@ -62,6 +62,14 @@ class Pry end end + opt.on :s, :show, 'Show the history corresponding to the history line (or range of lines).', true, :as => Range do |range| + unless opt.grep? + start_line = range.is_a?(Range) ? range.first : range + lines = text.with_line_numbers Array(history[range]).join("\n"), start_line + stagger_output lines + end + end + opt.on :e, :exclude, 'Exclude pry commands from the history.' do unless opt.grep? history.map!.with_index do |element, index| diff --git a/lib/pry/extended_commands/experimental.rb b/lib/pry/extended_commands/experimental.rb index 215a48d3..aabe0bc2 100644 --- a/lib/pry/extended_commands/experimental.rb +++ b/lib/pry/extended_commands/experimental.rb @@ -4,14 +4,14 @@ class Pry Experimental = Pry::CommandSet.new do - command /rue-(\d)/, "Experimental amend-line, where the N in rue-N represents line to replace", :interpolate => false do |replacement_line| - replacement_line = "" if !replacement_line - input_array = opts[:eval_string].each_line.to_a - line_number = opts[:captures].first.to_i - input_array[line_number] = opts[:arg_string] + "\n" - opts[:eval_string].replace input_array.join - end + command "reload-method", "Reload the source specifically for a method", :requires_gem => "method_reload" do |meth_name| + if (meth = get_method_object(meth_name, target, {})).nil? + output.puts "Invalid method name: #{meth_name}." + next + end + meth.reload + end command "play-string", "Play a string as input" do Pry.active_instance.input = StringIO.new(opts[:arg_string]) diff --git a/lib/pry/helpers/base_helpers.rb b/lib/pry/helpers/base_helpers.rb index bcb818f2..67e87da8 100644 --- a/lib/pry/helpers/base_helpers.rb +++ b/lib/pry/helpers/base_helpers.rb @@ -14,10 +14,6 @@ class Pry end end - def remove_first_word(text) - text.split.drop(1).join(' ') - end - def find_command(name) command_match = commands.find { |_, command| command.options[:listing] == name } @@ -49,8 +45,10 @@ class Pry gems_needed = Array(options[:requires_gem]) gems_not_installed = gems_needed.select { |g| !gem_installed?(g) } proc do - output.puts "\n#{name} requires the following gems to be installed: #{(gems_needed.join(", "))}" + output.puts "\nThe command '#{name}' requires the following gems to be installed: #{(gems_needed.join(", "))}" + output.puts "-" output.puts "Command not available due to dependency on gems: `#{gems_not_installed.join(", ")}` not being met." + output.puts "-" output.puts "Type `install #{name}` to install the required gems and activate this command." end end diff --git a/lib/pry/helpers/command_helpers.rb b/lib/pry/helpers/command_helpers.rb index 9298c6d6..d42dc3fa 100644 --- a/lib/pry/helpers/command_helpers.rb +++ b/lib/pry/helpers/command_helpers.rb @@ -48,11 +48,6 @@ class Pry end end - def remove_first_word(text) - text.split.drop(1).join(' ') - end - - def code_and_code_type_for(meth) case code_type = code_type_for(meth) when nil diff --git a/lib/pry/pry_class.rb b/lib/pry/pry_class.rb index 73ac38c3..a836e005 100644 --- a/lib/pry/pry_class.rb +++ b/lib/pry/pry_class.rb @@ -96,8 +96,8 @@ class Pry # we only want them loaded once per entire Pry lifetime, not # multiple times per each new session (i.e in debugging) load_rc if Pry.config.should_load_rc - load_history if Pry.config.history.load load_plugins if Pry.config.should_load_plugins + load_history if Pry.config.history.load @initial_session = false end diff --git a/lib/pry/pry_instance.rb b/lib/pry/pry_instance.rb index 6177d1a0..e724c497 100644 --- a/lib/pry/pry_instance.rb +++ b/lib/pry/pry_instance.rb @@ -1,6 +1,5 @@ require "pry/command_processor.rb" -# @attr prompt class Pry attr_accessor :input @@ -81,7 +80,7 @@ class Pry self.class.nesting = v end - # @return [Boolean] Whether current session is the top-level session. + # @return [Boolean] Whether top-level session has ended. def finished_top_level_session? nesting.empty? end @@ -243,7 +242,7 @@ class Pry eval_string end - # FIXME should delete this method? it's exposing an implementation detail! + # 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 @@ -364,7 +363,8 @@ class Pry # Save readline history to a file. def save_history - File.open Pry.config.history.file, 'w' do |f| + history_file = File.expand_path(Pry.config.history.file) + File.open(history_file, 'w') do |f| f.write Readline::HISTORY.to_a.join("\n") end end diff --git a/test/test_default_commands.rb b/test/test_default_commands.rb index 5a32265a..7530b6f9 100644 --- a/test/test_default_commands.rb +++ b/test/test_default_commands.rb @@ -98,6 +98,23 @@ describe "Pry::Commands" do str_output.string.each_line.count.should == 4 str_output.string.should =~ /a\n\d+:.*b\n\d+:.*c/ end + + # strangeness in this test is due to bug in Readline::HISTORY not + # always registering first line of input + it 'should show lines between lines A and B with the --show switch' do + push_first_hist_line.call(@hist, "0") + ("a".."z").each do |v| + @hist.push v + end + + str_output = StringIO.new + redirect_pry_io(InputTester.new("hist --show 1..4", "exit-all"), str_output) do + pry + end + + str_output.string.each_line.count.should == 4 + str_output.string.should =~ /b\n\d+:.*c\n\d+:.*d/ + end end describe "show-method" do diff --git a/test/test_pry.rb b/test/test_pry.rb index db689332..ecffa5a3 100644 --- a/test/test_pry.rb +++ b/test/test_pry.rb @@ -297,6 +297,11 @@ describe Pry do Pry.binding_for(_main_.call).should == TOPLEVEL_BINDING Pry.binding_for(_main_.call).should == Pry.binding_for(_main_.call) end + + it 'should return a binding with the right self for procs' do + proc = Proc.new {} + Pry.binding_for(proc).eval("self").should.equal? proc + end end