diff --git a/lib/pry/commands/edit.rb b/lib/pry/commands/edit.rb index 03602a70..3a8ff1d4 100644 --- a/lib/pry/commands/edit.rb +++ b/lib/pry/commands/edit.rb @@ -8,6 +8,7 @@ class Pry # everything (admittedly, doing extra job). class Command::Edit < Pry::ClassCommand require 'pry/commands/edit/method_patcher' + require 'pry/commands/edit/exception_patcher' match 'edit' group 'Editing' @@ -67,21 +68,21 @@ class Pry end def process_local_edit - content = initial_temp_file_content - + content = Pry::Editor.edit_tempfile_with_content(initial_temp_file_content, + initial_temp_file_content.lines.count) if local_reload? silence_warnings do - eval_string.replace Pry::Editor.edit_tempfile_with_content(content, content.lines.count) + eval_string.replace content end end end def apply_runtime_patch if patch_exception? - apply_runtime_patch_to_exception + ExceptionPatcher.new(self).perform_patch else if code_object.is_a?(Pry::Method) - MethodPatcher.new(code_object, target, _pry_).perform_patch + MethodPatcher.new(self).perform_patch else raise NotImplementedError, "Cannot yet patch #{code_object} objects!" end @@ -90,6 +91,7 @@ class Pry def process_remote_edit file_name, line = retrieve_file_and_line + raise CommandError, "#{file_name} is not a valid file name, cannot edit!" if not_a_real_file?(file_name) # Sanitize blanks. sanitized_file_name = Shellwords.escape(file_name) @@ -122,7 +124,11 @@ class Pry code_object.dynamically_defined? end - def retrieve_input_expression + def patch_exception? + opts.present?(:ex) && opts.present?(:patch) + end + + def input_expression case opts[:i] when Range (_pry_.input_array[opts[:i]] || []).join @@ -155,11 +161,11 @@ class Pry when opts.present?(:temp) "" when opts.present?(:in) - retrieve_input_expression + input_expression when eval_string.strip != "" eval_string else - _pry_.input_array.reverse_each.find{ |x| x && x.strip != "" } || "" + _pry_.input_array.reverse_each.find { |x| x && x.strip != "" } || "" end end @@ -168,6 +174,18 @@ class Pry str =~ /\/|\\/ end + def retrieve_file_and_line + file_name, line = if opts.present?(:ex) + file_and_line_for_exception + elsif opts.present?(:current) + current_file_and_line + else + object_file_and_line + end + + [file_name, opts.present?(:line) ? opts[:l].to_i : line] + end + def file_and_line_for_exception raise CommandError, "No exception found." if _pry_.last_exception.nil? @@ -194,35 +212,6 @@ class Pry [file_name, line] end end - - def retrieve_file_and_line - file_name, line = if opts.present?(:ex) - file_and_line_for_exception - elsif opts.present?(:current) - current_file_and_line - else - object_file_and_line - end - - if not_a_real_file?(file_name) - raise CommandError, "#{file_name} is not a valid file name, cannot edit!" - end - - [file_name, opts.present?(:line) ? opts[:l].to_i : line] - end - - def patch_exception? - opts.present?(:ex) && opts.present?(:patch) - end - - def apply_runtime_patch_to_exception - file_name, line = file_and_line_for_exception - lines = state.dynamical_ex_file || File.read(file_name) - - source = Pry::Editor.edit_tempfile_with_content(lines) - _pry_.evaluate_ruby source - state.dynamical_ex_file = source.split("\n") - end end Pry::Commands.add_command(Pry::Command::Edit) diff --git a/lib/pry/commands/edit/exception_patcher.rb b/lib/pry/commands/edit/exception_patcher.rb new file mode 100644 index 00000000..b7ee1fb1 --- /dev/null +++ b/lib/pry/commands/edit/exception_patcher.rb @@ -0,0 +1,21 @@ +class Pry + class Command::Edit + class ExceptionPatcher + attr_accessor :edit_context + + def initialize(edit_context) + @edit_context = edit_context + end + + # perform the patch + def perform_patch + file_name, line = edit_context.retrieve_file_and_line + lines = edit_context.state.dynamical_ex_file || File.read(file_name) + + source = Pry::Editor.edit_tempfile_with_content(lines) + edit_context._pry_.evaluate_ruby source + edit_context.state.dynamical_ex_file = source.split("\n") + end + end + end +end diff --git a/lib/pry/commands/edit/method_patcher.rb b/lib/pry/commands/edit/method_patcher.rb index 55d81021..9359efad 100644 --- a/lib/pry/commands/edit/method_patcher.rb +++ b/lib/pry/commands/edit/method_patcher.rb @@ -5,17 +5,15 @@ class Pry attr_accessor :target attr_accessor :_pry_ - def initialize(method_object, target, _pry_) - @method_object = method_object - @target = target - @_pry_ = _pry_ + def initialize(edit_context) + @method_object = edit_context.code_object + @target = edit_context.target + @_pry_ = edit_context._pry_ end # perform the patch def perform_patch - lines = method_object.source.lines.to_a - lines[0] = definition_line_for_owner(lines[0]) - source = wrap_for_nesting(wrap_for_owner(Pry::Editor.edit_tempfile_with_content(lines))) + source = wrap_for_nesting(wrap_for_owner(Pry::Editor.edit_tempfile_with_content(adjusted_lines))) if method_object.alias? with_method_transaction do @@ -29,6 +27,14 @@ class Pry private + # The method code adjusted so that the first line is rewritten + # so that def self.foo --> def foo + def adjusted_lines + lines = method_object.source.lines.to_a + lines[0] = definition_line_for_owner(lines.first) + lines + end + # Run some code ensuring that at the end target#meth_name will not have changed. # # When we're redefining aliased methods we will overwrite the method at the