зеркало из https://github.com/github/ruby.git
[ruby/reline] Handle INT signal correctly, remove handle_cleared
because clear(C-l) is not a signal (https://github.com/ruby/reline/pull/646) https://github.com/ruby/reline/commit/3debb0ae2f
This commit is contained in:
Родитель
80e31663f3
Коммит
8088c88d01
|
@ -254,12 +254,14 @@ module Reline
|
|||
Reline::DEFAULT_DIALOG_CONTEXT = Array.new
|
||||
|
||||
def readmultiline(prompt = '', add_hist = false, &confirm_multiline_termination)
|
||||
Reline.update_iogate
|
||||
io_gate.with_raw_input do
|
||||
unless confirm_multiline_termination
|
||||
raise ArgumentError.new('#readmultiline needs block to confirm multiline termination')
|
||||
end
|
||||
|
||||
Reline.update_iogate
|
||||
io_gate.with_raw_input do
|
||||
inner_readline(prompt, add_hist, true, &confirm_multiline_termination)
|
||||
end
|
||||
|
||||
whole_buffer = line_editor.whole_buffer.dup
|
||||
whole_buffer.taint if RUBY_VERSION < '2.7'
|
||||
|
@ -275,11 +277,12 @@ module Reline
|
|||
whole_buffer
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def readline(prompt = '', add_hist = false)
|
||||
Reline.update_iogate
|
||||
io_gate.with_raw_input do
|
||||
inner_readline(prompt, add_hist, false)
|
||||
end
|
||||
|
||||
line = line_editor.line.dup
|
||||
line.taint if RUBY_VERSION < '2.7'
|
||||
|
|
|
@ -151,7 +151,11 @@ class Reline::ANSI
|
|||
end
|
||||
|
||||
def self.with_raw_input
|
||||
@@input.raw { yield }
|
||||
if @@input.tty?
|
||||
@@input.raw(intr: true) { yield }
|
||||
else
|
||||
yield
|
||||
end
|
||||
end
|
||||
|
||||
@@buf = []
|
||||
|
@ -159,11 +163,13 @@ class Reline::ANSI
|
|||
unless @@buf.empty?
|
||||
return @@buf.shift
|
||||
end
|
||||
until c = @@input.raw(intr: true) { @@input.wait_readable(0.1) && @@input.getbyte }
|
||||
timeout_second -= 0.1
|
||||
until @@input.wait_readable(0.01)
|
||||
timeout_second -= 0.01
|
||||
return nil if timeout_second <= 0
|
||||
Reline.core.line_editor.resize
|
||||
|
||||
Reline.core.line_editor.handle_signal
|
||||
end
|
||||
c = @@input.getbyte
|
||||
(c == 0x16 && @@input.raw(min: 0, time: 0, &:getbyte)) || c
|
||||
rescue Errno::EIO
|
||||
# Maybe the I/O has been closed.
|
||||
|
|
|
@ -46,6 +46,7 @@ class Reline::GeneralIO
|
|||
end
|
||||
c = nil
|
||||
loop do
|
||||
Reline.core.line_editor.handle_signal
|
||||
result = @@input.wait_readable(0.1)
|
||||
next if result.nil?
|
||||
c = @@input.read(1)
|
||||
|
|
|
@ -138,9 +138,6 @@ class Reline::LineEditor
|
|||
@screen_size = Reline::IOGate.get_screen_size
|
||||
reset_variables(prompt, encoding: encoding)
|
||||
@rendered_screen.base_y = Reline::IOGate.cursor_pos.y
|
||||
Reline::IOGate.set_winch_handler do
|
||||
@resized = true
|
||||
end
|
||||
if ENV.key?('RELINE_ALT_SCROLLBAR')
|
||||
@full_block = '::'
|
||||
@upper_half_block = "''"
|
||||
|
@ -164,7 +161,12 @@ class Reline::LineEditor
|
|||
end
|
||||
end
|
||||
|
||||
def resize
|
||||
def handle_signal
|
||||
handle_interrupted
|
||||
handle_resized
|
||||
end
|
||||
|
||||
private def handle_resized
|
||||
return unless @resized
|
||||
|
||||
@screen_size = Reline::IOGate.get_screen_size
|
||||
|
@ -177,8 +179,10 @@ class Reline::LineEditor
|
|||
render_differential
|
||||
end
|
||||
|
||||
def set_signal_handlers
|
||||
@old_trap = Signal.trap('INT') {
|
||||
private def handle_interrupted
|
||||
return unless @interrupted
|
||||
|
||||
@interrupted = false
|
||||
clear_dialogs
|
||||
scrolldown = render_differential
|
||||
Reline::IOGate.scroll_down scrolldown
|
||||
|
@ -195,7 +199,15 @@ class Reline::LineEditor
|
|||
else
|
||||
@old_trap.call if @old_trap.respond_to?(:call)
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
def set_signal_handlers
|
||||
Reline::IOGate.set_winch_handler do
|
||||
@resized = true
|
||||
end
|
||||
@old_trap = Signal.trap('INT') do
|
||||
@interrupted = true
|
||||
end
|
||||
end
|
||||
|
||||
def finalize
|
||||
|
@ -212,7 +224,6 @@ class Reline::LineEditor
|
|||
@encoding = encoding
|
||||
@is_multiline = false
|
||||
@finished = false
|
||||
@cleared = false
|
||||
@history_pointer = nil
|
||||
@kill_ring ||= Reline::KillRing.new
|
||||
@vi_clipboard = ''
|
||||
|
@ -234,6 +245,7 @@ class Reline::LineEditor
|
|||
@in_pasting = false
|
||||
@auto_indent_proc = nil
|
||||
@dialogs = []
|
||||
@interrupted = false
|
||||
@resized = false
|
||||
@cache = {}
|
||||
@rendered_screen = RenderedScreen.new(base_y: 0, lines: [], cursor_y: 0)
|
||||
|
@ -541,19 +553,7 @@ class Reline::LineEditor
|
|||
screen_height - wrapped_cursor_y + screen_scroll_top - @rendered_screen.base_y - 1
|
||||
end
|
||||
|
||||
def handle_cleared
|
||||
return unless @cleared
|
||||
|
||||
@cleared = false
|
||||
Reline::IOGate.clear_screen
|
||||
@screen_size = Reline::IOGate.get_screen_size
|
||||
@rendered_screen.lines = []
|
||||
@rendered_screen.base_y = 0
|
||||
@rendered_screen.cursor_y = 0
|
||||
end
|
||||
|
||||
def rerender
|
||||
handle_cleared
|
||||
render_differential unless @in_pasting
|
||||
end
|
||||
|
||||
|
@ -2074,7 +2074,11 @@ class Reline::LineEditor
|
|||
alias_method :yank_pop, :em_yank_pop
|
||||
|
||||
private def ed_clear_screen(key)
|
||||
@cleared = true
|
||||
Reline::IOGate.clear_screen
|
||||
@screen_size = Reline::IOGate.get_screen_size
|
||||
@rendered_screen.lines = []
|
||||
@rendered_screen.base_y = 0
|
||||
@rendered_screen.cursor_y = 0
|
||||
end
|
||||
alias_method :clear_screen, :ed_clear_screen
|
||||
|
||||
|
|
|
@ -259,7 +259,7 @@ class Reline::Windows
|
|||
def self.check_input_event
|
||||
num_of_events = 0.chr * 8
|
||||
while @@output_buf.empty?
|
||||
Reline.core.line_editor.resize
|
||||
Reline.core.line_editor.handle_signal
|
||||
if @@WaitForSingleObject.(@@hConsoleInputHandle, 100) != 0 # max 0.1 sec
|
||||
# prevent for background consolemode change
|
||||
@@legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0)
|
||||
|
|
|
@ -255,18 +255,18 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
|
|||
end
|
||||
|
||||
def test_ed_clear_screen
|
||||
refute(@line_editor.instance_variable_get(:@cleared))
|
||||
@line_editor.instance_variable_get(:@rendered_screen).lines = [[]]
|
||||
input_keys("\C-l", false)
|
||||
assert(@line_editor.instance_variable_get(:@cleared))
|
||||
assert_empty(@line_editor.instance_variable_get(:@rendered_screen).lines)
|
||||
end
|
||||
|
||||
def test_ed_clear_screen_with_inputed
|
||||
input_keys('abc')
|
||||
input_keys("\C-b", false)
|
||||
refute(@line_editor.instance_variable_get(:@cleared))
|
||||
@line_editor.instance_variable_get(:@rendered_screen).lines = [[]]
|
||||
assert_line_around_cursor('ab', 'c')
|
||||
input_keys("\C-l", false)
|
||||
assert(@line_editor.instance_variable_get(:@cleared))
|
||||
assert_empty(@line_editor.instance_variable_get(:@rendered_screen).lines)
|
||||
assert_line_around_cursor('ab', 'c')
|
||||
end
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче