From 37b9fce97655a0dce789984ad9d1d0a4d9bf7f55 Mon Sep 17 00:00:00 2001 From: John Mair Date: Sat, 22 Dec 2012 22:54:17 +0100 Subject: [PATCH] show-source / show-doc: ensure _file_ and _line_ are set Also cleaned up some OCD edge cases for show-doc, totally unnecessary & kind of silly --- lib/pry/commands/show_doc.rb | 64 +++++++++++++++++++++++-------- lib/pry/commands/show_source.rb | 4 +- spec/commands/show_doc_spec.rb | 9 +++++ spec/commands/show_source_spec.rb | 10 ++++- 4 files changed, 69 insertions(+), 18 deletions(-) diff --git a/lib/pry/commands/show_doc.rb b/lib/pry/commands/show_doc.rb index 1c362504..cf3aec84 100644 --- a/lib/pry/commands/show_doc.rb +++ b/lib/pry/commands/show_doc.rb @@ -32,7 +32,7 @@ class Pry def process - code_object = Pry::CodeObject.lookup(obj_name, target, _pry_, :super => opts[:super]) + code_object = Pry::CodeObject.lookup obj_name, target, _pry_, :super => opts[:super] if !code_object raise Pry::CommandError, "Couldn't locate #{obj_name}!" @@ -40,32 +40,52 @@ class Pry if code_object.is_a?(Pry::WrappedModule) && opts.present?(:all) # show all monkey patches for a module + # docs_for_all_modules_candidates writes its own headers result = docs_for_all_module_candidates(code_object) else # show the source for a specific code object result = header(code_object) - result << Code.new(render_doc_markup_for(code_object), start_line_for(code_object), :text). + result << Code.new(render_doc_markup_for(code_object), + opts.present?(:b) ? 1 : start_line_for(code_object), + :text). with_line_numbers(use_line_numbers?).to_s + set_file_and_dir_locals(code_object.source_file) end stagger_output result end + # simple utility function to piece together the name of the object + # passed in from the arg list + def obj_name + @obj_name ||= args.empty? ? nil : args.join(" ") + end + + # process the markup (if necessary) and apply colors def render_doc_markup_for(code_object) - if code_object.is_a?(Module) && code_object <= Pry::Command + docs = docs_for(code_object) + + if code_object_is_command?(code_object) # command 'help' doesn't want markup highlighting - code_object.doc - elsif code_object.is_a?(WrappedModule) && code_object.yard_docs? - # yard docs - process_comment_markup(code_object.yard_doc) + docs else - # normal docs (i.e comments above method/module) - process_comment_markup(code_object.doc) + process_comment_markup(docs) end end - def obj_name - @obj_name ||= args.empty? ? nil : args.join(" ") + # Return docs for the code_object, adjusting for whether the code_object + # has yard docs available, in which case it returns those. + # (note we only have to check yard docs for modules since they can + # have multiple docs, but methods can only be doc'd once so we + # dont need to check them) + def docs_for(code_object) + if code_object.is_a?(WrappedModule) && code_object.yard_docs? + # yard docs + code_object.yard_doc + else + # normal docs (i.e comments above method/module/command) + code_object.doc + end end # we need this helper as some Pry::Method objects can wrap Procs @@ -75,11 +95,13 @@ class Pry end # takes into account possible yard docs, and returns yard_file / yard_line + # Also adjusts for start line of comments (using start_line_for), which it has to infer + # by subtracting number of lines of comment from start line of code_object def file_and_line_for(code_object) if code_object.is_a?(WrappedModule) && code_object.yard_docs? [code_object.yard_file, code_object.yard_line] else - [code_object.source_file, code_object.source_line] + [code_object.source_file, start_line_for(code_object)] end end @@ -99,7 +121,8 @@ class Pry h << "#{text.bold("Visibility:")} #{code_object.visibility}\n" h << "#{text.bold("Signature:")} #{code_object.signature}" end - h << "\n#{Pry::Helpers::Text.bold('Number of lines:')} #{code_object.source.lines.count}\n\n" + h << "\n#{Pry::Helpers::Text.bold('Number of lines:')} " << + "#{docs_for(code_object).lines.count}\n\n" end def docs_for_all_module_candidates(mod) @@ -107,8 +130,10 @@ class Pry mod.number_of_candidates.times do |v| candidate = mod.candidate(v) begin - result << "\nCandidate #{v+1}/#{mod.number_of_candidates}: #{candidate.file} @ line #{candidate.line}:\n" - doc = candidate.doc + result << "\nCandidate #{v+1}/#{mod.number_of_candidates}: #{candidate.source_file} @ line #{candidate.source_line}:\n" + doc = Code.new(render_doc_markup_for(candidate), + opts.present?(:b) ? 1 : candidate.source_line, + :text).with_line_numbers(use_line_numbers?).to_s result << "Number of lines: #{doc.lines.count}\n\n" << doc rescue Pry::RescuableException result << "\nNo code found.\n" @@ -118,8 +143,15 @@ class Pry result end + def code_object_is_command?(code_object) + code_object.is_a?(Module) && code_object <= Pry::Command + end + + # figure out start line of docs by back calculating based on + # number of lines in the comment and the start line of the code_object + # @return [Fixnum] start line of docs def start_line_for(code_object) - if opts.present?(:'base-one') + if code_object_is_command?(code_object) 1 else code_object.source_line.nil? ? 1 : diff --git a/lib/pry/commands/show_source.rb b/lib/pry/commands/show_source.rb index f0eae690..44bb1c10 100644 --- a/lib/pry/commands/show_source.rb +++ b/lib/pry/commands/show_source.rb @@ -37,7 +37,7 @@ class Pry end def process - code_object = Pry::CodeObject.lookup(obj_name, target, _pry_, :super => opts[:super]) + code_object = Pry::CodeObject.lookup obj_name, target, _pry_, :super => opts[:super] if !code_object raise Pry::CommandError, "Couldn't locate #{obj_name}!" @@ -51,6 +51,8 @@ class Pry result = header(code_object) result << Code.new(code_object.source, start_line_for(code_object)). with_line_numbers(use_line_numbers?).to_s + + set_file_and_dir_locals(code_object.source_file) end stagger_output result diff --git a/spec/commands/show_doc_spec.rb b/spec/commands/show_doc_spec.rb index 9e4289ac..4abd0fcb 100644 --- a/spec/commands/show_doc_spec.rb +++ b/spec/commands/show_doc_spec.rb @@ -336,5 +336,14 @@ if !PryTestHelpers.mri18_and_no_real_source_location? pry_eval('show-doc command with spaces').should =~ /description of a command with spaces/ end end + + describe "should set _file_ and _dir_" do + it 'should set _file_ and _dir_ to file containing method source' do + t = pry_tester + t.process_command "show-doc TestClassForShowSource#alpha" + t.pry.last_file.should =~ /show_source_doc_examples/ + t.pry.last_dir.should =~ /fixtures/ + end + end end end diff --git a/spec/commands/show_source_spec.rb b/spec/commands/show_source_spec.rb index 91f2da3c..d8d5f281 100644 --- a/spec/commands/show_source_spec.rb +++ b/spec/commands/show_source_spec.rb @@ -4,7 +4,6 @@ require "fixtures/show_source_doc_examples" if !PryTestHelpers.mri18_and_no_real_source_location? describe "show-source" do before do - @str_output = StringIO.new @o = Object.new def @o.sample_method :sample @@ -585,5 +584,14 @@ if !PryTestHelpers.mri18_and_no_real_source_location? pry_eval('show-source bar').should =~ /:body_of_foo_bar_regex/ end end + + describe "should set _file_ and _dir_" do + it 'should set _file_ and _dir_ to file containing method source' do + t = pry_tester + t.process_command "show-source TestClassForShowSource#alpha" + t.pry.last_file.should =~ /show_source_doc_examples/ + t.pry.last_dir.should =~ /fixtures/ + end + end end end