Class: Reline::Windows
- Inherits:
-
Object
- Object
- Reline::Windows
- Defined in:
- lib/reline/windows.rb
Defined Under Namespace
Classes: Win32API
Constant Summary collapse
- RAW_KEYSTROKE_CONFIG =
{ [224, 72] => :ed_prev_history, # ↑ [224, 80] => :ed_next_history, # ↓ [224, 77] => :ed_next_char, # → [224, 75] => :ed_prev_char, # ← [224, 83] => :key_delete, # Del [224, 71] => :ed_move_to_beg, # Home [224, 79] => :ed_move_to_end, # End }.each_key(&:freeze).freeze
- VK_MENU =
0x12- VK_SHIFT =
0x10- STD_OUTPUT_HANDLE =
-11
- @@getwch =
Win32API.new('msvcrt', '_getwch', [], 'I')
- @@kbhit =
Win32API.new('msvcrt', '_kbhit', [], 'I')
- @@GetKeyState =
Win32API.new('user32', 'GetKeyState', ['L'], 'L')
- @@GetConsoleScreenBufferInfo =
Win32API.new('kernel32', 'GetConsoleScreenBufferInfo', ['L', 'P'], 'L')
- @@SetConsoleCursorPosition =
Win32API.new('kernel32', 'SetConsoleCursorPosition', ['L', 'L'], 'L')
- @@GetStdHandle =
Win32API.new('kernel32', 'GetStdHandle', ['L'], 'L')
- @@FillConsoleOutputCharacter =
Win32API.new('kernel32', 'FillConsoleOutputCharacter', ['L', 'L', 'L', 'L', 'P'], 'L')
- @@ScrollConsoleScreenBuffer =
Win32API.new('kernel32', 'ScrollConsoleScreenBuffer', ['L', 'P', 'P', 'L', 'P'], 'L')
- @@hConsoleHandle =
@@GetStdHandle.call(STD_OUTPUT_HANDLE)
- @@buf =
[]
Class Method Summary collapse
- .clear_screen ⇒ Object
- .cursor_pos ⇒ Object
- .deprep(otio) ⇒ Object
- .erase_after_cursor ⇒ Object
- .get_screen_size ⇒ Object
- .getc ⇒ Object
- .getwch ⇒ Object
- .move_cursor_column(val) ⇒ Object
- .move_cursor_down(val) ⇒ Object
- .move_cursor_up(val) ⇒ Object
- .prep ⇒ Object
- .scroll_down(val) ⇒ Object
- .set_screen_size(rows, columns) ⇒ Object
- .ungetc(c) ⇒ Object
Class Method Details
.clear_screen ⇒ Object
174 175 176 177 178 |
# File 'lib/reline/windows.rb', line 174 def self.clear_screen # TODO: Use FillConsoleOutputCharacter and FillConsoleOutputAttribute print "\e[2J" print "\e[1;1H" end |
.cursor_pos ⇒ Object
130 131 132 133 134 135 136 |
# File 'lib/reline/windows.rb', line 130 def self.cursor_pos csbi = 0.chr * 24 @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi) x = csbi[4, 2].unpack('s*').first y = csbi[6, 4].unpack('s*').first Reline::CursorPos.new(x, y) end |
.deprep(otio) ⇒ Object
189 190 191 |
# File 'lib/reline/windows.rb', line 189 def self.deprep(otio) # do nothing end |
.erase_after_cursor ⇒ Object
158 159 160 161 162 163 164 |
# File 'lib/reline/windows.rb', line 158 def self.erase_after_cursor csbi = 0.chr * 24 @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi) cursor = csbi[4, 4].unpack('L').first written = 0.chr * 4 @@FillConsoleOutputCharacter.call(@@hConsoleHandle, 0x20, get_screen_size.last - cursor_pos.x, cursor, written) end |
.get_screen_size ⇒ Object
124 125 126 127 128 |
# File 'lib/reline/windows.rb', line 124 def self.get_screen_size csbi = 0.chr * 24 @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi) csbi[0, 4].unpack('SS').reverse end |
.getc ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/reline/windows.rb', line 83 def self.getc unless @@buf.empty? return @@buf.shift end input = getwch alt = (@@GetKeyState.call(VK_MENU) & 0x80) != 0 shift_enter = (@@GetKeyState.call(VK_SHIFT) & 0x80) != 0 && input.first == 0x0D if shift_enter # It's treated as Meta+Enter on Windows @@buf.concat(["\e".ord]) @@buf.concat(input) elsif input.size > 1 @@buf.concat(input) else # single byte case input[0] when 0x00 getwch alt = false input = getwch @@buf.concat(input) when 0xE0 @@buf.concat(input) input = getwch @@buf.concat(input) when 0x03 @@buf.concat(input) else @@buf.concat(input) end end if alt "\e".ord else @@buf.shift end end |
.getwch ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/reline/windows.rb', line 66 def self.getwch while @@kbhit.call == 0 sleep(0.001) end result = [] until @@kbhit.call == 0 ret = @@getwch.call begin result.concat(ret.chr(Encoding::UTF_8).encode(Encoding.default_external).bytes) rescue Encoding::UndefinedConversionError result << ret result << @@getwch.call if ret == 224 end end result end |
.move_cursor_column(val) ⇒ Object
138 139 140 |
# File 'lib/reline/windows.rb', line 138 def self.move_cursor_column(val) @@SetConsoleCursorPosition.call(@@hConsoleHandle, cursor_pos.y * 65536 + val) end |
.move_cursor_down(val) ⇒ Object
150 151 152 153 154 155 156 |
# File 'lib/reline/windows.rb', line 150 def self.move_cursor_down(val) if val > 0 @@SetConsoleCursorPosition.call(@@hConsoleHandle, (cursor_pos.y + val) * 65536 + cursor_pos.x) elsif val < 0 move_cursor_up(-val) end end |
.move_cursor_up(val) ⇒ Object
142 143 144 145 146 147 148 |
# File 'lib/reline/windows.rb', line 142 def self.move_cursor_up(val) if val > 0 @@SetConsoleCursorPosition.call(@@hConsoleHandle, (cursor_pos.y - val) * 65536 + cursor_pos.x) elsif val < 0 move_cursor_down(-val) end end |
.prep ⇒ Object
184 185 186 187 |
# File 'lib/reline/windows.rb', line 184 def self.prep # do nothing nil end |
.scroll_down(val) ⇒ Object
166 167 168 169 170 171 172 |
# File 'lib/reline/windows.rb', line 166 def self.scroll_down(val) return if val.zero? scroll_rectangle = [0, val, get_screen_size.first, get_screen_size.last].pack('s4') destination_origin = 0 # y * 65536 + x fill = [' '.ord, 0].pack('SS') @@ScrollConsoleScreenBuffer.call(@@hConsoleHandle, scroll_rectangle, nil, destination_origin, fill) end |
.set_screen_size(rows, columns) ⇒ Object
180 181 182 |
# File 'lib/reline/windows.rb', line 180 def self.set_screen_size(rows, columns) raise NotImplementedError end |
.ungetc(c) ⇒ Object
120 121 122 |
# File 'lib/reline/windows.rb', line 120 def self.ungetc(c) @@buf.unshift(c) end |