reline 0.3.2 → 0.5.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +33 -2
- data/lib/reline/config.rb +58 -77
- data/lib/reline/face.rb +199 -0
- data/lib/reline/history.rb +1 -1
- data/lib/reline/io/ansi.rb +364 -0
- data/lib/reline/io/dumb.rb +106 -0
- data/lib/reline/{windows.rb → io/windows.rb} +108 -102
- data/lib/reline/io.rb +41 -0
- data/lib/reline/key_actor/base.rb +20 -8
- data/lib/reline/key_actor/composite.rb +17 -0
- data/lib/reline/key_actor/emacs.rb +15 -15
- data/lib/reline/key_actor/vi_command.rb +25 -25
- data/lib/reline/key_actor/vi_insert.rb +7 -7
- data/lib/reline/key_actor.rb +1 -0
- data/lib/reline/key_stroke.rb +88 -84
- data/lib/reline/kill_ring.rb +2 -2
- data/lib/reline/line_editor.rb +1095 -1895
- data/lib/reline/terminfo.rb +13 -29
- data/lib/reline/unicode/east_asian_width.rb +91 -59
- data/lib/reline/unicode.rb +95 -64
- data/lib/reline/version.rb +1 -1
- data/lib/reline.rb +156 -240
- metadata +13 -7
- data/lib/reline/ansi.rb +0 -350
- data/lib/reline/general_io.rb +0 -109
@@ -1,19 +1,49 @@
|
|
1
1
|
require 'fiddle/import'
|
2
2
|
|
3
|
-
class Reline::Windows
|
4
|
-
def
|
3
|
+
class Reline::Windows < Reline::IO
|
4
|
+
def initialize
|
5
|
+
@input_buf = []
|
6
|
+
@output_buf = []
|
7
|
+
|
8
|
+
@output = STDOUT
|
9
|
+
@hsg = nil
|
10
|
+
@getwch = Win32API.new('msvcrt', '_getwch', [], 'I')
|
11
|
+
@kbhit = Win32API.new('msvcrt', '_kbhit', [], 'I')
|
12
|
+
@GetKeyState = Win32API.new('user32', 'GetKeyState', ['L'], 'L')
|
13
|
+
@GetConsoleScreenBufferInfo = Win32API.new('kernel32', 'GetConsoleScreenBufferInfo', ['L', 'P'], 'L')
|
14
|
+
@SetConsoleCursorPosition = Win32API.new('kernel32', 'SetConsoleCursorPosition', ['L', 'L'], 'L')
|
15
|
+
@GetStdHandle = Win32API.new('kernel32', 'GetStdHandle', ['L'], 'L')
|
16
|
+
@FillConsoleOutputCharacter = Win32API.new('kernel32', 'FillConsoleOutputCharacter', ['L', 'L', 'L', 'L', 'P'], 'L')
|
17
|
+
@ScrollConsoleScreenBuffer = Win32API.new('kernel32', 'ScrollConsoleScreenBuffer', ['L', 'P', 'P', 'L', 'P'], 'L')
|
18
|
+
@hConsoleHandle = @GetStdHandle.call(STD_OUTPUT_HANDLE)
|
19
|
+
@hConsoleInputHandle = @GetStdHandle.call(STD_INPUT_HANDLE)
|
20
|
+
@GetNumberOfConsoleInputEvents = Win32API.new('kernel32', 'GetNumberOfConsoleInputEvents', ['L', 'P'], 'L')
|
21
|
+
@ReadConsoleInputW = Win32API.new('kernel32', 'ReadConsoleInputW', ['L', 'P', 'L', 'P'], 'L')
|
22
|
+
@GetFileType = Win32API.new('kernel32', 'GetFileType', ['L'], 'L')
|
23
|
+
@GetFileInformationByHandleEx = Win32API.new('kernel32', 'GetFileInformationByHandleEx', ['L', 'I', 'P', 'L'], 'I')
|
24
|
+
@FillConsoleOutputAttribute = Win32API.new('kernel32', 'FillConsoleOutputAttribute', ['L', 'L', 'L', 'L', 'P'], 'L')
|
25
|
+
@SetConsoleCursorInfo = Win32API.new('kernel32', 'SetConsoleCursorInfo', ['L', 'P'], 'L')
|
26
|
+
|
27
|
+
@GetConsoleMode = Win32API.new('kernel32', 'GetConsoleMode', ['L', 'P'], 'L')
|
28
|
+
@SetConsoleMode = Win32API.new('kernel32', 'SetConsoleMode', ['L', 'L'], 'L')
|
29
|
+
@WaitForSingleObject = Win32API.new('kernel32', 'WaitForSingleObject', ['L', 'L'], 'L')
|
30
|
+
|
31
|
+
@legacy_console = getconsolemode & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0
|
32
|
+
end
|
33
|
+
|
34
|
+
def encoding
|
5
35
|
Encoding::UTF_8
|
6
36
|
end
|
7
37
|
|
8
|
-
def
|
38
|
+
def win?
|
9
39
|
true
|
10
40
|
end
|
11
41
|
|
12
|
-
def
|
13
|
-
|
42
|
+
def win_legacy_console?
|
43
|
+
@legacy_console
|
14
44
|
end
|
15
45
|
|
16
|
-
def
|
46
|
+
def set_default_key_bindings(config)
|
17
47
|
{
|
18
48
|
[224, 72] => :ed_prev_history, # ↑
|
19
49
|
[224, 80] => :ed_next_history, # ↓
|
@@ -85,7 +115,7 @@ class Reline::Windows
|
|
85
115
|
def call(*args)
|
86
116
|
import = @proto.split("")
|
87
117
|
args.each_with_index do |x, i|
|
88
|
-
args[i], = [x == 0 ? nil : x].pack("p").unpack(POINTER_TYPE) if import[i] == "S"
|
118
|
+
args[i], = [x == 0 ? nil : +x].pack("p").unpack(POINTER_TYPE) if import[i] == "S"
|
89
119
|
args[i], = [x].pack("I").unpack("i") if import[i] == "I"
|
90
120
|
end
|
91
121
|
ret, = @func.call(*args)
|
@@ -127,58 +157,32 @@ class Reline::Windows
|
|
127
157
|
STD_OUTPUT_HANDLE = -11
|
128
158
|
FILE_TYPE_PIPE = 0x0003
|
129
159
|
FILE_NAME_INFO = 2
|
130
|
-
@@getwch = Win32API.new('msvcrt', '_getwch', [], 'I')
|
131
|
-
@@kbhit = Win32API.new('msvcrt', '_kbhit', [], 'I')
|
132
|
-
@@GetKeyState = Win32API.new('user32', 'GetKeyState', ['L'], 'L')
|
133
|
-
@@GetConsoleScreenBufferInfo = Win32API.new('kernel32', 'GetConsoleScreenBufferInfo', ['L', 'P'], 'L')
|
134
|
-
@@SetConsoleCursorPosition = Win32API.new('kernel32', 'SetConsoleCursorPosition', ['L', 'L'], 'L')
|
135
|
-
@@GetStdHandle = Win32API.new('kernel32', 'GetStdHandle', ['L'], 'L')
|
136
|
-
@@FillConsoleOutputCharacter = Win32API.new('kernel32', 'FillConsoleOutputCharacter', ['L', 'L', 'L', 'L', 'P'], 'L')
|
137
|
-
@@ScrollConsoleScreenBuffer = Win32API.new('kernel32', 'ScrollConsoleScreenBuffer', ['L', 'P', 'P', 'L', 'P'], 'L')
|
138
|
-
@@hConsoleHandle = @@GetStdHandle.call(STD_OUTPUT_HANDLE)
|
139
|
-
@@hConsoleInputHandle = @@GetStdHandle.call(STD_INPUT_HANDLE)
|
140
|
-
@@GetNumberOfConsoleInputEvents = Win32API.new('kernel32', 'GetNumberOfConsoleInputEvents', ['L', 'P'], 'L')
|
141
|
-
@@ReadConsoleInputW = Win32API.new('kernel32', 'ReadConsoleInputW', ['L', 'P', 'L', 'P'], 'L')
|
142
|
-
@@GetFileType = Win32API.new('kernel32', 'GetFileType', ['L'], 'L')
|
143
|
-
@@GetFileInformationByHandleEx = Win32API.new('kernel32', 'GetFileInformationByHandleEx', ['L', 'I', 'P', 'L'], 'I')
|
144
|
-
@@FillConsoleOutputAttribute = Win32API.new('kernel32', 'FillConsoleOutputAttribute', ['L', 'L', 'L', 'L', 'P'], 'L')
|
145
|
-
@@SetConsoleCursorInfo = Win32API.new('kernel32', 'SetConsoleCursorInfo', ['L', 'P'], 'L')
|
146
|
-
|
147
|
-
@@GetConsoleMode = Win32API.new('kernel32', 'GetConsoleMode', ['L', 'P'], 'L')
|
148
|
-
@@SetConsoleMode = Win32API.new('kernel32', 'SetConsoleMode', ['L', 'L'], 'L')
|
149
|
-
@@WaitForSingleObject = Win32API.new('kernel32', 'WaitForSingleObject', ['L', 'L'], 'L')
|
150
160
|
ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4
|
151
161
|
|
152
|
-
|
162
|
+
private def getconsolemode
|
153
163
|
mode = "\000\000\000\000"
|
154
|
-
|
164
|
+
@GetConsoleMode.call(@hConsoleHandle, mode)
|
155
165
|
mode.unpack1('L')
|
156
166
|
end
|
157
167
|
|
158
|
-
|
159
|
-
|
168
|
+
private def setconsolemode(mode)
|
169
|
+
@SetConsoleMode.call(@hConsoleHandle, mode)
|
160
170
|
end
|
161
171
|
|
162
|
-
|
163
|
-
#if @@legacy_console
|
172
|
+
#if @legacy_console
|
164
173
|
# setconsolemode(getconsolemode() | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
|
165
|
-
#
|
174
|
+
# @legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0)
|
166
175
|
#end
|
167
176
|
|
168
|
-
|
169
|
-
@@output_buf = []
|
170
|
-
|
171
|
-
@@output = STDOUT
|
172
|
-
|
173
|
-
def self.msys_tty?(io = @@hConsoleInputHandle)
|
177
|
+
def msys_tty?(io = @hConsoleInputHandle)
|
174
178
|
# check if fd is a pipe
|
175
|
-
if
|
179
|
+
if @GetFileType.call(io) != FILE_TYPE_PIPE
|
176
180
|
return false
|
177
181
|
end
|
178
182
|
|
179
183
|
bufsize = 1024
|
180
184
|
p_buffer = "\0" * bufsize
|
181
|
-
res =
|
185
|
+
res = @GetFileInformationByHandleEx.call(io, FILE_NAME_INFO, p_buffer, bufsize - 2)
|
182
186
|
return false if res == 0
|
183
187
|
|
184
188
|
# get pipe name: p_buffer layout is:
|
@@ -215,65 +219,63 @@ class Reline::Windows
|
|
215
219
|
[ { control_keys: :SHIFT, virtual_key_code: VK_TAB }, [27, 91, 90] ],
|
216
220
|
]
|
217
221
|
|
218
|
-
|
219
|
-
|
220
|
-
def self.process_key_event(repeat_count, virtual_key_code, virtual_scan_code, char_code, control_key_state)
|
222
|
+
def process_key_event(repeat_count, virtual_key_code, virtual_scan_code, char_code, control_key_state)
|
221
223
|
|
222
224
|
# high-surrogate
|
223
225
|
if 0xD800 <= char_code and char_code <= 0xDBFF
|
224
|
-
|
226
|
+
@hsg = char_code
|
225
227
|
return
|
226
228
|
end
|
227
229
|
# low-surrogate
|
228
230
|
if 0xDC00 <= char_code and char_code <= 0xDFFF
|
229
|
-
if
|
230
|
-
char_code = 0x10000 + (
|
231
|
-
|
231
|
+
if @hsg
|
232
|
+
char_code = 0x10000 + (@hsg - 0xD800) * 0x400 + char_code - 0xDC00
|
233
|
+
@hsg = nil
|
232
234
|
else
|
233
235
|
# no high-surrogate. ignored.
|
234
236
|
return
|
235
237
|
end
|
236
238
|
else
|
237
239
|
# ignore high-surrogate without low-surrogate if there
|
238
|
-
|
240
|
+
@hsg = nil
|
239
241
|
end
|
240
242
|
|
241
243
|
key = KeyEventRecord.new(virtual_key_code, char_code, control_key_state)
|
242
244
|
|
243
245
|
match = KEY_MAP.find { |args,| key.matches?(**args) }
|
244
246
|
unless match.nil?
|
245
|
-
|
247
|
+
@output_buf.concat(match.last)
|
246
248
|
return
|
247
249
|
end
|
248
250
|
|
249
251
|
# no char, only control keys
|
250
252
|
return if key.char_code == 0 and key.control_keys.any?
|
251
253
|
|
252
|
-
|
254
|
+
@output_buf.push("\e".ord) if key.control_keys.include?(:ALT) and !key.control_keys.include?(:CTRL)
|
253
255
|
|
254
|
-
|
256
|
+
@output_buf.concat(key.char.bytes)
|
255
257
|
end
|
256
258
|
|
257
|
-
def
|
259
|
+
def check_input_event
|
258
260
|
num_of_events = 0.chr * 8
|
259
|
-
while
|
260
|
-
Reline.core.line_editor.
|
261
|
-
if
|
261
|
+
while @output_buf.empty?
|
262
|
+
Reline.core.line_editor.handle_signal
|
263
|
+
if @WaitForSingleObject.(@hConsoleInputHandle, 100) != 0 # max 0.1 sec
|
262
264
|
# prevent for background consolemode change
|
263
|
-
|
265
|
+
@legacy_console = getconsolemode & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0
|
264
266
|
next
|
265
267
|
end
|
266
|
-
next if
|
268
|
+
next if @GetNumberOfConsoleInputEvents.(@hConsoleInputHandle, num_of_events) == 0 or num_of_events.unpack1('L') == 0
|
267
269
|
input_records = 0.chr * 20 * 80
|
268
270
|
read_event = 0.chr * 4
|
269
|
-
if
|
271
|
+
if @ReadConsoleInputW.(@hConsoleInputHandle, input_records, 80, read_event) != 0
|
270
272
|
read_events = read_event.unpack1('L')
|
271
273
|
0.upto(read_events) do |idx|
|
272
274
|
input_record = input_records[idx * 20, 20]
|
273
275
|
event = input_record[0, 2].unpack1('s*')
|
274
276
|
case event
|
275
277
|
when WINDOW_BUFFER_SIZE_EVENT
|
276
|
-
|
278
|
+
@winch_handler.()
|
277
279
|
when KEY_EVENT
|
278
280
|
key_down = input_record[4, 4].unpack1('l*')
|
279
281
|
repeat_count = input_record[8, 2].unpack1('s*')
|
@@ -291,30 +293,34 @@ class Reline::Windows
|
|
291
293
|
end
|
292
294
|
end
|
293
295
|
|
294
|
-
def
|
296
|
+
def with_raw_input
|
297
|
+
yield
|
298
|
+
end
|
299
|
+
|
300
|
+
def getc(_timeout_second)
|
295
301
|
check_input_event
|
296
|
-
|
302
|
+
@output_buf.shift
|
297
303
|
end
|
298
304
|
|
299
|
-
def
|
300
|
-
|
305
|
+
def ungetc(c)
|
306
|
+
@output_buf.unshift(c)
|
301
307
|
end
|
302
308
|
|
303
|
-
def
|
304
|
-
not
|
309
|
+
def in_pasting?
|
310
|
+
not empty_buffer?
|
305
311
|
end
|
306
312
|
|
307
|
-
def
|
308
|
-
if not
|
313
|
+
def empty_buffer?
|
314
|
+
if not @output_buf.empty?
|
309
315
|
false
|
310
|
-
elsif
|
316
|
+
elsif @kbhit.call == 0
|
311
317
|
true
|
312
318
|
else
|
313
319
|
false
|
314
320
|
end
|
315
321
|
end
|
316
322
|
|
317
|
-
def
|
323
|
+
def get_console_screen_buffer_info
|
318
324
|
# CONSOLE_SCREEN_BUFFER_INFO
|
319
325
|
# [ 0,2] dwSize.X
|
320
326
|
# [ 2,2] dwSize.Y
|
@@ -328,18 +334,18 @@ class Reline::Windows
|
|
328
334
|
# [18,2] dwMaximumWindowSize.X
|
329
335
|
# [20,2] dwMaximumWindowSize.Y
|
330
336
|
csbi = 0.chr * 22
|
331
|
-
return if
|
337
|
+
return if @GetConsoleScreenBufferInfo.call(@hConsoleHandle, csbi) == 0
|
332
338
|
csbi
|
333
339
|
end
|
334
340
|
|
335
|
-
def
|
341
|
+
def get_screen_size
|
336
342
|
unless csbi = get_console_screen_buffer_info
|
337
343
|
return [1, 1]
|
338
344
|
end
|
339
345
|
csbi[0, 4].unpack('SS').reverse
|
340
346
|
end
|
341
347
|
|
342
|
-
def
|
348
|
+
def cursor_pos
|
343
349
|
unless csbi = get_console_screen_buffer_info
|
344
350
|
return Reline::CursorPos.new(0, 0)
|
345
351
|
end
|
@@ -348,49 +354,49 @@ class Reline::Windows
|
|
348
354
|
Reline::CursorPos.new(x, y)
|
349
355
|
end
|
350
356
|
|
351
|
-
def
|
352
|
-
|
357
|
+
def move_cursor_column(val)
|
358
|
+
@SetConsoleCursorPosition.call(@hConsoleHandle, cursor_pos.y * 65536 + val)
|
353
359
|
end
|
354
360
|
|
355
|
-
def
|
361
|
+
def move_cursor_up(val)
|
356
362
|
if val > 0
|
357
363
|
y = cursor_pos.y - val
|
358
364
|
y = 0 if y < 0
|
359
|
-
|
365
|
+
@SetConsoleCursorPosition.call(@hConsoleHandle, y * 65536 + cursor_pos.x)
|
360
366
|
elsif val < 0
|
361
367
|
move_cursor_down(-val)
|
362
368
|
end
|
363
369
|
end
|
364
370
|
|
365
|
-
def
|
371
|
+
def move_cursor_down(val)
|
366
372
|
if val > 0
|
367
373
|
return unless csbi = get_console_screen_buffer_info
|
368
374
|
screen_height = get_screen_size.first
|
369
375
|
y = cursor_pos.y + val
|
370
376
|
y = screen_height - 1 if y > (screen_height - 1)
|
371
|
-
|
377
|
+
@SetConsoleCursorPosition.call(@hConsoleHandle, (cursor_pos.y + val) * 65536 + cursor_pos.x)
|
372
378
|
elsif val < 0
|
373
379
|
move_cursor_up(-val)
|
374
380
|
end
|
375
381
|
end
|
376
382
|
|
377
|
-
def
|
383
|
+
def erase_after_cursor
|
378
384
|
return unless csbi = get_console_screen_buffer_info
|
379
385
|
attributes = csbi[8, 2].unpack1('S')
|
380
386
|
cursor = csbi[4, 4].unpack1('L')
|
381
387
|
written = 0.chr * 4
|
382
|
-
|
383
|
-
|
388
|
+
@FillConsoleOutputCharacter.call(@hConsoleHandle, 0x20, get_screen_size.last - cursor_pos.x, cursor, written)
|
389
|
+
@FillConsoleOutputAttribute.call(@hConsoleHandle, attributes, get_screen_size.last - cursor_pos.x, cursor, written)
|
384
390
|
end
|
385
391
|
|
386
|
-
def
|
392
|
+
def scroll_down(val)
|
387
393
|
return if val < 0
|
388
394
|
return unless csbi = get_console_screen_buffer_info
|
389
395
|
buffer_width, buffer_lines, x, y, attributes, window_left, window_top, window_bottom = csbi.unpack('ssssSssx2s')
|
390
396
|
screen_height = window_bottom - window_top + 1
|
391
397
|
val = screen_height if val > screen_height
|
392
398
|
|
393
|
-
if
|
399
|
+
if @legacy_console || window_left != 0
|
394
400
|
# unless ENABLE_VIRTUAL_TERMINAL,
|
395
401
|
# if srWindow.Left != 0 then it's conhost.exe hosted console
|
396
402
|
# and puts "\n" causes horizontal scroll. its glitch.
|
@@ -398,11 +404,11 @@ class Reline::Windows
|
|
398
404
|
scroll_rectangle = [0, val, buffer_width, buffer_lines - val].pack('s4')
|
399
405
|
destination_origin = 0 # y * 65536 + x
|
400
406
|
fill = [' '.ord, attributes].pack('SS')
|
401
|
-
|
407
|
+
@ScrollConsoleScreenBuffer.call(@hConsoleHandle, scroll_rectangle, nil, destination_origin, fill)
|
402
408
|
else
|
403
409
|
origin_x = x + 1
|
404
410
|
origin_y = y - window_top + 1
|
405
|
-
|
411
|
+
@output.write [
|
406
412
|
(origin_y != screen_height) ? "\e[#{screen_height};H" : nil,
|
407
413
|
"\n" * val,
|
408
414
|
(origin_y != screen_height or !x.zero?) ? "\e[#{origin_y};#{origin_x}H" : nil
|
@@ -410,49 +416,49 @@ class Reline::Windows
|
|
410
416
|
end
|
411
417
|
end
|
412
418
|
|
413
|
-
def
|
414
|
-
if
|
419
|
+
def clear_screen
|
420
|
+
if @legacy_console
|
415
421
|
return unless csbi = get_console_screen_buffer_info
|
416
422
|
buffer_width, _buffer_lines, attributes, window_top, window_bottom = csbi.unpack('ss@8S@12sx2s')
|
417
423
|
fill_length = buffer_width * (window_bottom - window_top + 1)
|
418
424
|
screen_topleft = window_top * 65536
|
419
425
|
written = 0.chr * 4
|
420
|
-
|
421
|
-
|
422
|
-
|
426
|
+
@FillConsoleOutputCharacter.call(@hConsoleHandle, 0x20, fill_length, screen_topleft, written)
|
427
|
+
@FillConsoleOutputAttribute.call(@hConsoleHandle, attributes, fill_length, screen_topleft, written)
|
428
|
+
@SetConsoleCursorPosition.call(@hConsoleHandle, screen_topleft)
|
423
429
|
else
|
424
|
-
|
430
|
+
@output.write "\e[2J" "\e[H"
|
425
431
|
end
|
426
432
|
end
|
427
433
|
|
428
|
-
def
|
434
|
+
def set_screen_size(rows, columns)
|
429
435
|
raise NotImplementedError
|
430
436
|
end
|
431
437
|
|
432
|
-
def
|
438
|
+
def hide_cursor
|
433
439
|
size = 100
|
434
440
|
visible = 0 # 0 means false
|
435
441
|
cursor_info = [size, visible].pack('Li')
|
436
|
-
|
442
|
+
@SetConsoleCursorInfo.call(@hConsoleHandle, cursor_info)
|
437
443
|
end
|
438
444
|
|
439
|
-
def
|
445
|
+
def show_cursor
|
440
446
|
size = 100
|
441
447
|
visible = 1 # 1 means true
|
442
448
|
cursor_info = [size, visible].pack('Li')
|
443
|
-
|
449
|
+
@SetConsoleCursorInfo.call(@hConsoleHandle, cursor_info)
|
444
450
|
end
|
445
451
|
|
446
|
-
def
|
447
|
-
|
452
|
+
def set_winch_handler(&handler)
|
453
|
+
@winch_handler = handler
|
448
454
|
end
|
449
455
|
|
450
|
-
def
|
456
|
+
def prep
|
451
457
|
# do nothing
|
452
458
|
nil
|
453
459
|
end
|
454
460
|
|
455
|
-
def
|
461
|
+
def deprep(otio)
|
456
462
|
# do nothing
|
457
463
|
end
|
458
464
|
|
data/lib/reline/io.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
module Reline
|
3
|
+
class IO
|
4
|
+
RESET_COLOR = "\e[0m"
|
5
|
+
|
6
|
+
def self.decide_io_gate
|
7
|
+
if ENV['TERM'] == 'dumb'
|
8
|
+
Reline::Dumb.new
|
9
|
+
else
|
10
|
+
require 'reline/io/ansi'
|
11
|
+
|
12
|
+
case RbConfig::CONFIG['host_os']
|
13
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
14
|
+
require 'reline/io/windows'
|
15
|
+
io = Reline::Windows.new
|
16
|
+
if io.msys_tty?
|
17
|
+
Reline::ANSI.new
|
18
|
+
else
|
19
|
+
io
|
20
|
+
end
|
21
|
+
else
|
22
|
+
Reline::ANSI.new
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def dumb?
|
28
|
+
false
|
29
|
+
end
|
30
|
+
|
31
|
+
def win?
|
32
|
+
false
|
33
|
+
end
|
34
|
+
|
35
|
+
def reset_color_sequence
|
36
|
+
self.class::RESET_COLOR
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
require 'reline/io/dumb'
|
@@ -1,19 +1,31 @@
|
|
1
1
|
class Reline::KeyActor::Base
|
2
|
-
|
2
|
+
def initialize(mapping = [])
|
3
|
+
@mapping = mapping
|
4
|
+
@matching_bytes = {}
|
5
|
+
@key_bindings = {}
|
6
|
+
end
|
3
7
|
|
4
8
|
def get_method(key)
|
5
|
-
|
9
|
+
@mapping[key]
|
10
|
+
end
|
11
|
+
|
12
|
+
def add(key, func)
|
13
|
+
(1...key.size).each do |size|
|
14
|
+
@matching_bytes[key.take(size)] = true
|
15
|
+
end
|
16
|
+
@key_bindings[key] = func
|
6
17
|
end
|
7
18
|
|
8
|
-
def
|
9
|
-
@
|
19
|
+
def matching?(key)
|
20
|
+
@matching_bytes[key]
|
10
21
|
end
|
11
22
|
|
12
|
-
def
|
13
|
-
@
|
23
|
+
def get(key)
|
24
|
+
@key_bindings[key]
|
14
25
|
end
|
15
26
|
|
16
|
-
def
|
17
|
-
@
|
27
|
+
def clear
|
28
|
+
@matching_bytes.clear
|
29
|
+
@key_bindings.clear
|
18
30
|
end
|
19
31
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Reline::KeyActor::Composite
|
2
|
+
def initialize(key_actors)
|
3
|
+
@key_actors = key_actors
|
4
|
+
end
|
5
|
+
|
6
|
+
def matching?(key)
|
7
|
+
@key_actors.any? { |key_actor| key_actor.matching?(key) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def get(key)
|
11
|
+
@key_actors.each do |key_actor|
|
12
|
+
func = key_actor.get(key)
|
13
|
+
return func if func
|
14
|
+
end
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Reline::KeyActor
|
2
|
+
EMACS_MAPPING = [
|
3
3
|
# 0 ^@
|
4
4
|
:em_set_mark,
|
5
5
|
# 1 ^A
|
@@ -19,7 +19,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|
19
19
|
# 8 ^H
|
20
20
|
:em_delete_prev_char,
|
21
21
|
# 9 ^I
|
22
|
-
:
|
22
|
+
:complete,
|
23
23
|
# 10 ^J
|
24
24
|
:ed_newline,
|
25
25
|
# 11 ^K
|
@@ -49,13 +49,13 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|
49
49
|
# 23 ^W
|
50
50
|
:em_kill_region,
|
51
51
|
# 24 ^X
|
52
|
-
:
|
52
|
+
:ed_unassigned,
|
53
53
|
# 25 ^Y
|
54
54
|
:em_yank,
|
55
55
|
# 26 ^Z
|
56
56
|
:ed_ignore,
|
57
57
|
# 27 ^[
|
58
|
-
:
|
58
|
+
:ed_unassigned,
|
59
59
|
# 28 ^\
|
60
60
|
:ed_ignore,
|
61
61
|
# 29 ^]
|
@@ -63,7 +63,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|
63
63
|
# 30 ^^
|
64
64
|
:ed_unassigned,
|
65
65
|
# 31 ^_
|
66
|
-
:
|
66
|
+
:undo,
|
67
67
|
# 32 SPACE
|
68
68
|
:ed_insert,
|
69
69
|
# 33 !
|
@@ -319,9 +319,9 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|
319
319
|
# 158 M-^^
|
320
320
|
:ed_unassigned,
|
321
321
|
# 159 M-^_
|
322
|
-
:
|
322
|
+
:redo,
|
323
323
|
# 160 M-SPACE
|
324
|
-
:
|
324
|
+
:em_set_mark,
|
325
325
|
# 161 M-!
|
326
326
|
:ed_unassigned,
|
327
327
|
# 162 M-"
|
@@ -415,7 +415,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|
415
415
|
# 206 M-N
|
416
416
|
:vi_search_next,
|
417
417
|
# 207 M-O
|
418
|
-
:
|
418
|
+
:ed_unassigned,
|
419
419
|
# 208 M-P
|
420
420
|
:vi_search_prev,
|
421
421
|
# 209 M-Q
|
@@ -431,15 +431,15 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|
431
431
|
# 214 M-V
|
432
432
|
:ed_unassigned,
|
433
433
|
# 215 M-W
|
434
|
-
:
|
434
|
+
:ed_unassigned,
|
435
435
|
# 216 M-X
|
436
|
-
:ed_command,
|
437
|
-
# 217 M-Y
|
438
436
|
:ed_unassigned,
|
437
|
+
# 217 M-Y
|
438
|
+
:em_yank_pop,
|
439
439
|
# 218 M-Z
|
440
440
|
:ed_unassigned,
|
441
441
|
# 219 M-[
|
442
|
-
:
|
442
|
+
:ed_unassigned,
|
443
443
|
# 220 M-\
|
444
444
|
:ed_unassigned,
|
445
445
|
# 221 M-]
|
@@ -495,9 +495,9 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|
495
495
|
# 246 M-v
|
496
496
|
:ed_unassigned,
|
497
497
|
# 247 M-w
|
498
|
-
:
|
498
|
+
:ed_unassigned,
|
499
499
|
# 248 M-x
|
500
|
-
:
|
500
|
+
:ed_unassigned,
|
501
501
|
# 249 M-y
|
502
502
|
:ed_unassigned,
|
503
503
|
# 250 M-z
|