reline 0.5.8 → 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,21 +1,49 @@
1
1
  require 'fiddle/import'
2
2
 
3
- class Reline::Windows
4
- RESET_COLOR = "\e[0m"
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
5
33
 
6
- def self.encoding
34
+ def encoding
7
35
  Encoding::UTF_8
8
36
  end
9
37
 
10
- def self.win?
38
+ def win?
11
39
  true
12
40
  end
13
41
 
14
- def self.win_legacy_console?
15
- @@legacy_console
42
+ def win_legacy_console?
43
+ @legacy_console
16
44
  end
17
45
 
18
- def self.set_default_key_bindings(config)
46
+ def set_default_key_bindings(config)
19
47
  {
20
48
  [224, 72] => :ed_prev_history, # ↑
21
49
  [224, 80] => :ed_next_history, # ↓
@@ -129,58 +157,32 @@ class Reline::Windows
129
157
  STD_OUTPUT_HANDLE = -11
130
158
  FILE_TYPE_PIPE = 0x0003
131
159
  FILE_NAME_INFO = 2
132
- @@getwch = Win32API.new('msvcrt', '_getwch', [], 'I')
133
- @@kbhit = Win32API.new('msvcrt', '_kbhit', [], 'I')
134
- @@GetKeyState = Win32API.new('user32', 'GetKeyState', ['L'], 'L')
135
- @@GetConsoleScreenBufferInfo = Win32API.new('kernel32', 'GetConsoleScreenBufferInfo', ['L', 'P'], 'L')
136
- @@SetConsoleCursorPosition = Win32API.new('kernel32', 'SetConsoleCursorPosition', ['L', 'L'], 'L')
137
- @@GetStdHandle = Win32API.new('kernel32', 'GetStdHandle', ['L'], 'L')
138
- @@FillConsoleOutputCharacter = Win32API.new('kernel32', 'FillConsoleOutputCharacter', ['L', 'L', 'L', 'L', 'P'], 'L')
139
- @@ScrollConsoleScreenBuffer = Win32API.new('kernel32', 'ScrollConsoleScreenBuffer', ['L', 'P', 'P', 'L', 'P'], 'L')
140
- @@hConsoleHandle = @@GetStdHandle.call(STD_OUTPUT_HANDLE)
141
- @@hConsoleInputHandle = @@GetStdHandle.call(STD_INPUT_HANDLE)
142
- @@GetNumberOfConsoleInputEvents = Win32API.new('kernel32', 'GetNumberOfConsoleInputEvents', ['L', 'P'], 'L')
143
- @@ReadConsoleInputW = Win32API.new('kernel32', 'ReadConsoleInputW', ['L', 'P', 'L', 'P'], 'L')
144
- @@GetFileType = Win32API.new('kernel32', 'GetFileType', ['L'], 'L')
145
- @@GetFileInformationByHandleEx = Win32API.new('kernel32', 'GetFileInformationByHandleEx', ['L', 'I', 'P', 'L'], 'I')
146
- @@FillConsoleOutputAttribute = Win32API.new('kernel32', 'FillConsoleOutputAttribute', ['L', 'L', 'L', 'L', 'P'], 'L')
147
- @@SetConsoleCursorInfo = Win32API.new('kernel32', 'SetConsoleCursorInfo', ['L', 'P'], 'L')
148
-
149
- @@GetConsoleMode = Win32API.new('kernel32', 'GetConsoleMode', ['L', 'P'], 'L')
150
- @@SetConsoleMode = Win32API.new('kernel32', 'SetConsoleMode', ['L', 'L'], 'L')
151
- @@WaitForSingleObject = Win32API.new('kernel32', 'WaitForSingleObject', ['L', 'L'], 'L')
152
160
  ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4
153
161
 
154
- private_class_method def self.getconsolemode
162
+ private def getconsolemode
155
163
  mode = "\000\000\000\000"
156
- @@GetConsoleMode.call(@@hConsoleHandle, mode)
164
+ @GetConsoleMode.call(@hConsoleHandle, mode)
157
165
  mode.unpack1('L')
158
166
  end
159
167
 
160
- private_class_method def self.setconsolemode(mode)
161
- @@SetConsoleMode.call(@@hConsoleHandle, mode)
168
+ private def setconsolemode(mode)
169
+ @SetConsoleMode.call(@hConsoleHandle, mode)
162
170
  end
163
171
 
164
- @@legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0)
165
- #if @@legacy_console
172
+ #if @legacy_console
166
173
  # setconsolemode(getconsolemode() | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
167
- # @@legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0)
174
+ # @legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0)
168
175
  #end
169
176
 
170
- @@input_buf = []
171
- @@output_buf = []
172
-
173
- @@output = STDOUT
174
-
175
- def self.msys_tty?(io = @@hConsoleInputHandle)
177
+ def msys_tty?(io = @hConsoleInputHandle)
176
178
  # check if fd is a pipe
177
- if @@GetFileType.call(io) != FILE_TYPE_PIPE
179
+ if @GetFileType.call(io) != FILE_TYPE_PIPE
178
180
  return false
179
181
  end
180
182
 
181
183
  bufsize = 1024
182
184
  p_buffer = "\0" * bufsize
183
- res = @@GetFileInformationByHandleEx.call(io, FILE_NAME_INFO, p_buffer, bufsize - 2)
185
+ res = @GetFileInformationByHandleEx.call(io, FILE_NAME_INFO, p_buffer, bufsize - 2)
184
186
  return false if res == 0
185
187
 
186
188
  # get pipe name: p_buffer layout is:
@@ -217,65 +219,63 @@ class Reline::Windows
217
219
  [ { control_keys: :SHIFT, virtual_key_code: VK_TAB }, [27, 91, 90] ],
218
220
  ]
219
221
 
220
- @@hsg = nil
221
-
222
- 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)
223
223
 
224
224
  # high-surrogate
225
225
  if 0xD800 <= char_code and char_code <= 0xDBFF
226
- @@hsg = char_code
226
+ @hsg = char_code
227
227
  return
228
228
  end
229
229
  # low-surrogate
230
230
  if 0xDC00 <= char_code and char_code <= 0xDFFF
231
- if @@hsg
232
- char_code = 0x10000 + (@@hsg - 0xD800) * 0x400 + char_code - 0xDC00
233
- @@hsg = nil
231
+ if @hsg
232
+ char_code = 0x10000 + (@hsg - 0xD800) * 0x400 + char_code - 0xDC00
233
+ @hsg = nil
234
234
  else
235
235
  # no high-surrogate. ignored.
236
236
  return
237
237
  end
238
238
  else
239
239
  # ignore high-surrogate without low-surrogate if there
240
- @@hsg = nil
240
+ @hsg = nil
241
241
  end
242
242
 
243
243
  key = KeyEventRecord.new(virtual_key_code, char_code, control_key_state)
244
244
 
245
245
  match = KEY_MAP.find { |args,| key.matches?(**args) }
246
246
  unless match.nil?
247
- @@output_buf.concat(match.last)
247
+ @output_buf.concat(match.last)
248
248
  return
249
249
  end
250
250
 
251
251
  # no char, only control keys
252
252
  return if key.char_code == 0 and key.control_keys.any?
253
253
 
254
- @@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)
255
255
 
256
- @@output_buf.concat(key.char.bytes)
256
+ @output_buf.concat(key.char.bytes)
257
257
  end
258
258
 
259
- def self.check_input_event
259
+ def check_input_event
260
260
  num_of_events = 0.chr * 8
261
- while @@output_buf.empty?
261
+ while @output_buf.empty?
262
262
  Reline.core.line_editor.handle_signal
263
- if @@WaitForSingleObject.(@@hConsoleInputHandle, 100) != 0 # max 0.1 sec
263
+ if @WaitForSingleObject.(@hConsoleInputHandle, 100) != 0 # max 0.1 sec
264
264
  # prevent for background consolemode change
265
- @@legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0)
265
+ @legacy_console = getconsolemode & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0
266
266
  next
267
267
  end
268
- 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
269
269
  input_records = 0.chr * 20 * 80
270
270
  read_event = 0.chr * 4
271
- if @@ReadConsoleInputW.(@@hConsoleInputHandle, input_records, 80, read_event) != 0
271
+ if @ReadConsoleInputW.(@hConsoleInputHandle, input_records, 80, read_event) != 0
272
272
  read_events = read_event.unpack1('L')
273
273
  0.upto(read_events) do |idx|
274
274
  input_record = input_records[idx * 20, 20]
275
275
  event = input_record[0, 2].unpack1('s*')
276
276
  case event
277
277
  when WINDOW_BUFFER_SIZE_EVENT
278
- @@winch_handler.()
278
+ @winch_handler.()
279
279
  when KEY_EVENT
280
280
  key_down = input_record[4, 4].unpack1('l*')
281
281
  repeat_count = input_record[8, 2].unpack1('s*')
@@ -293,34 +293,34 @@ class Reline::Windows
293
293
  end
294
294
  end
295
295
 
296
- def self.with_raw_input
296
+ def with_raw_input
297
297
  yield
298
298
  end
299
299
 
300
- def self.getc(_timeout_second)
300
+ def getc(_timeout_second)
301
301
  check_input_event
302
- @@output_buf.shift
302
+ @output_buf.shift
303
303
  end
304
304
 
305
- def self.ungetc(c)
306
- @@output_buf.unshift(c)
305
+ def ungetc(c)
306
+ @output_buf.unshift(c)
307
307
  end
308
308
 
309
- def self.in_pasting?
310
- not self.empty_buffer?
309
+ def in_pasting?
310
+ not empty_buffer?
311
311
  end
312
312
 
313
- def self.empty_buffer?
314
- if not @@output_buf.empty?
313
+ def empty_buffer?
314
+ if not @output_buf.empty?
315
315
  false
316
- elsif @@kbhit.call == 0
316
+ elsif @kbhit.call == 0
317
317
  true
318
318
  else
319
319
  false
320
320
  end
321
321
  end
322
322
 
323
- def self.get_console_screen_buffer_info
323
+ def get_console_screen_buffer_info
324
324
  # CONSOLE_SCREEN_BUFFER_INFO
325
325
  # [ 0,2] dwSize.X
326
326
  # [ 2,2] dwSize.Y
@@ -334,18 +334,18 @@ class Reline::Windows
334
334
  # [18,2] dwMaximumWindowSize.X
335
335
  # [20,2] dwMaximumWindowSize.Y
336
336
  csbi = 0.chr * 22
337
- return if @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi) == 0
337
+ return if @GetConsoleScreenBufferInfo.call(@hConsoleHandle, csbi) == 0
338
338
  csbi
339
339
  end
340
340
 
341
- def self.get_screen_size
341
+ def get_screen_size
342
342
  unless csbi = get_console_screen_buffer_info
343
343
  return [1, 1]
344
344
  end
345
345
  csbi[0, 4].unpack('SS').reverse
346
346
  end
347
347
 
348
- def self.cursor_pos
348
+ def cursor_pos
349
349
  unless csbi = get_console_screen_buffer_info
350
350
  return Reline::CursorPos.new(0, 0)
351
351
  end
@@ -354,49 +354,49 @@ class Reline::Windows
354
354
  Reline::CursorPos.new(x, y)
355
355
  end
356
356
 
357
- def self.move_cursor_column(val)
358
- @@SetConsoleCursorPosition.call(@@hConsoleHandle, cursor_pos.y * 65536 + val)
357
+ def move_cursor_column(val)
358
+ @SetConsoleCursorPosition.call(@hConsoleHandle, cursor_pos.y * 65536 + val)
359
359
  end
360
360
 
361
- def self.move_cursor_up(val)
361
+ def move_cursor_up(val)
362
362
  if val > 0
363
363
  y = cursor_pos.y - val
364
364
  y = 0 if y < 0
365
- @@SetConsoleCursorPosition.call(@@hConsoleHandle, y * 65536 + cursor_pos.x)
365
+ @SetConsoleCursorPosition.call(@hConsoleHandle, y * 65536 + cursor_pos.x)
366
366
  elsif val < 0
367
367
  move_cursor_down(-val)
368
368
  end
369
369
  end
370
370
 
371
- def self.move_cursor_down(val)
371
+ def move_cursor_down(val)
372
372
  if val > 0
373
373
  return unless csbi = get_console_screen_buffer_info
374
374
  screen_height = get_screen_size.first
375
375
  y = cursor_pos.y + val
376
376
  y = screen_height - 1 if y > (screen_height - 1)
377
- @@SetConsoleCursorPosition.call(@@hConsoleHandle, (cursor_pos.y + val) * 65536 + cursor_pos.x)
377
+ @SetConsoleCursorPosition.call(@hConsoleHandle, (cursor_pos.y + val) * 65536 + cursor_pos.x)
378
378
  elsif val < 0
379
379
  move_cursor_up(-val)
380
380
  end
381
381
  end
382
382
 
383
- def self.erase_after_cursor
383
+ def erase_after_cursor
384
384
  return unless csbi = get_console_screen_buffer_info
385
385
  attributes = csbi[8, 2].unpack1('S')
386
386
  cursor = csbi[4, 4].unpack1('L')
387
387
  written = 0.chr * 4
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)
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)
390
390
  end
391
391
 
392
- def self.scroll_down(val)
392
+ def scroll_down(val)
393
393
  return if val < 0
394
394
  return unless csbi = get_console_screen_buffer_info
395
395
  buffer_width, buffer_lines, x, y, attributes, window_left, window_top, window_bottom = csbi.unpack('ssssSssx2s')
396
396
  screen_height = window_bottom - window_top + 1
397
397
  val = screen_height if val > screen_height
398
398
 
399
- if @@legacy_console || window_left != 0
399
+ if @legacy_console || window_left != 0
400
400
  # unless ENABLE_VIRTUAL_TERMINAL,
401
401
  # if srWindow.Left != 0 then it's conhost.exe hosted console
402
402
  # and puts "\n" causes horizontal scroll. its glitch.
@@ -404,11 +404,11 @@ class Reline::Windows
404
404
  scroll_rectangle = [0, val, buffer_width, buffer_lines - val].pack('s4')
405
405
  destination_origin = 0 # y * 65536 + x
406
406
  fill = [' '.ord, attributes].pack('SS')
407
- @@ScrollConsoleScreenBuffer.call(@@hConsoleHandle, scroll_rectangle, nil, destination_origin, fill)
407
+ @ScrollConsoleScreenBuffer.call(@hConsoleHandle, scroll_rectangle, nil, destination_origin, fill)
408
408
  else
409
409
  origin_x = x + 1
410
410
  origin_y = y - window_top + 1
411
- @@output.write [
411
+ @output.write [
412
412
  (origin_y != screen_height) ? "\e[#{screen_height};H" : nil,
413
413
  "\n" * val,
414
414
  (origin_y != screen_height or !x.zero?) ? "\e[#{origin_y};#{origin_x}H" : nil
@@ -416,49 +416,49 @@ class Reline::Windows
416
416
  end
417
417
  end
418
418
 
419
- def self.clear_screen
420
- if @@legacy_console
419
+ def clear_screen
420
+ if @legacy_console
421
421
  return unless csbi = get_console_screen_buffer_info
422
422
  buffer_width, _buffer_lines, attributes, window_top, window_bottom = csbi.unpack('ss@8S@12sx2s')
423
423
  fill_length = buffer_width * (window_bottom - window_top + 1)
424
424
  screen_topleft = window_top * 65536
425
425
  written = 0.chr * 4
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)
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)
429
429
  else
430
- @@output.write "\e[2J" "\e[H"
430
+ @output.write "\e[2J" "\e[H"
431
431
  end
432
432
  end
433
433
 
434
- def self.set_screen_size(rows, columns)
434
+ def set_screen_size(rows, columns)
435
435
  raise NotImplementedError
436
436
  end
437
437
 
438
- def self.hide_cursor
438
+ def hide_cursor
439
439
  size = 100
440
440
  visible = 0 # 0 means false
441
441
  cursor_info = [size, visible].pack('Li')
442
- @@SetConsoleCursorInfo.call(@@hConsoleHandle, cursor_info)
442
+ @SetConsoleCursorInfo.call(@hConsoleHandle, cursor_info)
443
443
  end
444
444
 
445
- def self.show_cursor
445
+ def show_cursor
446
446
  size = 100
447
447
  visible = 1 # 1 means true
448
448
  cursor_info = [size, visible].pack('Li')
449
- @@SetConsoleCursorInfo.call(@@hConsoleHandle, cursor_info)
449
+ @SetConsoleCursorInfo.call(@hConsoleHandle, cursor_info)
450
450
  end
451
451
 
452
- def self.set_winch_handler(&handler)
453
- @@winch_handler = handler
452
+ def set_winch_handler(&handler)
453
+ @winch_handler = handler
454
454
  end
455
455
 
456
- def self.prep
456
+ def prep
457
457
  # do nothing
458
458
  nil
459
459
  end
460
460
 
461
- def self.deprep(otio)
461
+ def deprep(otio)
462
462
  # do nothing
463
463
  end
464
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,15 +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
17
+ end
18
+
19
+ def matching?(key)
20
+ @matching_bytes[key]
6
21
  end
7
22
 
8
- def initialize
9
- @default_key_bindings = {}
23
+ def get(key)
24
+ @key_bindings[key]
10
25
  end
11
26
 
12
- def default_key_bindings
13
- @default_key_bindings
27
+ def clear
28
+ @matching_bytes.clear
29
+ @key_bindings.clear
14
30
  end
15
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
@@ -1,5 +1,5 @@
1
- class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
2
- MAPPING = [
1
+ module Reline::KeyActor
2
+ VI_COMMAND_MAPPING = [
3
3
  # 0 ^@
4
4
  :ed_unassigned,
5
5
  # 1 ^A
@@ -1,5 +1,5 @@
1
- class Reline::KeyActor::ViInsert < Reline::KeyActor::Base
2
- MAPPING = [
1
+ module Reline::KeyActor
2
+ VI_INSERT_MAPPING = [
3
3
  # 0 ^@
4
4
  :ed_unassigned,
5
5
  # 1 ^A
@@ -2,6 +2,7 @@ module Reline::KeyActor
2
2
  end
3
3
 
4
4
  require 'reline/key_actor/base'
5
+ require 'reline/key_actor/composite'
5
6
  require 'reline/key_actor/emacs'
6
7
  require 'reline/key_actor/vi_command'
7
8
  require 'reline/key_actor/vi_insert'