Class: Reline::KeyStroke

Inherits:
Object
  • Object
show all
Defined in:
lib/reline/key_stroke.rb

Constant Summary collapse

ESC_BYTE =
27
CSI_PARAMETER_BYTES_RANGE =
0x30..0x3f
CSI_INTERMEDIATE_BYTES_RANGE =
(0x20..0x2f)
MATCHING =

Input exactly matches to a key sequence

:matching
MATCHED =

Input partially matches to a key sequence

:matched
MATCHING_MATCHED =

Input matches to a key sequence and the key sequence is a prefix of another key sequence

:matching_matched
UNMATCHED =

Input does not match to any key sequence

:unmatched

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ KeyStroke

Returns a new instance of KeyStroke.



6
7
8
# File 'lib/reline/key_stroke.rb', line 6

def initialize(config)
  @config = config
end

Instance Method Details

#expand(input) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/reline/key_stroke.rb', line 42

def expand(input)
  matched_bytes = nil
  (1..input.size).each do |i|
    bytes = input.take(i)
    status = match_status(bytes)
    matched_bytes = bytes if status == MATCHED || status == MATCHING_MATCHED
  end
  return [[], []] unless matched_bytes

  func = key_mapping.get(matched_bytes)
  if func.is_a?(Array)
    keys = func.map { |c| Reline::Key.new(c, c, false) }
  elsif func
    keys = [Reline::Key.new(func, func, false)]
  elsif matched_bytes.size == 1
    keys = [Reline::Key.new(matched_bytes.first, matched_bytes.first, false)]
  elsif matched_bytes.size == 2 && matched_bytes[0] == ESC_BYTE
    keys = [Reline::Key.new(matched_bytes[1], matched_bytes[1] | 0b10000000, true)]
  else
    keys = []
  end

  [keys, input.drop(matched_bytes.size)]
end

#match_status(input) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/reline/key_stroke.rb', line 19

def match_status(input)
  matching = key_mapping.matching?(input)
  matched = key_mapping.get(input)

  # FIXME: Workaround for single byte. remove this after MAPPING is merged into KeyActor.
  matched ||= input.size == 1
  matching ||= input == [ESC_BYTE]

  if matching && matched
    MATCHING_MATCHED
  elsif matching
    MATCHING
  elsif matched
    MATCHED
  elsif input[0] == ESC_BYTE
    match_unknown_escape_sequence(input, vi_mode: @config.editing_mode_is?(:vi_insert, :vi_command))
  elsif input.size == 1
    MATCHED
  else
    UNMATCHED
  end
end