From 019245bf105f22035204e15bd2613a2660f16613 Mon Sep 17 00:00:00 2001 From: John Mair Date: Tue, 13 Sep 2011 05:07:05 +1200 Subject: [PATCH] extended cat --ex and edit --ex to allow access to all levels of backtrace cat --ex N now shows a window of code around the Nth level of the backtrace (window size determined by Pry.config.exception_window_size, defaults to 5) edit --ex N opens an editor at the line of code at the Nth level of the backtrace --- lib/pry/default_commands/introspection.rb | 13 ++++++++----- lib/pry/default_commands/shell.rb | 22 +++++++++++++--------- lib/pry/pry_class.rb | 1 + lib/pry/pry_instance.rb | 7 +++++-- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/lib/pry/default_commands/introspection.rb b/lib/pry/default_commands/introspection.rb index 39773e7f..80876479 100644 --- a/lib/pry/default_commands/introspection.rb +++ b/lib/pry/default_commands/introspection.rb @@ -121,7 +121,7 @@ class Pry e.g: edit sample.rb USAGE - opt.on :e, :ex, "Open the file that raised the most recent exception (_ex_.file)" + opt.on :e, :ex, "Open the file that raised the most recent exception (_ex_.file)", :optional => true, :as => Integer opt.on :t, :temp, "Open an empty temporary file" opt.on :l, :line, "Jump to this line in the opened file", true, :as => Integer opt.on :n, :"no-reload", "Don't automatically reload the edited code" @@ -162,14 +162,17 @@ class Pry else if opts.ex? next output.puts "No Exception found." if _pry_.last_exception.nil? + ex = _pry_.last_exception + bt_index = opts[:ex].to_i - if is_core_rbx_path?(_pry_.last_exception.file) - file_name = rbx_convert_path_to_full(_pry_.last_exception.file) + ex_file, ex_line = ex.bt_source_location_for(bt_index) + if is_core_rbx_path?(ex_file) + file_name = rbx_convert_path_to_full(ex_file) else - file_name = _pry_.last_exception.file + file_name = ex_file end - line = _pry_.last_exception.line + line = ex_line next output.puts "Exception has no associated file." if file_name.nil? next output.puts "Cannot edit exceptions raised in REPL." if Pry.eval_path == file_name diff --git a/lib/pry/default_commands/shell.rb b/lib/pry/default_commands/shell.rb index 1be6dd88..15a53832 100644 --- a/lib/pry/default_commands/shell.rb +++ b/lib/pry/default_commands/shell.rb @@ -38,6 +38,7 @@ class Pry start_line = 0 end_line = -1 file_name = nil + bt_index = 0 opts = Slop.parse!(args) do |opt| opt.on :s, :start, "Start line (defaults to start of file)Line 1 is the first line.", true, :as => Integer do |line| @@ -48,17 +49,19 @@ class Pry end_line = line - 1 end - opt.on :ex, "Show a window of N lines either side of the last exception (defaults to 5).", :optional => true, :as => Integer do |window_size| - window_size ||= 5 + opt.on :ex, "Show a window of N lines either side of the last exception (defaults to 5).", :optional => true, :as => Integer do |bt_index_str| + window_size = Pry.config.exception_window_size || 5 + bt_index = bt_index_str.to_i ex = _pry_.last_exception next if !ex - start_line = (ex.line - 1) - window_size + ex_file, ex_line = ex.bt_source_location_for(bt_index) + start_line = (ex_line - 1) - window_size start_line = start_line < 0 ? 0 : start_line - end_line = (ex.line - 1) + window_size - if is_core_rbx_path?(ex.file) - file_name = rbx_convert_path_to_full(ex.file) + end_line = (ex_line - 1) + window_size + if is_core_rbx_path?(ex_file) + file_name = rbx_convert_path_to_full(ex_file) else - file_name = ex.file + file_name = ex_file end end @@ -92,11 +95,12 @@ class Pry # add the arrow pointing to line that caused the exception if opts.ex? + ex_file, ex_line = _pry_.last_exception.bt_source_location_for(bt_index) contents = text.with_line_numbers contents, start_line + 1, :bright_red contents = contents.lines.each_with_index.map do |line, idx| l = idx + start_line - if l == (_pry_.last_exception.line - 1) + if l == (ex_line - 1) " =>#{line}" else " #{line}" @@ -105,7 +109,7 @@ class Pry # header for exceptions output.puts "\n#{Pry::Helpers::Text.bold('Exception:')} #{_pry_.last_exception.class}: #{_pry_.last_exception.message}\n--" - output.puts "#{Pry::Helpers::Text.bold('From:')} #{file_name} @ line #{_pry_.last_exception.line}\n\n" + output.puts "#{Pry::Helpers::Text.bold('From:')} #{ex_file} @ line #{ex_line} @ #{text.bold('level: ')} #{bt_index} of backtrace.\n\n" end set_file_and_dir_locals(file_name) diff --git a/lib/pry/pry_class.rb b/lib/pry/pry_class.rb index 95453dd1..3855e051 100644 --- a/lib/pry/pry_class.rb +++ b/lib/pry/pry_class.rb @@ -182,6 +182,7 @@ class Pry config.prompt = DEFAULT_PROMPT config.print = DEFAULT_PRINT config.exception_handler = DEFAULT_EXCEPTION_HANDLER + config.exception_window_size = 5 config.hooks = DEFAULT_HOOKS config.color = true config.pager = true diff --git a/lib/pry/pry_instance.rb b/lib/pry/pry_instance.rb index ddd57684..93daf18c 100644 --- a/lib/pry/pry_instance.rb +++ b/lib/pry/pry_instance.rb @@ -347,10 +347,13 @@ class Pry def set_last_exception(ex, target) class << ex attr_accessor :file, :line + def bt_source_location_for(index) + backtrace[index] =~ /(.*):(\d+)/ + [$1, $2.to_i] + end end - ex.backtrace.first =~ /(.*):(\d+)/ - ex.file, ex.line = $1, $2.to_i + ex.file, ex.line = ex.bt_source_location_for(0)#_btw_index#$1, $2.to_i @last_result_is_exception = true @output_array << ex