Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix redisplay/insert_text called from pre_input_hook #742

Merged
merged 2 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions lib/reline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -324,14 +324,17 @@ def readline(prompt = '', add_hist = false)
line_editor.prompt_proc = prompt_proc
line_editor.auto_indent_proc = auto_indent_proc
line_editor.dig_perfect_match_proc = dig_perfect_match_proc

# Readline calls pre_input_hook just after printing the first prompt.
line_editor.print_nomultiline_prompt
pre_input_hook&.call

unless Reline::IOGate.dumb?
@dialog_proc_list.each_pair do |name_sym, d|
line_editor.add_dialog_proc(name_sym, d.dialog_proc, d.context)
end
end

line_editor.print_nomultiline_prompt
line_editor.update_dialogs
line_editor.rerender

Expand All @@ -343,7 +346,7 @@ def readline(prompt = '', add_hist = false)
inputs.each do |key|
if key.char == :bracketed_paste_start
text = io_gate.read_bracketed_paste
line_editor.insert_pasted_text(text)
line_editor.insert_multiline_text(text)
line_editor.scroll_into_view
else
line_editor.update(key)
Expand Down Expand Up @@ -457,8 +460,8 @@ def ambiguous_width
def_single_delegator :line_editor, :byte_pointer, :point
def_single_delegator :line_editor, :byte_pointer=, :point=

def self.insert_text(*args, &block)
line_editor.insert_text(*args, &block)
def self.insert_text(text)
line_editor.insert_multiline_text(text)
self
end

Expand Down
2 changes: 1 addition & 1 deletion lib/reline/line_editor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1333,7 +1333,7 @@ def confirm_multiline_termination
@confirm_multiline_termination_proc.(temp_buffer.join("\n") + "\n")
end

def insert_pasted_text(text)
def insert_multiline_text(text)
save_old_buffer
pre = @buffer_of_lines[@line_index].byteslice(0, @byte_pointer)
post = @buffer_of_lines[@line_index].byteslice(@byte_pointer..)
Expand Down
34 changes: 34 additions & 0 deletions test/reline/yamatanooroti/test_rendering.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1841,6 +1841,40 @@ def test_print_before_readline
EOC
end

def test_pre_input_hook_with_redisplay
code = <<~'RUBY'
puts 'Multiline REPL.'
Reline.pre_input_hook = -> do
Reline.insert_text 'abc'
Reline.redisplay # Reline doesn't need this but Readline requires calling redisplay
end
Reline.readline('prompt> ')
RUBY
start_terminal(6, 30, ['ruby', "-I#{@pwd}/lib", '-rreline', '-e', code], startup_message: 'Multiline REPL.')
assert_screen(<<~EOC)
Multiline REPL.
prompt> abc
EOC
end

def test_pre_input_hook_with_multiline_text_insert
# Frequently used pattern of pre_input_hook
code = <<~'RUBY'
puts 'Multiline REPL.'
Reline.pre_input_hook = -> do
Reline.insert_text "abc\nef"
end
Reline.readline('>')
RUBY
start_terminal(6, 30, ['ruby', "-I#{@pwd}/lib", '-rreline', '-e', code], startup_message: 'Multiline REPL.')
write("\C-ad")
assert_screen(<<~EOC)
Multiline REPL.
>abc
def
EOC
end

def test_thread_safe
start_terminal(6, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
write("[Thread.new{Reline.readline'>'},Thread.new{Reline.readmultiline('>'){true}}].map(&:join).size\n")
Expand Down
Loading