Backport lib/reline, and lib/irb for 3.0.1 3rd (#4228)

* [ruby/irb] Suppress error when File::ALT_SEPARATOR is nil

96accf3b95

* [ruby/irb] Suppress colorize on Windows tests

5be9354cf9

* [ruby/irb] The command "irb_info" should show RUBY_PLATFORM

39d1cd874f

* [ruby/irb] Fix inverse separator condition

33f933196f

* [ruby/reline] Return 1 when char width not found

This fixes ruby/reline#261.

3cf1213014

* [ruby/reline] Avoid tripping over nil prompt

d4d9d3e3d4

* [ruby/reline] Move script files for yamatanooroti tests

03031b885d

* [ruby/reline] Add a test for suppressing crash when dynamic prompt returns empty

ref. https://github.com/ruby/reline/pull/262

b98bc3c329

* [ruby/reline] We still need support new and legacy behavior.
Revert "Support for change in Windows-specific behavior at eol"

This reverts commit cad4de6ee841b43f3f0e441626f9415c3eda0f82.

646587fc2c

* [ruby/reline] check ENABLE_VIRTUAL_TERMINAL_PROCESSING flag and switch eof processing

3535676689

* [ruby/reline] Use UTF-8 only for width calc, rest uses original encoding

I confirmed that libvterm supports only which are UTF-8, US ASCII, UK, and
DEC graphics by reading source code, so can't test this patch by
yamatanoorogi gem through vterm gem for now.

This fixes ruby/irb#190.

44596c0cc7

* [ruby/reline] fix Reline::Windows.getconsolemode buffer

use double quotes to properly convert the \000 escape sequence.

236dfe5683

* [ruby/irb] Version 1.3.4

ab9852ccc5

* [ruby/reline] Version 0.2.4

462f971bd3

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
Co-authored-by: Eamonn Webster <eamonn.webster@gmail.com>
Co-authored-by: Yoshinao Muramatu <ysno@ac.auone-net.jp>
Co-authored-by: cremno <cremno@mail.ru>
This commit is contained in:
aycabta 2021-02-26 10:32:34 +09:00 committed by GitHub
parent 551f1236a4
commit 46825a7462
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 231 additions and 60 deletions

View file

@ -13,6 +13,7 @@ module IRB
str += "IRB version: #{IRB.version}\n" str += "IRB version: #{IRB.version}\n"
str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n" str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n"
str += ".irbrc path: #{IRB.rc_file}\n" if File.exist?(IRB.rc_file) str += ".irbrc path: #{IRB.rc_file}\n" if File.exist?(IRB.rc_file)
str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
str str
end end
alias_method :to_s, :inspect alias_method :to_s, :inspect

View file

@ -38,9 +38,9 @@ module IRB # :nodoc:
else else
separator = separator =
if File::ALT_SEPARATOR if File::ALT_SEPARATOR
File::SEPARATOR
else
"[#{Regexp.quote(File::SEPARATOR + File::ALT_SEPARATOR)}]" "[#{Regexp.quote(File::SEPARATOR + File::ALT_SEPARATOR)}]"
else
File::SEPARATOR
end end
ABSOLUTE_PATH_PATTERN = # :nodoc: ABSOLUTE_PATH_PATTERN = # :nodoc:
case Dir.pwd case Dir.pwd

View file

@ -11,7 +11,7 @@
# #
module IRB # :nodoc: module IRB # :nodoc:
VERSION = "1.3.3" VERSION = "1.3.4"
@RELEASE_VERSION = VERSION @RELEASE_VERSION = VERSION
@LAST_UPDATE_DATE = "2021-02-07" @LAST_UPDATE_DATE = "2021-02-25"
end end

View file

@ -175,7 +175,7 @@ EOF
body = (start_pos..end_pos).map do |current_pos| body = (start_pos..end_pos).map do |current_pos|
sprintf(fmt, pos == current_pos ? '=>' : '', current_pos + 1, lines[current_pos]) sprintf(fmt, pos == current_pos ? '=>' : '', current_pos + 1, lines[current_pos])
end.join("") end.join("")
"\nFrom: #{file} @ line #{pos + 1} :\n\n#{body}#{Color.clear}\n" "\nFrom: #{file} @ line #{pos + 1} :\n\n#{body}#{Color.clear if use_colorize}\n"
end end
def IRB.delete_caller def IRB.delete_caller

View file

@ -124,6 +124,7 @@ class Reline::LineEditor
@prompt_cache_time = Time.now.to_f @prompt_cache_time = Time.now.to_f
end end
prompt_list.map!{ prompt } if @vi_arg or @searching_prompt prompt_list.map!{ prompt } if @vi_arg or @searching_prompt
prompt_list = [prompt] if prompt_list.empty?
mode_string = check_mode_string mode_string = check_mode_string
prompt_list = prompt_list.map{ |pr| mode_string + pr } if mode_string prompt_list = prompt_list.map{ |pr| mode_string + pr } if mode_string
prompt = prompt_list[@line_index] prompt = prompt_list[@line_index]
@ -343,8 +344,9 @@ class Reline::LineEditor
else else
end_of_line_cursor = new_cursor_max end_of_line_cursor = new_cursor_max
end end
line_to_calc.encode(Encoding::UTF_8).grapheme_clusters.each do |gc| line_to_calc.grapheme_clusters.each do |gc|
mbchar_width = Reline::Unicode.get_mbchar_width(gc) mbchar = gc.encode(Encoding::UTF_8)
mbchar_width = Reline::Unicode.get_mbchar_width(mbchar)
now = new_cursor + mbchar_width now = new_cursor + mbchar_width
if now > end_of_line_cursor or now > cursor if now > end_of_line_cursor or now > cursor
break break
@ -724,13 +726,17 @@ class Reline::LineEditor
Reline::IOGate.move_cursor_column(0) Reline::IOGate.move_cursor_column(0)
if line.nil? if line.nil?
if calculate_width(visual_lines[index - 1], true) == Reline::IOGate.get_screen_size.last if calculate_width(visual_lines[index - 1], true) == Reline::IOGate.get_screen_size.last
# Reaches the end of line. # reaches the end of line
# if Reline::IOGate.win? and Reline::IOGate.win_legacy_console?
# A newline is automatically inserted if a character is rendered at
# eol on command prompt.
else
# When the cursor is at the end of the line and erases characters # When the cursor is at the end of the line and erases characters
# after the cursor, some terminals delete the character at the # after the cursor, some terminals delete the character at the
# cursor position. # cursor position.
move_cursor_down(1) move_cursor_down(1)
Reline::IOGate.move_cursor_column(0) Reline::IOGate.move_cursor_column(0)
end
else else
Reline::IOGate.erase_after_cursor Reline::IOGate.erase_after_cursor
move_cursor_down(1) move_cursor_down(1)
@ -739,6 +745,10 @@ class Reline::LineEditor
next next
end end
@output.write line @output.write line
if Reline::IOGate.win? and Reline::IOGate.win_legacy_console? and calculate_width(line, true) == Reline::IOGate.get_screen_size.last
# A newline is automatically inserted if a character is rendered at eol on command prompt.
@rest_height -= 1 if @rest_height > 0
end
@output.flush @output.flush
if @first_prompt if @first_prompt
@first_prompt = false @first_prompt = false

View file

@ -108,6 +108,7 @@ class Reline::Unicode
end end
m = mbchar.encode(Encoding::UTF_8).match(MBCharWidthRE) m = mbchar.encode(Encoding::UTF_8).match(MBCharWidthRE)
case case
when m.nil? then 1 # TODO should be U+FFFD <20> REPLACEMENT CHARACTER
when m[:width_2_1], m[:width_2_2] then 2 when m[:width_2_1], m[:width_2_2] then 2
when m[:width_3] then 3 when m[:width_3] then 3
when m[:width_0] then 0 when m[:width_0] then 0

View file

@ -1,3 +1,3 @@
module Reline module Reline
VERSION = '0.2.3' VERSION = '0.2.4'
end end

View file

@ -9,6 +9,10 @@ class Reline::Windows
true true
end end
def self.win_legacy_console?
@@legacy_console
end
RAW_KEYSTROKE_CONFIG = { RAW_KEYSTROKE_CONFIG = {
[224, 72] => :ed_prev_history, # ↑ [224, 72] => :ed_prev_history, # ↑
[224, 80] => :ed_next_history, # ↓ [224, 80] => :ed_next_history, # ↓
@ -94,6 +98,26 @@ class Reline::Windows
@@GetFileInformationByHandleEx = Win32API.new('kernel32', 'GetFileInformationByHandleEx', ['L', 'I', 'P', 'L'], 'I') @@GetFileInformationByHandleEx = Win32API.new('kernel32', 'GetFileInformationByHandleEx', ['L', 'I', 'P', 'L'], 'I')
@@FillConsoleOutputAttribute = Win32API.new('kernel32', 'FillConsoleOutputAttribute', ['L', 'L', 'L', 'L', 'P'], 'L') @@FillConsoleOutputAttribute = Win32API.new('kernel32', 'FillConsoleOutputAttribute', ['L', 'L', 'L', 'L', 'P'], 'L')
@@GetConsoleMode = Win32API.new('kernel32', 'GetConsoleMode', ['L', 'P'], 'L')
@@SetConsoleMode = Win32API.new('kernel32', 'SetConsoleMode', ['L', 'L'], 'L')
ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4
private_class_method def self.getconsolemode
mode = "\000\000\000\000"
@@GetConsoleMode.call(@@hConsoleHandle, mode)
mode.unpack1('L')
end
private_class_method def self.setconsolemode(mode)
@@SetConsoleMode.call(@@hConsoleHandle, mode)
end
@@legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0)
#if @@legacy_console
# setconsolemode(getconsolemode() | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
# @@legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0)
#end
@@input_buf = [] @@input_buf = []
@@output_buf = [] @@output_buf = []

View file

@ -48,7 +48,8 @@ module TestIRB
Ruby\sversion: .+\n Ruby\sversion: .+\n
IRB\sversion:\sirb .+\n IRB\sversion:\sirb .+\n
InputMethod:\sReidlineInputMethod\swith\sReline .+ and .+\n InputMethod:\sReidlineInputMethod\swith\sReline .+ and .+\n
\.irbrc\spath: .+ \.irbrc\spath: .+\n
RUBY_PLATFORM: .+
}x }x
assert_match expected, irb.context.main.irb_info.to_s assert_match expected, irb.context.main.irb_info.to_s
end end
@ -67,7 +68,8 @@ module TestIRB
Ruby\sversion: .+\n Ruby\sversion: .+\n
IRB\sversion:\sirb .+\n IRB\sversion:\sirb .+\n
InputMethod:\sReadlineInputMethod\swith .+ and .+\n InputMethod:\sReadlineInputMethod\swith .+ and .+\n
\.irbrc\spath: .+ \.irbrc\spath: .+\n
RUBY_PLATFORM: .+
}x }x
assert_match expected, irb.context.main.irb_info.to_s assert_match expected, irb.context.main.irb_info.to_s
end end
@ -89,6 +91,7 @@ module TestIRB
Ruby\sversion: .+\n Ruby\sversion: .+\n
IRB\sversion:\sirb .+\n IRB\sversion:\sirb .+\n
InputMethod:\sReidlineInputMethod\swith\sReline\s[^ ]+(?!\sand\s.+)\n InputMethod:\sReidlineInputMethod\swith\sReline\s[^ ]+(?!\sand\s.+)\n
RUBY_PLATFORM: .+\n
\z \z
}x }x
assert_match expected, irb.context.main.irb_info.to_s assert_match expected, irb.context.main.irb_info.to_s
@ -115,6 +118,7 @@ module TestIRB
Ruby\sversion: .+\n Ruby\sversion: .+\n
IRB\sversion:\sirb .+\n IRB\sversion:\sirb .+\n
InputMethod:\sReadlineInputMethod\swith\s(?~.*\sand\s.+)\n InputMethod:\sReadlineInputMethod\swith\s(?~.*\sand\s.+)\n
RUBY_PLATFORM: .+\n
\z \z
}x }x
assert_match expected, irb.context.main.irb_info.to_s assert_match expected, irb.context.main.irb_info.to_s

View file

@ -9,6 +9,7 @@ require 'irb/color'
module TestIRB module TestIRB
class TestWorkSpace < Test::Unit::TestCase class TestWorkSpace < Test::Unit::TestCase
def test_code_around_binding def test_code_around_binding
IRB.conf[:USE_COLORIZE] = false
Tempfile.create('irb') do |f| Tempfile.create('irb') do |f|
code = <<~RUBY code = <<~RUBY
# 1 # 1
@ -33,6 +34,8 @@ module TestIRB
EOS EOS
end end
ensure
IRB.conf.delete(:USE_COLORIZE)
end end
def test_code_around_binding_with_existing_unreadable_file def test_code_around_binding_with_existing_unreadable_file
@ -52,6 +55,7 @@ module TestIRB
end end
def test_code_around_binding_with_script_lines__ def test_code_around_binding_with_script_lines__
IRB.conf[:USE_COLORIZE] = false
with_script_lines do |script_lines| with_script_lines do |script_lines|
Tempfile.create('irb') do |f| Tempfile.create('irb') do |f|
code = "IRB::WorkSpace.new(binding)\n" code = "IRB::WorkSpace.new(binding)\n"
@ -67,6 +71,8 @@ module TestIRB
EOS EOS
end end
end end
ensure
IRB.conf.delete(:USE_COLORIZE)
end end
def test_code_around_binding_on_irb def test_code_around_binding_on_irb

View file

@ -2280,6 +2280,14 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
assert_line(' 12345') assert_line(' 12345')
end end
def test_input_unknown_char
input_keys('͸') # U+0378 (unassigned)
assert_line('͸')
assert_byte_pointer_size('͸')
assert_cursor(1)
assert_cursor_max(1)
end
=begin # TODO: move KeyStroke instance from Reline to LineEditor =begin # TODO: move KeyStroke instance from Reline to LineEditor
def test_key_delete def test_key_delete
input_keys('ab') input_keys('ab')

View file

@ -0,0 +1,74 @@
#!/usr/bin/env ruby
require 'reline'
require 'optparse'
require_relative 'termination_checker'
opt = OptionParser.new
opt.on('--prompt-list-cache-timeout VAL') { |v|
Reline::LineEditor.__send__(:remove_const, :PROMPT_LIST_CACHE_TIMEOUT)
Reline::LineEditor::PROMPT_LIST_CACHE_TIMEOUT = v.to_f
}
opt.on('--dynamic-prompt') {
Reline.prompt_proc = proc { |lines|
lines.each_with_index.map { |l, i|
'[%04d]> ' % i
}
}
}
opt.on('--broken-dynamic-prompt') {
Reline.prompt_proc = proc { |lines|
range = lines.size > 1 ? (0..(lines.size - 2)) : (0..0)
lines[range].each_with_index.map { |l, i|
'[%04d]> ' % i
}
}
}
opt.on('--dynamic-prompt-returns-empty') {
Reline.prompt_proc = proc { |l| [] }
}
opt.on('--auto-indent') {
AutoIndent.new
}
opt.parse!(ARGV)
begin
stty_save = `stty -g`.chomp
rescue
end
begin
prompt = ENV['RELINE_TEST_PROMPT'] || 'prompt> '
puts 'Multiline REPL.'
checker = TerminationChecker.new
while code = Reline.readmultiline(prompt, true) { |code| checker.terminated?(code) }
case code.chomp
when 'exit', 'quit', 'q'
exit 0
when ''
# NOOP
else
begin
result = eval(code)
puts "=> #{result.inspect}"
rescue ScriptError, StandardError => e
puts "Traceback (most recent call last):"
e.backtrace.reverse_each do |f|
puts " #{f}"
end
puts e.message
end
end
end
rescue Interrupt
puts '^C'
`stty #{stty_save}` if stty_save
exit 0
ensure
`stty #{stty_save}` if stty_save
end
begin
puts
rescue Errno::EIO
# Maybe the I/O has been closed.
end

View file

@ -0,0 +1,30 @@
require 'ripper'
require 'irb/ruby-lex'
class TerminationChecker < RubyLex
def terminated?(code)
code.gsub!(/\n*$/, '').concat("\n")
@tokens = Ripper.lex(code)
continue = process_continue
code_block_open = check_code_block(code)
indent = process_nesting_level
ltype = process_literal_type
if code_block_open or ltype or continue or indent > 0
false
else
true
end
end
end
class AutoIndent < RubyLex
def initialize
set_input(self)
context = Struct.new(:auto_indent_mode).new(true)
set_auto_indent(context)
end
def auto_indent(&block)
Reline.auto_indent_proc = block
end
end

View file

@ -26,7 +26,7 @@ begin
end end
def test_history_back def test_history_back
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write(":a\n") write(":a\n")
write("\C-p") write("\C-p")
close close
@ -39,7 +39,7 @@ begin
end end
def test_backspace def test_backspace
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write(":abc\C-h\n") write(":abc\C-h\n")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -51,7 +51,7 @@ begin
end end
def test_autowrap def test_autowrap
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write('01234567890123456789012') write('01234567890123456789012')
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -62,7 +62,7 @@ begin
end end
def test_fullwidth def test_fullwidth
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write(":あ\n") write(":あ\n")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -74,7 +74,7 @@ begin
end end
def test_two_fullwidth def test_two_fullwidth
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write(":あい\n") write(":あい\n")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -86,7 +86,7 @@ begin
end end
def test_finish_autowrapped_line def test_finish_autowrapped_line
start_terminal(10, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(10, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("[{'user'=>{'email'=>'a@a', 'id'=>'ABC'}, 'version'=>4, 'status'=>'succeeded'}]\n") write("[{'user'=>{'email'=>'a@a', 'id'=>'ABC'}, 'version'=>4, 'status'=>'succeeded'}]\n")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -102,7 +102,7 @@ begin
end end
def test_finish_autowrapped_line_in_the_middle_of_lines def test_finish_autowrapped_line_in_the_middle_of_lines
start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("[{'user'=>{'email'=>'abcdef@abcdef', 'id'=>'ABC'}, 'version'=>4, 'status'=>'succeeded'}]#{"\C-b"*7}") write("[{'user'=>{'email'=>'abcdef@abcdef', 'id'=>'ABC'}, 'version'=>4, 'status'=>'succeeded'}]#{"\C-b"*7}")
write("\n") write("\n")
close close
@ -121,7 +121,7 @@ begin
end end
def test_finish_autowrapped_line_in_the_middle_of_multilines def test_finish_autowrapped_line_in_the_middle_of_multilines
start_terminal(30, 16, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(30, 16, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("<<~EOM\n ABCDEFG\nEOM\n") write("<<~EOM\n ABCDEFG\nEOM\n")
close close
assert_screen(<<~'EOC') assert_screen(<<~'EOC')
@ -139,7 +139,7 @@ begin
write_inputrc <<~'LINES' write_inputrc <<~'LINES'
"abc": "123" "abc": "123"
LINES LINES
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("abc\n") write("abc\n")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -154,7 +154,7 @@ begin
write_inputrc <<~LINES write_inputrc <<~LINES
set show-mode-in-prompt on set show-mode-in-prompt on
LINES LINES
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
Multiline REPL. Multiline REPL.
@ -167,7 +167,7 @@ begin
set editing-mode vi set editing-mode vi
set show-mode-in-prompt on set show-mode-in-prompt on
LINES LINES
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write(":a\n\C-[k") write(":a\n\C-[k")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -183,7 +183,7 @@ begin
set show-mode-in-prompt on set show-mode-in-prompt on
set emacs-mode-string [emacs] set emacs-mode-string [emacs]
LINES LINES
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
Multiline REPL. Multiline REPL.
@ -196,7 +196,7 @@ begin
set show-mode-in-prompt on set show-mode-in-prompt on
set emacs-mode-string "[emacs]" set emacs-mode-string "[emacs]"
LINES LINES
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
Multiline REPL. Multiline REPL.
@ -211,7 +211,7 @@ begin
set vi-ins-mode-string "{InS}" set vi-ins-mode-string "{InS}"
set vi-cmd-mode-string "{CmD}" set vi-cmd-mode-string "{CmD}"
LINES LINES
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write(":a\n\C-[k") write(":a\n\C-[k")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -227,7 +227,7 @@ begin
set editing-mode vi set editing-mode vi
set show-mode-in-prompt on set show-mode-in-prompt on
LINES LINES
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write(":a\C-[ab\C-[ac\C-h\C-h\C-h\C-h:a") write(":a\C-[ab\C-[ac\C-h\C-h\C-h\C-h:a")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -238,7 +238,7 @@ begin
def test_prompt_with_escape_sequence def test_prompt_with_escape_sequence
ENV['RELINE_TEST_PROMPT'] = "\1\e[30m\2prompt> \1\e[m\2" ENV['RELINE_TEST_PROMPT'] = "\1\e[30m\2prompt> \1\e[m\2"
start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("123\n") write("123\n")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -251,7 +251,7 @@ begin
def test_prompt_with_escape_sequence_and_autowrap def test_prompt_with_escape_sequence_and_autowrap
ENV['RELINE_TEST_PROMPT'] = "\1\e[30m\2prompt> \1\e[m\2" ENV['RELINE_TEST_PROMPT'] = "\1\e[30m\2prompt> \1\e[m\2"
start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("1234567890123\n") write("1234567890123\n")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -264,7 +264,7 @@ begin
end end
def test_multiline_and_autowrap def test_multiline_and_autowrap
start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def aaaaaaaaaa\n 33333333\n end\C-a\C-pputs\C-e\e\C-m888888888888888") write("def aaaaaaaaaa\n 33333333\n end\C-a\C-pputs\C-e\e\C-m888888888888888")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -281,7 +281,7 @@ begin
end end
def test_clear def test_clear
start_terminal(10, 15, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(10, 15, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("3\C-l") write("3\C-l")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -291,7 +291,7 @@ begin
def test_clear_multiline_and_autowrap def test_clear_multiline_and_autowrap
omit # FIXME clear logic is buggy omit # FIXME clear logic is buggy
start_terminal(10, 15, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(10, 15, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def aaaaaa\n 3\n\C-lend") write("def aaaaaa\n 3\n\C-lend")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -303,7 +303,7 @@ begin
end end
def test_nearest_cursor def test_nearest_cursor
start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def ああ\n :いい\nend\C-pbb\C-pcc") write("def ああ\n :いい\nend\C-pbb\C-pcc")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -315,7 +315,7 @@ begin
end end
def test_delete_line def test_delete_line
start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def a\n\nend\C-p\C-h") write("def a\n\nend\C-p\C-h")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -326,7 +326,7 @@ begin
end end
def test_last_line_of_screen def test_last_line_of_screen
start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("\n\n\n\n\ndef a\nend") write("\n\n\n\n\ndef a\nend")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -340,7 +340,7 @@ begin
# c17a09b7454352e2aff5a7d8722e80afb73e454b # c17a09b7454352e2aff5a7d8722e80afb73e454b
def test_autowrap_at_last_line_of_screen def test_autowrap_at_last_line_of_screen
start_terminal(5, 15, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 15, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def a\nend\n\C-p") write("def a\nend\n\C-p")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -354,7 +354,7 @@ begin
# f002483b27cdb325c5edf9e0fe4fa4e1c71c4b0e # f002483b27cdb325c5edf9e0fe4fa4e1c71c4b0e
def test_insert_line_in_the_middle_of_line def test_insert_line_in_the_middle_of_line
start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("333\C-b\C-b\e\C-m8") write("333\C-b\C-b\e\C-m8")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -366,7 +366,7 @@ begin
# 9d8978961c5de5064f949d56d7e0286df9e18f43 # 9d8978961c5de5064f949d56d7e0286df9e18f43
def test_insert_line_in_the_middle_of_line_at_last_line_of_screen def test_insert_line_in_the_middle_of_line_at_last_line_of_screen
start_terminal(3, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(3, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("333333333333333\C-a\C-f\e\C-m") write("333333333333333\C-a\C-f\e\C-m")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -377,7 +377,7 @@ begin
end end
def test_insert_after_clear def test_insert_after_clear
start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def a\n 01234\nend\C-l\C-p5678") write("def a\n 01234\nend\C-l\C-p5678")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -388,7 +388,7 @@ begin
end end
def test_foced_newline_insertion def test_foced_newline_insertion
start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
#write("def a\nend\C-p\C-e\e\C-m 3") #write("def a\nend\C-p\C-e\e\C-m 3")
write("def a\nend\C-p\C-e\e\x0D") write("def a\nend\C-p\C-e\e\x0D")
close close
@ -401,7 +401,7 @@ begin
end end
def test_multiline_incremental_search def test_multiline_incremental_search
start_terminal(6, 25, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(6, 25, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def a\n 8\nend\ndef b\n 3\nend\C-s8") write("def a\n 8\nend\ndef b\n 3\nend\C-s8")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -412,7 +412,7 @@ begin
end end
def test_multiline_incremental_search_finish def test_multiline_incremental_search_finish
start_terminal(6, 25, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(6, 25, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def a\n 8\nend\ndef b\n 3\nend\C-r8\C-j") write("def a\n 8\nend\ndef b\n 3\nend\C-r8\C-j")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -427,7 +427,7 @@ begin
set editing-mode vi set editing-mode vi
"\\C-j": vi-movement-mode "\\C-j": vi-movement-mode
LINES LINES
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write(":1234\C-jhhhi0") write(":1234\C-jhhhi0")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -437,7 +437,7 @@ begin
end end
def test_prompt_list_caching def test_prompt_list_caching
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl --prompt-list-cache-timeout 10 --dynamic-prompt}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --prompt-list-cache-timeout 10 --dynamic-prompt}, startup_message: 'Multiline REPL.')
write("def hoge\n 3\nend") write("def hoge\n 3\nend")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -449,7 +449,7 @@ begin
end end
def test_broken_prompt_list def test_broken_prompt_list
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl --broken-dynamic-prompt}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --broken-dynamic-prompt}, startup_message: 'Multiline REPL.')
write("def hoge\n 3\nend") write("def hoge\n 3\nend")
close close
assert_screen(<<~EOC) assert_screen(<<~EOC)
@ -465,7 +465,7 @@ begin
write_inputrc <<~LINES write_inputrc <<~LINES
set enable-bracketed-paste on set enable-bracketed-paste on
LINES LINES
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("\e[200~,") write("\e[200~,")
write("def hoge\n 3\nend") write("def hoge\n 3\nend")
write("\e[200~.") write("\e[200~.")
@ -479,7 +479,7 @@ begin
end end
def test_backspace_until_returns_to_initial def test_backspace_until_returns_to_initial
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("ABC") write("ABC")
write("\C-h\C-h\C-h") write("\C-h\C-h\C-h")
close close
@ -490,7 +490,7 @@ begin
end end
def test_longer_than_screen_height def test_longer_than_screen_height
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write(<<~EOC.chomp) write(<<~EOC.chomp)
def each_top_level_statement def each_top_level_statement
initialize_input initialize_input
@ -537,7 +537,7 @@ begin
end end
def test_longer_than_screen_height_with_scroll_back def test_longer_than_screen_height_with_scroll_back
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write(<<~EOC.chomp) write(<<~EOC.chomp)
def each_top_level_statement def each_top_level_statement
initialize_input initialize_input
@ -585,7 +585,7 @@ begin
end end
def test_longer_than_screen_height_with_complex_scroll_back def test_longer_than_screen_height_with_complex_scroll_back
start_terminal(4, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(4, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write(<<~EOC.chomp) write(<<~EOC.chomp)
def each_top_level_statement def each_top_level_statement
initialize_input initialize_input
@ -633,7 +633,7 @@ begin
end end
def test_update_cursor_correctly_when_just_cursor_moving def test_update_cursor_correctly_when_just_cursor_moving
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def hoge\n 01234678") write("def hoge\n 01234678")
write("\C-p") write("\C-p")
write("\C-b") write("\C-b")
@ -650,7 +650,7 @@ begin
end 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}/bin/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")
write("\C-bn") write("\C-bn")
close close
@ -664,7 +664,7 @@ begin
end end
def test_suppress_auto_indent_for_adding_newlines_in_pasting def test_suppress_auto_indent_for_adding_newlines_in_pasting
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/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("<<~Q\n") write("<<~Q\n")
write("{\n #\n}") write("{\n #\n}")
write("#") write("#")
@ -679,7 +679,7 @@ begin
end end
def test_autowrap_in_the_middle_of_a_line def test_autowrap_in_the_middle_of_a_line
start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def abcdefg; end\C-b\C-b\C-b\C-b\C-b") write("def abcdefg; end\C-b\C-b\C-b\C-b\C-b")
%w{h i}.each do |c| %w{h i}.each do |c|
write(c) write(c)
@ -693,7 +693,7 @@ begin
end end
def test_terminate_in_the_middle_of_lines def test_terminate_in_the_middle_of_lines
start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.') start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def hoge\n 1\n 2\n 3\n 4\nend\n") write("def hoge\n 1\n 2\n 3\n 4\nend\n")
write("\C-p\C-p\C-p\C-e\n") write("\C-p\C-p\C-p\C-e\n")
close close
@ -706,6 +706,19 @@ begin
EOC EOC
end end
def test_dynamic_prompt_returns_empty
start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dynamic-prompt-returns-empty}, startup_message: 'Multiline REPL.')
write("def hoge\nend\n")
close
assert_screen(<<~EOC)
Multiline REPL.
prompt> def hoge
prompt> end
=> :hoge
prompt>
EOC
end
private def write_inputrc(content) private def write_inputrc(content)
File.open(@inputrc_file, 'w') do |f| File.open(@inputrc_file, 'w') do |f|
f.write content f.write content