diff --git a/lib/pry/helpers/command_helpers.rb b/lib/pry/helpers/command_helpers.rb index ad683afb..696aa318 100644 --- a/lib/pry/helpers/command_helpers.rb +++ b/lib/pry/helpers/command_helpers.rb @@ -84,7 +84,9 @@ class Pry text = text.sub(/^[ \t]+$/, '') # Find the longest common whitespace to all indented lines - margin = text.scan(/^[ \t]*(?=[^ \t\n])/).inject do |current_margin, next_indent| + # Ignore lines containing just -- or ++ as these seem to be used by + # comment authors as delimeters. + margin = text.scan(/^[ \t]*(?!--\n|\+\+\n)(?=[^ \t\n])/).inject do |current_margin, next_indent| if next_indent.start_with?(current_margin) current_margin elsif current_margin.start_with?(next_indent) diff --git a/lib/pry/helpers/documentation_helpers.rb b/lib/pry/helpers/documentation_helpers.rb index 536c7718..95fd6193 100644 --- a/lib/pry/helpers/documentation_helpers.rb +++ b/lib/pry/helpers/documentation_helpers.rb @@ -4,14 +4,18 @@ class Pry # This class contains methods useful for extracting # documentation from methods and classes. module DocumentationHelpers + + module_function + def process_rdoc(comment) + return comment unless Pry.color comment = comment.dup - comment.gsub(/(?:\s*\n)?(.*?)\s*<\/code>/m) { Pry.color ? CodeRay.scan($1, :ruby).term : $1 }. - gsub(/(?:\s*\n)?(.*?)\s*<\/em>/m) { Pry.color ? "\e[1m#{$1}\e[0m": $1 }. - gsub(/(?:\s*\n)?(.*?)\s*<\/i>/m) { Pry.color ? "\e[1m#{$1}\e[0m" : $1 }. - gsub(/\B\+(\w*?)\+\B/) { Pry.color ? "\e[32m#{$1}\e[0m": $1 }. - gsub(/((?:^[ \t]+.+(?:\n+|\Z))+)/) { Pry.color ? CodeRay.scan($1, :ruby).term : $1 }. - gsub(/`(?:\s*\n)?([^\e]*?)\s*`/) { "`#{Pry.color ? CodeRay.scan($1, :ruby).term : $1}`" } + comment.gsub(/(?:\s*\n)?(.*?)\s*<\/code>/m) { CodeRay.scan($1, :ruby).term }. + gsub(/(?:\s*\n)?(.*?)\s*<\/em>/m) { "\e[1m#{$1}\e[0m" }. + gsub(/(?:\s*\n)?(.*?)\s*<\/i>/m) { "\e[1m#{$1}\e[0m" }. + gsub(/\B\+(\w+?)\+\B/) { "\e[32m#{$1}\e[0m" }. + gsub(/((?:^[ \t]+.+(?:\n+|\Z))+)/) { CodeRay.scan($1, :ruby).term }. + gsub(/`(?:\s*\n)?([^\e]*?)\s*`/) { "`#{CodeRay.scan($1, :ruby).term}`" } end def process_yardoc_tag(comment, tag) @@ -46,10 +50,17 @@ class Pry code.sub(/\A\s*\/\*.*?\*\/\s*/m, '') end + # Given a string that makes up a comment in a source-code file parse out the content + # that the user is intended to read. (i.e. without leading indentation, #-characters + # or shebangs) + # # @param [String] comment # @return [String] - def strip_leading_hash_and_whitespace_from_ruby_comments(comment) + def get_comment_content(comment) comment = comment.dup + # Remove #!/usr/bin/ruby + comment.gsub!(/\A\#!.*$/, '') + # Remove leading empty comment lines comment.gsub!(/\A\#+?$/, '') comment.gsub!(/^\s*#/, '') strip_leading_whitespace(comment) diff --git a/lib/pry/method.rb b/lib/pry/method.rb index 57b923c6..519218b5 100644 --- a/lib/pry/method.rb +++ b/lib/pry/method.rb @@ -311,11 +311,11 @@ class Pry info.docstring if info when :ruby if rbx? && !pry_method? - strip_leading_hash_and_whitespace_from_ruby_comments(core_doc) + get_comment_content(core_doc) elsif pry_method? - strip_leading_hash_and_whitespace_from_ruby_comments(doc_for_pry_method) + get_comment_content(doc_for_pry_method) else - strip_leading_hash_and_whitespace_from_ruby_comments(@method.comment) + get_comment_content(@method.comment) end end end diff --git a/lib/pry/module_candidate.rb b/lib/pry/module_candidate.rb index 9e9f7e69..bcbde96c 100644 --- a/lib/pry/module_candidate.rb +++ b/lib/pry/module_candidate.rb @@ -64,7 +64,7 @@ class Pry return nil if file.nil? return @doc if @doc - @doc = strip_leading_hash_and_whitespace_from_ruby_comments(Pry::Code.from_file(file).comment_describing(line)) + @doc = get_comment_content(Pry::Code.from_file(file).comment_describing(line)) end # @return [Array, nil] A `[String, Fixnum]` pair representing the diff --git a/spec/command_helpers_spec.rb b/spec/command_helpers_spec.rb index 883f863c..2a36b57e 100644 --- a/spec/command_helpers_spec.rb +++ b/spec/command_helpers_spec.rb @@ -5,5 +5,25 @@ describe Pry::Helpers::CommandHelpers do @helper = Pry::Helpers::CommandHelpers end - # FIXME: currently no tests + describe "unindent" do + it "should remove the same prefix from all lines" do + @helper.unindent(" one\n two\n").should == "one\ntwo\n" + end + + it "should not be phased by empty lines" do + @helper.unindent(" one\n\n two\n").should == "one\n\ntwo\n" + end + + it "should only remove a common prefix" do + @helper.unindent(" one\n two\n").should == " one\ntwo\n" + end + + it "should also remove tabs if present" do + @helper.unindent("\tone\n\ttwo\n").should == "one\ntwo\n" + end + + it "should ignore lines starting with --" do + @helper.unindent(" one\n--\n two\n").should == "one\n--\ntwo\n" + end + end end diff --git a/spec/documentation_helper_spec.rb b/spec/documentation_helper_spec.rb new file mode 100644 index 00000000..7623ffb0 --- /dev/null +++ b/spec/documentation_helper_spec.rb @@ -0,0 +1,73 @@ +require 'helper' + +describe Pry::Helpers::DocumentationHelpers do + before do + @helper = Pry::Helpers::DocumentationHelpers + end + + describe "get_comment_content" do + it "should strip off the hash and unindent" do + @helper.get_comment_content(" # hello\n # world\n").should == "hello\nworld\n" + end + + it "should strip out leading lines of hashes" do + @helper.get_comment_content("###############\n#hello\n#world\n").should == "hello\nworld\n" + end + + it "should remove shebangs" do + @helper.get_comment_content("#!/usr/bin/env ruby\n# This is a program\n").should == "This is a program\n" + end + + it "should unindent past separators" do + @helper.get_comment_content(" # Copyright Me \n #--\n # So there.\n").should == "Copyright Me \n--\nSo there.\n" + end + end + + describe "process_rdoc" do + before do + Pry.color = true + end + + after do + Pry.color = false + end + + it "should syntax highlight indented code" do + @helper.process_rdoc(" 4 + 4\n").should.not == " 4 + 4\n" + end + + it "should highlight words surrounded by +s" do + @helper.process_rdoc("the +parameter+").should =~ /the \e.*parameter\e.*/ + end + + it "should syntax highlight things in backticks" do + @helper.process_rdoc("for `Example`").should =~ /for `\e.*Example\e.*`/ + end + + it "should emphasise em tags" do + @helper.process_rdoc("for science").should == "for \e[1mscience\e[0m" + end + + it "should emphasise italic tags" do + @helper.process_rdoc("for science").should == "for \e[1mscience\e[0m" + end + + it "should syntax highlight code in " do + @helper.process_rdoc("for Example").should =~ /for \e.*Example\e.*/ + end + + it "should not double-highlight backticks inside indented code" do + @helper.process_rdoc(" `echo 5`").should =~ /echo 5/ + end + + it "should not remove ++" do + @helper.process_rdoc("--\n comment in a bubble\n++").should =~ /\+\+/ + end + + it "should do nothing if Pry.color is false" do + Pry.color = false + @helper.process_rdoc(" 4 + 4\n").should == " 4 + 4\n" + end + end + +end \ No newline at end of file