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 [ 0, 41] => :ed_unassigned, # input method on/off [ 0, 72] => :ed_prev_history, # ↑ [ 0, 80] => :ed_next_history, # ↓ [ 0, 77] => :ed_next_char, # → [ 0, 75] => :ed_prev_char, # ← [ 0, 83] => :key_delete, # Del [ 0, 71] => :ed_move_to_beg, # Home [ 0, 79] => :ed_move_to_end # End }
- VK_MENU =
0x12
- VK_LMENU =
0xA4
- VK_CONTROL =
0x11
- VK_SHIFT =
0x10
- STD_INPUT_HANDLE =
-10
- STD_OUTPUT_HANDLE =
-11
- WINDOW_BUFFER_SIZE_EVENT =
0x04
- @@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)
- @@hConsoleInputHandle =
@@GetStdHandle.call(STD_INPUT_HANDLE)
- @@GetNumberOfConsoleInputEvents =
Win32API.new('kernel32', 'GetNumberOfConsoleInputEvents', ['L', 'P'], 'L')
- @@ReadConsoleInput =
Win32API.new('kernel32', 'ReadConsoleInput', ['L', 'P', 'L', 'P'], 'L')
- @@input_buf =
[]
- @@output_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
- .set_winch_handler(&handler) ⇒ Object
- .ungetc(c) ⇒ Object
Class Method Details
.clear_screen ⇒ Object
214 215 216 217 218 |
# File 'lib/reline/windows.rb', line 214 def self.clear_screen # TODO: Use FillConsoleOutputCharacter and FillConsoleOutputAttribute print "\e[2J" print "\e[1;1H" end |
.cursor_pos ⇒ Object
170 171 172 173 174 175 176 |
# File 'lib/reline/windows.rb', line 170 def self.cursor_pos csbi = 0.chr * 22 @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi) x = csbi[4, 2].unpack('s*').first y = csbi[6, 2].unpack('s*').first Reline::CursorPos.new(x, y) end |
.deprep(otio) ⇒ Object
233 234 235 |
# File 'lib/reline/windows.rb', line 233 def self.deprep(otio) # do nothing end |
.erase_after_cursor ⇒ Object
198 199 200 201 202 203 204 |
# File 'lib/reline/windows.rb', line 198 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
164 165 166 167 168 |
# File 'lib/reline/windows.rb', line 164 def self.get_screen_size csbi = 0.chr * 22 @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi) csbi[0, 4].unpack('SS').reverse end |
.getc ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/reline/windows.rb', line 112 def self.getc num_of_events = 0.chr * 8 while @@GetNumberOfConsoleInputEvents.(@@hConsoleInputHandle, num_of_events) != 0 and num_of_events.unpack('L').first > 0 input_record = 0.chr * 18 read_event = 0.chr * 4 if @@ReadConsoleInput.(@@hConsoleInputHandle, input_record, 1, read_event) != 0 event = input_record[0, 2].unpack('s*').first if event == WINDOW_BUFFER_SIZE_EVENT @@winch_handler.() end end end unless @@output_buf.empty? return @@output_buf.shift end input = getwch = (@@GetKeyState.call(VK_LMENU) & 0x80) != 0 control = (@@GetKeyState.call(VK_CONTROL) & 0x80) != 0 shift = (@@GetKeyState.call(VK_SHIFT) & 0x80) != 0 force_enter = !input.instance_of?(Array) && (control or shift) && input == 0x0D if force_enter # It's treated as Meta+Enter on Windows @@output_buf.push("\e".ord) @@output_buf.push(input) else case input when 0x00 = false @@output_buf.push(input) input = getwch @@output_buf.push(*input) when 0xE0 @@output_buf.push(input) input = getwch @@output_buf.push(*input) when 0x03 @@output_buf.push(input) else @@output_buf.push(input) end end if "\e".ord else @@output_buf.shift end end |
.getwch ⇒ Object
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 |
# File 'lib/reline/windows.rb', line 86 def self.getwch unless @@input_buf.empty? return @@input_buf.shift end while @@kbhit.call == 0 sleep(0.001) end until @@kbhit.call == 0 ret = @@getwch.call if ret == 0 or ret == 0xE0 @@input_buf << ret ret = @@getwch.call @@input_buf << ret return @@input_buf.shift end begin bytes = ret.chr(Encoding::UTF_8).encode(Encoding.default_external).bytes @@input_buf.push(*bytes) rescue Encoding::UndefinedConversionError @@input_buf << ret @@input_buf << @@getwch.call if ret == 224 end end @@input_buf.shift end |
.move_cursor_column(val) ⇒ Object
178 179 180 |
# File 'lib/reline/windows.rb', line 178 def self.move_cursor_column(val) @@SetConsoleCursorPosition.call(@@hConsoleHandle, cursor_pos.y * 65536 + val) end |
.move_cursor_down(val) ⇒ Object
190 191 192 193 194 195 196 |
# File 'lib/reline/windows.rb', line 190 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
182 183 184 185 186 187 188 |
# File 'lib/reline/windows.rb', line 182 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
228 229 230 231 |
# File 'lib/reline/windows.rb', line 228 def self.prep # do nothing nil end |
.scroll_down(val) ⇒ Object
206 207 208 209 210 211 212 |
# File 'lib/reline/windows.rb', line 206 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
220 221 222 |
# File 'lib/reline/windows.rb', line 220 def self.set_screen_size(rows, columns) raise NotImplementedError end |
.set_winch_handler(&handler) ⇒ Object
224 225 226 |
# File 'lib/reline/windows.rb', line 224 def self.set_winch_handler(&handler) @@winch_handler = handler end |
.ungetc(c) ⇒ Object
160 161 162 |
# File 'lib/reline/windows.rb', line 160 def self.ungetc(c) @@output_buf.unshift(c) end |