diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb index dc0dcc6bbc..135432a5d1 100644 --- a/lib/reline/line_editor.rb +++ b/lib/reline/line_editor.rb @@ -466,19 +466,17 @@ def rerender new_highest_in_this = calculate_height_by_width(prompt_width + calculate_width(@line.nil? ? '' : @line)) rendered = false if @add_newline_to_end_of_buffer + clear_dialog_with_content rerender_added_newline(prompt, prompt_width) @add_newline_to_end_of_buffer = false else if @just_cursor_moving and not @rerender_all - @dialogs.each do |dialog| - clear_each_dialog(dialog) - dialog.contents = nil - dialog.trap_key = nil - end + clear_dialog_with_content rendered = just_move_cursor @just_cursor_moving = false return elsif @previous_line_index or new_highest_in_this != @highest_in_this + clear_dialog_with_content rerender_changed_current_line @previous_line_index = nil rendered = true @@ -887,6 +885,14 @@ def add_dialog_proc(name, p, context = nil) end end + private def clear_dialog_with_content + @dialogs.each do |dialog| + clear_each_dialog(dialog) + dialog.contents = nil + dialog.trap_key = nil + end + end + private def clear_each_dialog(dialog) dialog.trap_key = nil return unless dialog.contents @@ -2227,6 +2233,8 @@ def finish @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty? @line_index = @buffer_of_lines.size - 1 @line = @buffer_of_lines.last + @byte_pointer = @line.bytesize + @cursor = @cursor_max = calculate_width(@line) @rerender_all = true @searching_prompt = "(%s)`%s'" % [prompt_name, search_word] else diff --git a/test/reline/yamatanooroti/multiline_repl b/test/reline/yamatanooroti/multiline_repl index 3c47184b8e..d27d216652 100755 --- a/test/reline/yamatanooroti/multiline_repl +++ b/test/reline/yamatanooroti/multiline_repl @@ -1,5 +1,9 @@ #!/usr/bin/env ruby + +require 'bundler' +Bundler.require + require 'reline' require 'optparse' require_relative 'termination_checker' diff --git a/test/reline/yamatanooroti/test_rendering.rb b/test/reline/yamatanooroti/test_rendering.rb index a1aab6bfee..c383112131 100644 --- a/test/reline/yamatanooroti/test_rendering.rb +++ b/test/reline/yamatanooroti/test_rendering.rb @@ -767,6 +767,7 @@ def test_with_newline omit if Reline::IOGate.win? cmd = %Q{ruby -e 'print(%Q{abc def \\e\\r})' | ruby -I#{@pwd}/lib -rreline -e 'p Reline.readline(%{> })'} start_terminal(40, 50, ['bash', '-c', cmd]) + sleep 1 close assert_screen(<<~'EOC') > abc def @@ -1271,6 +1272,67 @@ def test_clear_dialog_when_just_move_cursor_at_last_line EOC end + def test_clear_dialog_when_adding_new_line_to_end_of_buffer + start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') + write("class A\n def a\n 3\n end\nend") + write("\n") + write("class S") + write("\n") + write(" 3") + close + assert_screen(<<~'EOC') + prompt> end + prompt> end + => :a + prompt> class S + prompt> 3 + EOC + end + + def test_insert_newline_in_the_middle_of_buffer_just_after_dialog + start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') + write("class A\n def a\n 3\n end\nend") + write("\n") + write("\C-p\C-p\C-p\C-p\C-p\C-e\C-hS") + write("\M-\x0D") + write(" 3") + close + assert_screen(<<~'EOC') + prompt> end + prompt> end + => :a + prompt> class S + prompt> 3 + prompt> def a + prompt> 3 + prompt> end + prompt> end + EOC + end + + def test_incremental_search_on_not_last_line + start_terminal(10, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') + write("def abc\nend\n") + write("def def\nend\n") + write("\C-p\C-p\C-e") + write("\C-r") + write("a") + write("\n\n") + close + assert_screen(<<~'EOC') + prompt> def abc + prompt> end + => :abc + prompt> def def + prompt> end + => :def + prompt> def abc + prompt> end + => :abc + prompt> + EOC + end + def write_inputrc(content) File.open(@inputrc_file, 'w') do |f| f.write content