reline 0.3.2 → 0.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|