1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
require_relative 'helper'
class Reline::KeyStroke::Test < Reline::TestCase
def encoding
Reline.core.encoding
end
def test_match_status
config = Reline::Config.new
{
'a' => 'xx',
'ab' => 'y',
'abc' => 'z',
'x' => 'rr'
}.each_pair do |key, func|
config.add_default_key_binding(key.bytes, func.bytes)
end
stroke = Reline::KeyStroke.new(config, encoding)
assert_equal(Reline::KeyStroke::MATCHING_MATCHED, stroke.match_status("a".bytes))
assert_equal(Reline::KeyStroke::MATCHING_MATCHED, stroke.match_status("ab".bytes))
assert_equal(Reline::KeyStroke::MATCHED, stroke.match_status("abc".bytes))
assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status("abz".bytes))
assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status("abcx".bytes))
assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status("aa".bytes))
assert_equal(Reline::KeyStroke::MATCHED, stroke.match_status("x".bytes))
assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status("xa".bytes))
end
def test_match_unknown
config = Reline::Config.new
config.add_default_key_binding("\e[9abc".bytes, 'x')
stroke = Reline::KeyStroke.new(config, encoding)
sequences = [
"\e[9abc",
"\e[9d",
"\e[A", # Up
"\e[1;1R", # Cursor position report
"\e[15~", # F5
"\eOP", # F1
"\e\e[A", # Option+Up
"\eX",
"\e\eX"
]
sequences.each do |seq|
assert_equal(Reline::KeyStroke::MATCHED, stroke.match_status(seq.bytes))
assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status(seq.bytes + [32]))
(2...seq.size).each do |i|
assert_equal(Reline::KeyStroke::MATCHING, stroke.match_status(seq.bytes.take(i)))
end
end
end
def test_expand
config = Reline::Config.new
{
'abc' => 'AB',
'ab' => "1\C-a"
}.each_pair do |key, func|
config.add_default_key_binding(key.bytes, func.bytes)
end
stroke = Reline::KeyStroke.new(config, encoding)
assert_equal([[Reline::Key.new('A', :ed_insert, false), Reline::Key.new('B', :ed_insert, false)], 'de'.bytes], stroke.expand('abcde'.bytes))
assert_equal([[Reline::Key.new('1', :ed_digit, false), Reline::Key.new("\C-a", :ed_move_to_beg, false)], 'de'.bytes], stroke.expand('abde'.bytes))
# CSI sequence
assert_equal([[], 'bc'.bytes], stroke.expand("\e[1;2;3;4;5abc".bytes))
assert_equal([[], 'BC'.bytes], stroke.expand("\e\e[ABC".bytes))
# SS3 sequence
assert_equal([[], 'QR'.bytes], stroke.expand("\eOPQR".bytes))
end
def test_oneshot_key_bindings
config = Reline::Config.new
{
'abc'.bytes => '123',
# IRB version <= 1.13.1 wrongly uses Reline::Key with wrong argument. It should be ignored without error.
[Reline::Key.new(nil, 0xE4, true)] => '012',
"\eda".bytes => 'abc', # Alt+d a
[195, 164] => 'def'
}.each_pair do |key, func|
config.add_oneshot_key_binding(key, func.bytes)
end
stroke = Reline::KeyStroke.new(config, encoding)
assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status('zzz'.bytes))
assert_equal(Reline::KeyStroke::MATCHED, stroke.match_status('abc'.bytes))
assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status('da'.bytes))
assert_equal(Reline::KeyStroke::MATCHED, stroke.match_status("\eda".bytes))
assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status(" \eda".bytes))
assert_equal(Reline::KeyStroke::MATCHED, stroke.match_status([195, 164]))
end
def test_multibyte_matching
begin
char = 'あ'.encode(encoding)
rescue Encoding::UndefinedConversionError
omit
end
config = Reline::Config.new
stroke = Reline::KeyStroke.new(config, encoding)
key = Reline::Key.new(char, :ed_insert, false)
bytes = char.bytes
assert_equal(Reline::KeyStroke::MATCHED, stroke.match_status(bytes))
assert_equal([[key], []], stroke.expand(bytes))
assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status(bytes * 2))
assert_equal([[key], bytes], stroke.expand(bytes * 2))
(1...bytes.size).each do |i|
partial_bytes = bytes.take(i)
assert_equal(Reline::KeyStroke::MATCHING_MATCHED, stroke.match_status(partial_bytes))
assert_equal([[], []], stroke.expand(partial_bytes))
end
end
end
|