diff --git a/lib/irb/source_finder.rb b/lib/irb/source_finder.rb index 8d12c32cc..1a6382089 100644 --- a/lib/irb/source_finder.rb +++ b/lib/irb/source_finder.rb @@ -29,10 +29,13 @@ def file_content def colorized_content if !binary_file? && file_exist? - end_line = find_end # To correctly colorize, we need to colorize full content and extract the relevant lines. - colored = IRB::Color.colorize_code(file_content) - colored.lines[@line - 1...end_line].join + colored_lines = IRB::Color.colorize_code(file_content).lines + + # Handle wrong line number case: line_no passed to eval is wrong, file is edited after load, etc + return if colored_lines.size < @line + + colored_lines[@line - 1...find_end].join elsif @ast_source IRB::Color.colorize_code(@ast_source) end diff --git a/test/irb/command/test_show_source.rb b/test/irb/command/test_show_source.rb index 7ef879e81..adf9c8d06 100644 --- a/test/irb/command/test_show_source.rb +++ b/test/irb/command/test_show_source.rb @@ -376,7 +376,7 @@ def test_show_source_shows_binary_source assert_match(%r[Defined in binary file:.+io/console], out) end - def test_show_source_method_overrided + def test_show_source_method_overridden write_ruby <<~RUBY class Request def method; 'POST'; end @@ -393,6 +393,23 @@ def path; '/'; end assert_match(%r[#{@ruby_file.to_path}:3\s+def path; '/'; end], out) end + def test_show_source_with_wrong_line + write_ruby <<~RUBY.chomp + eval 'def foo; end', binding, __FILE__, 4 # Line 4 doesn't exist + binding.irb if + def bar; end # Line 3 + RUBY + + out = run_ruby_file do + type "show_source foo" + type "show_source bar" + type "exit" + end + + assert_match(%r[#{@ruby_file.to_path}:4\s+Source not available], out) + assert_match(%r[#{@ruby_file.to_path}:3\s+def bar; end], out) + end + def test_show_source_with_constant_lookup write_ruby <<~RUBY X = 1