aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYO4 <ysno@ac.auone-net.jp>2021-12-17 18:22:59 +0900
committergit <svn-admin@ruby-lang.org>2021-12-20 14:51:52 +0900
commit2a8ff602e0a6302faef92d554fc809aef3b71212 (patch)
treee6a969ffce36656d6338bb357f72165eca6cc682
parent65cb250cb15f8b93cee8a1a7c1e8adb1b2e6e95e (diff)
downloadruby-2a8ff602e0a6302faef92d554fc809aef3b71212.tar.gz
[ruby/reline] windows jruby issue
jruby needs terminal control with Windows API on classic console https://github.com/ruby/reline/commit/b61bc43374
-rw-r--r--lib/reline/windows.rb60
1 files changed, 46 insertions, 14 deletions
diff --git a/lib/reline/windows.rb b/lib/reline/windows.rb
index 8710e6cb80..e7b8957115 100644
--- a/lib/reline/windows.rb
+++ b/lib/reline/windows.rb
@@ -315,6 +315,18 @@ class Reline::Windows
end
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
return if @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi) == 0
csbi
@@ -373,24 +385,44 @@ class Reline::Windows
def self.scroll_down(val)
return if val < 0
-
- csbi = 0.chr * 22
- @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi)
- x, y, left, top, screen_height = csbi.unpack 'x4ssx2ssx2s'
-
- origin_x = x - left + 1
- origin_y = y - top + 1
- screen_height += 1
+ return unless csbi = get_console_screen_buffer_info
+ buffer_width, x, y, buffer_lines, attributes, window_left, window_top, window_bottom = csbi.unpack('ssssSssx2s')
+ screen_height = window_bottom - window_top + 1
val = screen_height if val > screen_height
- @@output.write [
- (origin_y != screen_height) ? "\e[#{screen_height};H" : nil,
- "\n" * val,
- (origin_y != screen_height or !origin_x.zero?) ? "\e[#{origin_y};#{origin_x}H" : nil
- ].join
+
+ if @@legacy_console || window_left != 0
+ # unless ENABLE_VIRTUAL_TERMINAL,
+ # if srWindow.Left != 0 then it's conhost.exe hosted console
+ # 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
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
def self.set_screen_size(rows, columns)