1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

[ruby/reline] Simplify SIGWINCH handler to avoid aborting when resizing.

481add0537
This commit is contained in:
TOMITA Masahiro 2021-09-26 15:39:45 +09:00 committed by git
parent 2a3d0fbe17
commit ef350b3a56
2 changed files with 44 additions and 37 deletions

View file

@ -126,8 +126,8 @@ class Reline::ANSI
unless @@buf.empty?
return @@buf.shift
end
until c = @@input.raw(intr: true, &:getbyte)
sleep 0.1
until c = @@input.raw(intr: true) { select([@@input], [], [], 0.1) && @@input.getbyte }
Reline.core.line_editor.resize
end
(c == 0x16 && @@input.raw(min: 0, tim: 0, &:getbyte)) || c
rescue Errno::EIO

View file

@ -178,45 +178,51 @@ class Reline::LineEditor
rescue ArgumentError
end
Reline::IOGate.set_winch_handler do
@rest_height = (Reline::IOGate.get_screen_size.first - 1) - Reline::IOGate.cursor_pos.y
old_screen_size = @screen_size
@screen_size = Reline::IOGate.get_screen_size
@screen_height = @screen_size.first
if old_screen_size.last < @screen_size.last # columns increase
@rerender_all = true
rerender
else
back = 0
new_buffer = whole_lines
prompt, prompt_width, prompt_list = check_multiline_prompt(new_buffer, prompt)
new_buffer.each_with_index do |line, index|
prompt_width = calculate_width(prompt_list[index], true) if @prompt_proc
width = prompt_width + calculate_width(line)
height = calculate_height_by_width(width)
back += height
end
@highest_in_all = back
@highest_in_this = calculate_height_by_width(prompt_width + @cursor_max)
@first_line_started_from =
if @line_index.zero?
0
else
calculate_height_by_lines(@buffer_of_lines[0..(@line_index - 1)], prompt_list || prompt)
end
if @prompt_proc
prompt = prompt_list[@line_index]
prompt_width = calculate_width(prompt, true)
end
calculate_nearest_cursor
@started_from = calculate_height_by_width(prompt_width + @cursor) - 1
Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
@highest_in_this = calculate_height_by_width(prompt_width + @cursor_max)
@rerender_all = true
end
@resized = true
end
@block_elem_width = Reline::Unicode.calculate_width('█')
end
def resize
return unless @resized
@resized = false
@rest_height = (Reline::IOGate.get_screen_size.first - 1) - Reline::IOGate.cursor_pos.y
old_screen_size = @screen_size
@screen_size = Reline::IOGate.get_screen_size
@screen_height = @screen_size.first
if old_screen_size.last < @screen_size.last # columns increase
@rerender_all = true
rerender
else
back = 0
new_buffer = whole_lines
prompt, prompt_width, prompt_list = check_multiline_prompt(new_buffer, prompt)
new_buffer.each_with_index do |line, index|
prompt_width = calculate_width(prompt_list[index], true) if @prompt_proc
width = prompt_width + calculate_width(line)
height = calculate_height_by_width(width)
back += height
end
@highest_in_all = back
@highest_in_this = calculate_height_by_width(prompt_width + @cursor_max)
@first_line_started_from =
if @line_index.zero?
0
else
calculate_height_by_lines(@buffer_of_lines[0..(@line_index - 1)], prompt_list || prompt)
end
if @prompt_proc
prompt = prompt_list[@line_index]
prompt_width = calculate_width(prompt, true)
end
calculate_nearest_cursor
@started_from = calculate_height_by_width(prompt_width + @cursor) - 1
Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
@highest_in_this = calculate_height_by_width(prompt_width + @cursor_max)
@rerender_all = true
end
end
def finalize
Signal.trap('INT', @old_trap)
begin
@ -264,6 +270,7 @@ class Reline::LineEditor
@auto_indent_proc = nil
@dialogs = []
@last_key = nil
@resized = false
reset_line
end