diff --git a/lib/irb/command/show_source.rb b/lib/irb/command/show_source.rb index f4c6f104a..5da11ae29 100644 --- a/lib/irb/command/show_source.rb +++ b/lib/irb/command/show_source.rb @@ -36,10 +36,12 @@ def execute(arg) str, esses = str.split(" -") super_level = esses ? esses.count("s") : 0 - source = SourceFinder.new(@irb_context).find_source(str, super_level) + source_finder = SourceFinder.new(@irb_context) + source = source_finder.find_source(str, super_level) + rdoc_path = source_finder.resolve_rdoc_path(str) - if source - show_source(source) + if source || rdoc_path + show_source(source, rdoc_path) elsif super_level > 0 puts "Error: Couldn't locate a super definition for #{str}" else @@ -50,20 +52,36 @@ def execute(arg) private - def show_source(source) - if source.binary_file? - content = "\n#{bold('Defined in binary file')}: #{source.file}\n\n" - else - code = source.colorized_content || 'Source not available' - content = <<~CONTENT - - #{bold("From")}: #{source.file}:#{source.line} - - #{code.chomp} - - CONTENT - end - Pager.page_content(content) + def show_source(source, rdoc_path) + # Note: + # - We use /master because it has better UI from the latest RDoc + # - The main reason this is experimental is because we can't easily verify if the documentation actually exists. + # While RI may be used to display the documentation directly in a pager, it doesn't have a good API to check + # if the documentation exists. + docs_link = "#{bold("[Experimental] View on Ruby docs")}: https://docs.ruby-lang.org/en/master/#{rdoc_path}" if rdoc_path + + content = + if source + if source.binary_file? + <<~CONTENT + #{docs_link} + #{bold('Defined in binary file')}: #{source.file}\n\n + CONTENT + else + code = source.colorized_content || 'Source not available' + <<~CONTENT + #{docs_link} + + #{bold("From")}: #{source.file}:#{source.line} + + #{code.chomp} + + CONTENT + end + else + docs_link + end + Pager.page_content(content) if content end def bold(str) diff --git a/lib/irb/source_finder.rb b/lib/irb/source_finder.rb index ee4b5f61f..5ca216382 100644 --- a/lib/irb/source_finder.rb +++ b/lib/irb/source_finder.rb @@ -101,7 +101,12 @@ def resolve_rdoc_path(signature, super_level = 0) return unless method method_type_flag = method.owner.singleton_class? ? "c" : "i" - receiver.name.split("::").join("/") + ".html#method-#{method_type_flag}-#{method.name}" + + if receiver.is_a?(Class) + receiver.name.split("::").join("/") + ".html#method-#{method_type_flag}-#{method.name}" + else + "Kernel.html#method-#{method_type_flag}-#{method.name}" + end end rescue EvaluationError nil