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

[ruby/reline] windows jruby issue

jruby needs terminal control with Windows API  on classic console

https://github.com/ruby/reline/commit/b61bc43374
This commit is contained in:
YO4 2021-12-17 18:22:59 +09:00 committed by git
parent 65cb250cb1
commit 2a8ff602e0

View file

@ -315,6 +315,18 @@ class Reline::Windows
end end
def self.get_console_screen_buffer_info def self.get_console_screen_buffer_info
# CONSOLE_SCREEN_BUFFER_INFO
# [ 0,2] dwSize.X
# [ 2,2] dwSize.Y
# [ 4,2] dwCursorPositions.X
# [ 6,2] dwCursorPositions.Y
# [ 8,2] wAttributes
# [10,2] srWindow.Left
# [12,2] srWindow.Top
# [14,2] srWindow.Right
# [16,2] srWindow.Bottom
# [18,2] dwMaximumWindowSize.X
# [20,2] dwMaximumWindowSize.Y
csbi = 0.chr * 22 csbi = 0.chr * 22
return if @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi) == 0 return if @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi) == 0
csbi csbi
@ -373,24 +385,44 @@ class Reline::Windows
def self.scroll_down(val) def self.scroll_down(val)
return if val < 0 return if val < 0
return unless csbi = get_console_screen_buffer_info
csbi = 0.chr * 22 buffer_width, x, y, buffer_lines, attributes, window_left, window_top, window_bottom = csbi.unpack('ssssSssx2s')
@@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi) screen_height = window_bottom - window_top + 1
x, y, left, top, screen_height = csbi.unpack 'x4ssx2ssx2s'
origin_x = x - left + 1
origin_y = y - top + 1
screen_height += 1
val = screen_height if val > screen_height val = screen_height if val > screen_height
@@output.write [
(origin_y != screen_height) ? "\e[#{screen_height};H" : nil, if @@legacy_console || window_left != 0
"\n" * val, # unless ENABLE_VIRTUAL_TERMINAL,
(origin_y != screen_height or !origin_x.zero?) ? "\e[#{origin_y};#{origin_x}H" : nil # if srWindow.Left != 0 then it's conhost.exe hosted console
].join # and puts "\n" causes horizontal scroll. its glitch.
# FYI irb write from culumn 1, so this gives no gain.
scroll_rectangle = [0, val, buffer_width, buffer_lines - val].pack('s4')
destination_origin = 0 # y * 65536 + x
fill = [' '.ord, attributes].pack('SS')
@@ScrollConsoleScreenBuffer.call(@@hConsoleHandle, scroll_rectangle, nil, destination_origin, fill)
else
origin_x = x + 1
origin_y = y - window_top + 1
@@output.write [
(origin_y != screen_height) ? "\e[#{screen_height};H" : nil,
"\n" * val,
(origin_y != screen_height or !x.zero?) ? "\e[#{origin_y};#{origin_x}H" : nil
].join
end
end end
def self.clear_screen def self.clear_screen
@@output.write "\e[2J" "\e[H" if @@legacy_console
return unless csbi = get_console_screen_buffer_info
buffer_width, buffer_lines, attributes, window_top, window_bottom = csbi.unpack('ss@8S@12sx2s')
fill_length = buffer_width * (window_bottom - window_top + 1)
screen_topleft = window_top * 65536
written = 0.chr * 4
@@FillConsoleOutputCharacter.call(@@hConsoleHandle, 0x20, fill_length, screen_topleft, written)
@@FillConsoleOutputAttribute.call(@@hConsoleHandle, attributes, fill_length, screen_topleft, written)
@@SetConsoleCursorPosition.call(@@hConsoleHandle, screen_topleft)
else
@@output.write "\e[2J" "\e[H"
end
end end
def self.set_screen_size(rows, columns) def self.set_screen_size(rows, columns)