Skip to content

Commit

Permalink
Handle empty input and pass it to debugger
Browse files Browse the repository at this point in the history
Since `rdbg` accepts empty input to repeat the previous command, IRB
should take empty input in `irb:rdbg` sessions and pass them to the
debugger.

Currently, IRB simply ignores empty input and does nothing. This commit
creates `EmptyInput` to represent empty input so it can fit into the
current IRB's input processing flow in `Irb#eval_input`.
  • Loading branch information
st0012 committed Feb 16, 2024
1 parent 594a538 commit 7e728a1
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 5 deletions.
9 changes: 5 additions & 4 deletions lib/irb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1082,16 +1082,17 @@ def each_top_level_statement
loop do
code = readmultiline
break unless code

if code != "\n"
yield build_statement(code), @line_no
end
yield build_statement(code), @line_no
@line_no += code.count("\n")
rescue RubyLex::TerminateLineInput
end
end

def build_statement(code)
if code.match?(/\A\n*\z/)
return Statement::EmptyInput.new
end

code.force_encoding(@context.io.encoding)
command_or_alias, arg = code.split(/\s/, 2)
# Transform a non-identifier alias (@, $) or keywords (next, break)
Expand Down
23 changes: 23 additions & 0 deletions lib/irb/statement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,29 @@ def evaluable_code
raise NotImplementedError
end

class EmptyInput < Statement
def is_assignment?
false
end

def suppresses_echo?
true
end

# Debugger takes empty input to repeat the last command
def should_be_handled_by_debugger?
true
end

def code
""
end

def evaluable_code
code
end
end

class Expression < Statement
def initialize(code, is_assignment)
@code = code
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
require_relative "helper"

module TestIRB
class DebugCommandTest < IntegrationTestCase
class DebuggerIntegrationTest < IntegrationTestCase
def setup
super

Expand Down Expand Up @@ -434,5 +434,29 @@ def test_multi_irb_commands_are_not_available_after_activating_the_debugger
assert_match(/irb\(main\):001> next/, output)
assert_include(output, "Multi-IRB commands are not available when the debugger is enabled.")
end

def test_irb_passes_empty_input_to_debugger_to_repeat_the_last_command
write_ruby <<~'ruby'
binding.irb
puts "foo"
puts "bar"
puts "baz"
ruby

output = run_ruby_file do
type "next"
type ""
# Test that empty input doesn't repeat expressions
type "123"
type ""
type "next"
type ""
type ""
end

assert_include(output, "=> 2\| puts \"foo\"")
assert_include(output, "=> 3\| puts \"bar\"")
assert_include(output, "=> 4\| puts \"baz\"")
end
end
end

0 comments on commit 7e728a1

Please sign in to comment.