[ruby/irb] Support repeating debugger input by passing empty input
to it (https://github.com/ruby/irb/pull/856) * Test IRB's behaviour with empty input * Handle empty input and pass it to debugger 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`. https://github.com/ruby/irb/commit/0e9db419be
This commit is contained in:
parent
ff4f5c0cdd
commit
b315826377
@ -1082,16 +1082,17 @@ module IRB
|
|||||||
loop do
|
loop do
|
||||||
code = readmultiline
|
code = readmultiline
|
||||||
break unless code
|
break unless code
|
||||||
|
|
||||||
if code != "\n"
|
|
||||||
yield build_statement(code), @line_no
|
yield build_statement(code), @line_no
|
||||||
end
|
|
||||||
@line_no += code.count("\n")
|
@line_no += code.count("\n")
|
||||||
rescue RubyLex::TerminateLineInput
|
rescue RubyLex::TerminateLineInput
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_statement(code)
|
def build_statement(code)
|
||||||
|
if code.match?(/\A\n*\z/)
|
||||||
|
return Statement::EmptyInput.new
|
||||||
|
end
|
||||||
|
|
||||||
code.force_encoding(@context.io.encoding)
|
code.force_encoding(@context.io.encoding)
|
||||||
command_or_alias, arg = code.split(/\s/, 2)
|
command_or_alias, arg = code.split(/\s/, 2)
|
||||||
# Transform a non-identifier alias (@, $) or keywords (next, break)
|
# Transform a non-identifier alias (@, $) or keywords (next, break)
|
||||||
|
@ -20,6 +20,29 @@ module IRB
|
|||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
end
|
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
|
class Expression < Statement
|
||||||
def initialize(code, is_assignment)
|
def initialize(code, is_assignment)
|
||||||
@code = code
|
@code = code
|
||||||
|
@ -6,7 +6,7 @@ require "tmpdir"
|
|||||||
require_relative "helper"
|
require_relative "helper"
|
||||||
|
|
||||||
module TestIRB
|
module TestIRB
|
||||||
class DebugCommandTest < IntegrationTestCase
|
class DebuggerIntegrationTest < IntegrationTestCase
|
||||||
def setup
|
def setup
|
||||||
super
|
super
|
||||||
|
|
||||||
@ -434,5 +434,29 @@ module TestIRB
|
|||||||
assert_match(/irb\(main\):001> next/, output)
|
assert_match(/irb\(main\):001> next/, output)
|
||||||
assert_include(output, "Multi-IRB commands are not available when the debugger is enabled.")
|
assert_include(output, "Multi-IRB commands are not available when the debugger is enabled.")
|
||||||
end
|
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
|
||||||
end
|
end
|
@ -58,6 +58,24 @@ module TestIRB
|
|||||||
assert_include output, "=> \"It's a foo\""
|
assert_include output, "=> \"It's a foo\""
|
||||||
assert_include output, "=> \"It's a bar\""
|
assert_include output, "=> \"It's a bar\""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_empty_input_echoing_behaviour
|
||||||
|
write_ruby <<~'RUBY'
|
||||||
|
binding.irb
|
||||||
|
RUBY
|
||||||
|
|
||||||
|
output = run_ruby_file do
|
||||||
|
type ""
|
||||||
|
type " "
|
||||||
|
type "exit"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Input cramped together due to how Reline's Reline::GeneralIO works
|
||||||
|
assert_include(
|
||||||
|
output,
|
||||||
|
"irb(main):001> irb(main):002> irb(main):002> irb(main):002> => nil\r\n"
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class IrbIOConfigurationTest < TestCase
|
class IrbIOConfigurationTest < TestCase
|
||||||
|
Loading…
x
Reference in New Issue
Block a user