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.
@@ -1,19 +1,49 @@
1
1
  require 'fiddle/import'
2
2
 
3
- class Reline::Windows
4
- def self.encoding
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 self.win?
38
+ def win?
9
39
  true
10
40
  end
11
41
 
12
- def self.win_legacy_console?
13
- @@legacy_console
42
+ def win_legacy_console?
43
+ @legacy_console
14
44
  end
15
45
 
16
- def self.set_default_key_bindings(config)
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
- private_class_method def self.getconsolemode
162
+ private def getconsolemode
153
163
  mode = "\000\000\000\000"
154
- @@GetConsoleMode.call(@@hConsoleHandle, mode)
164
+ @GetConsoleMode.call(@hConsoleHandle, mode)
155
165
  mode.unpack1('L')
156
166
  end
157
167
 
158
- private_class_method def self.setconsolemode(mode)
159
- @@SetConsoleMode.call(@@hConsoleHandle, mode)
168
+ private def setconsolemode(mode)
169
+ @SetConsoleMode.call(@hConsoleHandle, mode)
160
170
  end
161
171
 
162
- @@legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0)
163
- #if @@legacy_console
172
+ #if @legacy_console
164
173
  # setconsolemode(getconsolemode() | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
165
- # @@legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0)
174
+ # @legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0)
166
175
  #end
167
176
 
168
- @@input_buf = []
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 @@GetFileType.call(io) != FILE_TYPE_PIPE
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 = @@GetFileInformationByHandleEx.call(io, FILE_NAME_INFO, p_buffer, bufsize - 2)
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
- @@hsg = nil
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
- @@hsg = char_code
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 @@hsg
230
- char_code = 0x10000 + (@@hsg - 0xD800) * 0x400 + char_code - 0xDC00
231
- @@hsg = nil
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
- @@hsg = nil
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
- @@output_buf.concat(match.last)
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
- @@output_buf.push("\e".ord) if key.control_keys.include?(:ALT) and !key.control_keys.include?(:CTRL)
254
+ @output_buf.push("\e".ord) if key.control_keys.include?(:ALT) and !key.control_keys.include?(:CTRL)
253
255
 
254
- @@output_buf.concat(key.char.bytes)
256
+ @output_buf.concat(key.char.bytes)
255
257
  end
256
258
 
257
- def self.check_input_event
259
+ def check_input_event
258
260
  num_of_events = 0.chr * 8
259
- while @@output_buf.empty?
260
- Reline.core.line_editor.resize
261
- if @@WaitForSingleObject.(@@hConsoleInputHandle, 100) != 0 # max 0.1 sec
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
- @@legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0)
265
+ @legacy_console = getconsolemode & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0
264
266
  next
265
267
  end
266
- next if @@GetNumberOfConsoleInputEvents.(@@hConsoleInputHandle, num_of_events) == 0 or num_of_events.unpack1('L') == 0
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 @@ReadConsoleInputW.(@@hConsoleInputHandle, input_records, 80, read_event) != 0
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
- @@winch_handler.()
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 self.getc
296
+ def with_raw_input
297
+ yield
298
+ end
299
+
300
+ def getc(_timeout_second)
295
301
  check_input_event
296
- @@output_buf.shift
302
+ @output_buf.shift
297
303
  end
298
304
 
299
- def self.ungetc(c)
300
- @@output_buf.unshift(c)
305
+ def ungetc(c)
306
+ @output_buf.unshift(c)
301
307
  end
302
308
 
303
- def self.in_pasting?
304
- not self.empty_buffer?
309
+ def in_pasting?
310
+ not empty_buffer?
305
311
  end
306
312
 
307
- def self.empty_buffer?
308
- if not @@output_buf.empty?
313
+ def empty_buffer?
314
+ if not @output_buf.empty?
309
315
  false
310
- elsif @@kbhit.call == 0
316
+ elsif @kbhit.call == 0
311
317
  true
312
318
  else
313
319
  false
314
320
  end
315
321
  end
316
322
 
317
- def self.get_console_screen_buffer_info
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 @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi) == 0
337
+ return if @GetConsoleScreenBufferInfo.call(@hConsoleHandle, csbi) == 0
332
338
  csbi
333
339
  end
334
340
 
335
- def self.get_screen_size
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 self.cursor_pos
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 self.move_cursor_column(val)
352
- @@SetConsoleCursorPosition.call(@@hConsoleHandle, cursor_pos.y * 65536 + val)
357
+ def move_cursor_column(val)
358
+ @SetConsoleCursorPosition.call(@hConsoleHandle, cursor_pos.y * 65536 + val)
353
359
  end
354
360
 
355
- def self.move_cursor_up(val)
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
- @@SetConsoleCursorPosition.call(@@hConsoleHandle, y * 65536 + cursor_pos.x)
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 self.move_cursor_down(val)
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
- @@SetConsoleCursorPosition.call(@@hConsoleHandle, (cursor_pos.y + val) * 65536 + cursor_pos.x)
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 self.erase_after_cursor
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
- @@FillConsoleOutputCharacter.call(@@hConsoleHandle, 0x20, get_screen_size.last - cursor_pos.x, cursor, written)
383
- @@FillConsoleOutputAttribute.call(@@hConsoleHandle, attributes, get_screen_size.last - cursor_pos.x, cursor, written)
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 self.scroll_down(val)
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 @@legacy_console || window_left != 0
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
- @@ScrollConsoleScreenBuffer.call(@@hConsoleHandle, scroll_rectangle, nil, destination_origin, fill)
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
- @@output.write [
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 self.clear_screen
414
- if @@legacy_console
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
- @@FillConsoleOutputCharacter.call(@@hConsoleHandle, 0x20, fill_length, screen_topleft, written)
421
- @@FillConsoleOutputAttribute.call(@@hConsoleHandle, attributes, fill_length, screen_topleft, written)
422
- @@SetConsoleCursorPosition.call(@@hConsoleHandle, screen_topleft)
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
- @@output.write "\e[2J" "\e[H"
430
+ @output.write "\e[2J" "\e[H"
425
431
  end
426
432
  end
427
433
 
428
- def self.set_screen_size(rows, columns)
434
+ def set_screen_size(rows, columns)
429
435
  raise NotImplementedError
430
436
  end
431
437
 
432
- def self.hide_cursor
438
+ def hide_cursor
433
439
  size = 100
434
440
  visible = 0 # 0 means false
435
441
  cursor_info = [size, visible].pack('Li')
436
- @@SetConsoleCursorInfo.call(@@hConsoleHandle, cursor_info)
442
+ @SetConsoleCursorInfo.call(@hConsoleHandle, cursor_info)
437
443
  end
438
444
 
439
- def self.show_cursor
445
+ def show_cursor
440
446
  size = 100
441
447
  visible = 1 # 1 means true
442
448
  cursor_info = [size, visible].pack('Li')
443
- @@SetConsoleCursorInfo.call(@@hConsoleHandle, cursor_info)
449
+ @SetConsoleCursorInfo.call(@hConsoleHandle, cursor_info)
444
450
  end
445
451
 
446
- def self.set_winch_handler(&handler)
447
- @@winch_handler = handler
452
+ def set_winch_handler(&handler)
453
+ @winch_handler = handler
448
454
  end
449
455
 
450
- def self.prep
456
+ def prep
451
457
  # do nothing
452
458
  nil
453
459
  end
454
460
 
455
- def self.deprep(otio)
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
- MAPPING = Array.new(256)
2
+ def initialize(mapping = [])
3
+ @mapping = mapping
4
+ @matching_bytes = {}
5
+ @key_bindings = {}
6
+ end
3
7
 
4
8
  def get_method(key)
5
- self.class::MAPPING[key]
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 initialize
9
- @default_key_bindings = {}
19
+ def matching?(key)
20
+ @matching_bytes[key]
10
21
  end
11
22
 
12
- def default_key_bindings
13
- @default_key_bindings
23
+ def get(key)
24
+ @key_bindings[key]
14
25
  end
15
26
 
16
- def reset_default_key_bindings
17
- @default_key_bindings.clear
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
- class Reline::KeyActor::Emacs < Reline::KeyActor::Base
2
- MAPPING = [
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
- :ed_unassigned,
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
- :ed_sequence_lead_in,
52
+ :ed_unassigned,
53
53
  # 25 ^Y
54
54
  :em_yank,
55
55
  # 26 ^Z
56
56
  :ed_ignore,
57
57
  # 27 ^[
58
- :em_meta_next,
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
- :ed_unassigned,
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
- :em_copy_prev_word,
322
+ :redo,
323
323
  # 160 M-SPACE
324
- :ed_unassigned,
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
- :ed_sequence_lead_in,
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
- :em_copy_region,
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
- :ed_sequence_lead_in,
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
- :em_copy_region,
498
+ :ed_unassigned,
499
499
  # 248 M-x
500
- :ed_command,
500
+ :ed_unassigned,
501
501
  # 249 M-y
502
502
  :ed_unassigned,
503
503
  # 250 M-z