This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Pry
|
||||
class Command
|
||||
class Cat
|
||||
class AbstractFormatter
|
||||
include Pry::Helpers::CommandHelpers
|
||||
include Pry::Helpers::BaseHelpers
|
||||
|
||||
private
|
||||
|
||||
def decorate(content)
|
||||
content.code_type = code_type
|
||||
content.between(*between_lines)
|
||||
.with_line_numbers(use_line_numbers?).highlighted
|
||||
end
|
||||
|
||||
def code_type
|
||||
opts[:type] || :ruby
|
||||
end
|
||||
|
||||
def use_line_numbers?
|
||||
opts.present?(:'line-numbers') || opts.present?(:ex)
|
||||
end
|
||||
|
||||
def between_lines
|
||||
[opts[:start] || 1, opts[:end] || -1]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,90 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Pry
|
||||
class Command
|
||||
class Cat
|
||||
class ExceptionFormatter < AbstractFormatter
|
||||
attr_reader :ex
|
||||
attr_reader :opts
|
||||
attr_reader :pry_instance
|
||||
include Pry::Helpers::Text
|
||||
|
||||
def initialize(exception, pry_instance, opts)
|
||||
@ex = exception
|
||||
@opts = opts
|
||||
@pry_instance = pry_instance
|
||||
end
|
||||
|
||||
def format
|
||||
check_for_errors
|
||||
set_file_and_dir_locals(
|
||||
backtrace_file, pry_instance, pry_instance.current_context
|
||||
)
|
||||
code = decorate(
|
||||
Pry::Code.from_file(backtrace_file)
|
||||
.between(*start_and_end_line_for_code_window)
|
||||
.with_marker(backtrace_line)
|
||||
)
|
||||
"#{header}#{code}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def code_window_size
|
||||
pry_instance.config.default_window_size || 5
|
||||
end
|
||||
|
||||
def backtrace_level
|
||||
@backtrace_level ||=
|
||||
begin
|
||||
bl =
|
||||
if opts[:ex].nil?
|
||||
ex.bt_index
|
||||
else
|
||||
ex.bt_index = absolute_index_number(opts[:ex], ex.backtrace.size)
|
||||
end
|
||||
|
||||
increment_backtrace_level
|
||||
bl
|
||||
end
|
||||
end
|
||||
|
||||
def increment_backtrace_level
|
||||
ex.inc_bt_index
|
||||
end
|
||||
|
||||
def backtrace_file
|
||||
Array(ex.bt_source_location_for(backtrace_level)).first
|
||||
end
|
||||
|
||||
def backtrace_line
|
||||
Array(ex.bt_source_location_for(backtrace_level)).last
|
||||
end
|
||||
|
||||
def check_for_errors
|
||||
raise CommandError, "No exception found." unless ex
|
||||
return if backtrace_file
|
||||
|
||||
raise CommandError, "The given backtrace level is out of bounds."
|
||||
end
|
||||
|
||||
def start_and_end_line_for_code_window
|
||||
start_line = backtrace_line - code_window_size
|
||||
start_line = 1 if start_line < 1
|
||||
|
||||
[start_line, backtrace_line + code_window_size]
|
||||
end
|
||||
|
||||
def header
|
||||
unindent(
|
||||
"#{bold 'Exception:'} #{ex.class}: #{ex.message}\n" \
|
||||
"--\n" \
|
||||
"#{bold('From:')} #{backtrace_file}:#{backtrace_line} @ " \
|
||||
"#{bold("level: #{backtrace_level}")} of backtrace " \
|
||||
"(of #{ex.backtrace.size - 1}).\n\n"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,77 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Pry
|
||||
class Command
|
||||
class Cat
|
||||
class FileFormatter < AbstractFormatter
|
||||
attr_reader :file_with_embedded_line
|
||||
attr_reader :opts
|
||||
attr_reader :pry_instance
|
||||
|
||||
def initialize(file_with_embedded_line, pry_instance, opts)
|
||||
unless file_with_embedded_line
|
||||
raise CommandError, "Must provide a filename, --in, or --ex."
|
||||
end
|
||||
|
||||
@file_with_embedded_line = file_with_embedded_line
|
||||
@opts = opts
|
||||
@pry_instance = pry_instance
|
||||
@code_from_file = Pry::Code.from_file(file_name)
|
||||
end
|
||||
|
||||
def format
|
||||
set_file_and_dir_locals(file_name, pry_instance, pry_instance.current_context)
|
||||
decorate(@code_from_file)
|
||||
end
|
||||
|
||||
def file_and_line
|
||||
file_name, line_num = file_with_embedded_line.split(%r{:(?!/|\\)})
|
||||
|
||||
[file_name, line_num ? line_num.to_i : nil]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def file_name
|
||||
file_and_line.first
|
||||
end
|
||||
|
||||
def line_number
|
||||
file_and_line.last
|
||||
end
|
||||
|
||||
def code_window_size
|
||||
pry_instance.config.default_window_size || 7
|
||||
end
|
||||
|
||||
def decorate(content)
|
||||
if line_number
|
||||
super(content.around(line_number, code_window_size))
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def code_type
|
||||
opts[:type] || detect_code_type_from_file(file_name)
|
||||
end
|
||||
|
||||
def detect_code_type_from_file(file_name)
|
||||
code_type = @code_from_file.code_type
|
||||
|
||||
if code_type == :unknown
|
||||
name = File.basename(file_name).split('.', 2).first
|
||||
case name
|
||||
when "Rakefile", "Gemfile"
|
||||
:ruby
|
||||
else
|
||||
:text
|
||||
end
|
||||
else
|
||||
code_type
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,48 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Pry
|
||||
class Command
|
||||
class Cat
|
||||
class InputExpressionFormatter < AbstractFormatter
|
||||
attr_accessor :input_expressions
|
||||
attr_accessor :opts
|
||||
|
||||
def initialize(input_expressions, opts)
|
||||
@input_expressions = input_expressions
|
||||
@opts = opts
|
||||
end
|
||||
|
||||
def format
|
||||
raise CommandError, "No input expressions!" if numbered_input_items.empty?
|
||||
|
||||
if numbered_input_items.length > 1
|
||||
content = ''
|
||||
numbered_input_items.each do |i, s|
|
||||
content += "#{Helpers::Text.bold(i.to_s)}:\n"
|
||||
content += decorate(Pry::Code(s).with_indentation(2)).to_s
|
||||
end
|
||||
|
||||
content
|
||||
else
|
||||
decorate(Pry::Code(selected_input_items.first))
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def selected_input_items
|
||||
input_expressions[normalized_expression_range] || []
|
||||
end
|
||||
|
||||
def numbered_input_items
|
||||
@numbered_input_items ||= normalized_expression_range.zip(selected_input_items)
|
||||
.reject { |_, s| s.nil? || s == "" }
|
||||
end
|
||||
|
||||
def normalized_expression_range
|
||||
absolute_index_range(opts[:i], input_expressions.count)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user