[ruby/reline] multiline_repl do not need to depend on RubyLex
(https://github.com/ruby/reline/pull/502) * multiline_repl do not need to depend on RubyLex * Add auto indent test
This commit is contained in:
parent
46066d0b96
commit
2d7e639549
@ -53,7 +53,9 @@ opt.on('--color-bold') {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
opt.on('--auto-indent') {
|
opt.on('--auto-indent') {
|
||||||
AutoIndent.new
|
Reline.auto_indent_proc = lambda do |lines, line_index, byte_pointer, is_newline|
|
||||||
|
AutoIndent.calculate_indent(lines, line_index, byte_pointer, is_newline)
|
||||||
|
end
|
||||||
}
|
}
|
||||||
opt.on('--dialog VAL') { |v|
|
opt.on('--dialog VAL') { |v|
|
||||||
Reline.add_dialog_proc(:simple_dialog, lambda {
|
Reline.add_dialog_proc(:simple_dialog, lambda {
|
||||||
@ -194,8 +196,7 @@ end
|
|||||||
begin
|
begin
|
||||||
prompt = ENV['RELINE_TEST_PROMPT'] || 'prompt> '
|
prompt = ENV['RELINE_TEST_PROMPT'] || 'prompt> '
|
||||||
puts 'Multiline REPL.'
|
puts 'Multiline REPL.'
|
||||||
checker = TerminationChecker.new
|
while code = Reline.readmultiline(prompt, true) { |code| TerminationChecker.terminated?(code) }
|
||||||
while code = Reline.readmultiline(prompt, true) { |code| checker.terminated?(code) }
|
|
||||||
case code.chomp
|
case code.chomp
|
||||||
when 'exit', 'quit', 'q'
|
when 'exit', 'quit', 'q'
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -1,28 +1,26 @@
|
|||||||
require 'ripper'
|
require 'ripper'
|
||||||
require 'irb/ruby-lex'
|
|
||||||
|
|
||||||
class TerminationChecker < RubyLex
|
module TerminationChecker
|
||||||
def terminated?(code)
|
def self.terminated?(code)
|
||||||
code.gsub!(/\n*$/, '').concat("\n")
|
Ripper.sexp(code) ? true : false
|
||||||
tokens = self.class.ripper_lex_without_warning(code)
|
end
|
||||||
continue = process_continue(tokens)
|
end
|
||||||
code_block_open = check_code_block(code, tokens)
|
|
||||||
indent = process_nesting_level(tokens)
|
module AutoIndent
|
||||||
ltype = process_literal_type(tokens)
|
def self.calculate_indent(lines, line_index, byte_pointer, is_newline)
|
||||||
if code_block_open or ltype or continue or indent > 0
|
if is_newline
|
||||||
false
|
2 * nesting_level(lines[0..line_index - 1])
|
||||||
else
|
else
|
||||||
true
|
lines = lines.dup
|
||||||
|
lines[line_index] = lines[line_index]&.byteslice(0, byte_pointer)
|
||||||
|
prev_level = nesting_level(lines[0..line_index - 1])
|
||||||
|
level = nesting_level(lines[0..line_index])
|
||||||
|
2 * level if level < prev_level
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
class AutoIndent < RubyLex
|
def self.nesting_level(lines)
|
||||||
def initialize
|
code = lines.join("\n")
|
||||||
@context = Struct.new("MockIRBContext", :auto_indent_mode, :workspace, :local_variables).new(true, nil, [])
|
code.scan(/if|def|\(|\[|\{/).size - code.scan(/end|\)|\]|\}/).size
|
||||||
end
|
|
||||||
|
|
||||||
def auto_indent(&block)
|
|
||||||
Reline.auto_indent_proc = block
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -661,6 +661,35 @@ begin
|
|||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_auto_indent
|
||||||
|
start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
|
||||||
|
"def hoge\nputs(\n1,\n2\n)\nend".lines do |line|
|
||||||
|
write line
|
||||||
|
end
|
||||||
|
close
|
||||||
|
assert_screen(<<~EOC)
|
||||||
|
Multiline REPL.
|
||||||
|
prompt> def hoge
|
||||||
|
prompt> puts(
|
||||||
|
prompt> 1,
|
||||||
|
prompt> 2
|
||||||
|
prompt> )
|
||||||
|
prompt> end
|
||||||
|
EOC
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_auto_indent_when_inserting_line
|
||||||
|
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
|
||||||
|
write 'aa(bb(cc(dd(ee('
|
||||||
|
write "\C-b" * 5 + "\n"
|
||||||
|
close
|
||||||
|
assert_screen(<<~EOC)
|
||||||
|
Multiline REPL.
|
||||||
|
prompt> aa(bb(cc(d
|
||||||
|
prompt> d(ee(
|
||||||
|
EOC
|
||||||
|
end
|
||||||
|
|
||||||
def test_suppress_auto_indent_just_after_pasted
|
def test_suppress_auto_indent_just_after_pasted
|
||||||
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
|
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
|
||||||
write("def hoge\n [[\n 3]]\ned")
|
write("def hoge\n [[\n 3]]\ned")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user