reline 0.1.5 → 0.3.1
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 +50 -0
- data/lib/reline/ansi.rb +206 -58
- data/lib/reline/config.rb +71 -21
- data/lib/reline/general_io.rb +31 -3
- data/lib/reline/key_actor/base.rb +12 -0
- data/lib/reline/key_actor/emacs.rb +2 -2
- data/lib/reline/key_actor/vi_command.rb +2 -2
- data/lib/reline/key_stroke.rb +64 -14
- data/lib/reline/kill_ring.rb +12 -0
- data/lib/reline/line_editor.rb +1332 -291
- data/lib/reline/sibori.rb +170 -0
- data/lib/reline/terminfo.rb +171 -0
- data/lib/reline/unicode/east_asian_width.rb +1149 -1130
- data/lib/reline/unicode.rb +103 -33
- data/lib/reline/version.rb +1 -1
- data/lib/reline/windows.rb +324 -109
- data/lib/reline.rb +184 -39
- data/license_of_rb-readline +25 -0
- metadata +6 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1009c9156a8c15c1f3c64a3cb89a0d6a1acef037185bfb76c24ed9df7e49cb2c
|
4
|
+
data.tar.gz: 983ad1d570617a47d732402485a79eba8bd1acc6f3555f117ca6822cee52030d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 424c026623c896ccd59fed73b5f61e7bb067dfdc8fe34a13bdb317895fb512eb666b25c76439e940915307e658e85dbbfcb8339ecfae5c5b72fa9239d1599778
|
7
|
+
data.tar.gz: 93077ced9c8009d5c2f7f59eb013f8134394347c57660e7958244a2adfe60b2a09463ac2062d9ce31e5d75974b19665f7e800f2078bf9b461dfbada76c3e572e
|
data/README.md
CHANGED
@@ -8,6 +8,56 @@ This is a screen capture of *IRB improved by Reline*.
|
|
8
8
|
|
9
9
|
Reline is compatible with the API of Ruby's stdlib 'readline', GNU Readline and Editline by pure Ruby implementation.
|
10
10
|
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
### Single line editing mode
|
14
|
+
|
15
|
+
It's compatible with the readline standard library.
|
16
|
+
|
17
|
+
See [the document of readline stdlib](https://ruby-doc.org/stdlib/libdoc/readline/rdoc/Readline.html) or [bin/example](https://github.com/ruby/reline/blob/master/bin/example).
|
18
|
+
|
19
|
+
### Multi-line editing mode
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
require "reline"
|
23
|
+
|
24
|
+
prompt = 'prompt> '
|
25
|
+
use_history = true
|
26
|
+
|
27
|
+
begin
|
28
|
+
while true
|
29
|
+
text = Reline.readmultiline(prompt, use_history) do |multiline_input|
|
30
|
+
# Accept the input until `end` is entered
|
31
|
+
multiline_input.split.last == "end"
|
32
|
+
end
|
33
|
+
|
34
|
+
puts 'You entered:'
|
35
|
+
puts text
|
36
|
+
end
|
37
|
+
# If you want to exit, type Ctrl-C
|
38
|
+
rescue Interrupt
|
39
|
+
puts '^C'
|
40
|
+
exit 0
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
```bash
|
45
|
+
$ ruby example.rb
|
46
|
+
prompt> aaa
|
47
|
+
prompt> bbb
|
48
|
+
prompt> end
|
49
|
+
You entered:
|
50
|
+
aaa
|
51
|
+
bbb
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
See also: [test/reline/yamatanooroti/multiline_repl](https://github.com/ruby/reline/blob/master/test/reline/yamatanooroti/multiline_repl)
|
56
|
+
|
11
57
|
## License
|
12
58
|
|
13
59
|
The gem is available as open source under the terms of the [Ruby License](https://www.ruby-lang.org/en/about/license.txt).
|
60
|
+
|
61
|
+
## Acknowledgments for [rb-readline](https://github.com/ConnorAtherton/rb-readline)
|
62
|
+
|
63
|
+
In developing Reline, we have used some of the rb-readline implementation, so this library includes [copyright notice, list of conditions and the disclaimer](license_of_rb-readline) under the 3-Clause BSD License. Reline would never have been developed without rb-readline. Thank you for the tremendous accomplishments.
|
data/lib/reline/ansi.rb
CHANGED
@@ -1,6 +1,26 @@
|
|
1
1
|
require 'io/console'
|
2
|
+
require 'io/wait'
|
3
|
+
require 'timeout'
|
4
|
+
require_relative 'terminfo'
|
2
5
|
|
3
6
|
class Reline::ANSI
|
7
|
+
CAPNAME_KEY_BINDINGS = {
|
8
|
+
'khome' => :ed_move_to_beg,
|
9
|
+
'kend' => :ed_move_to_end,
|
10
|
+
'kcuu1' => :ed_prev_history,
|
11
|
+
'kcud1' => :ed_next_history,
|
12
|
+
'kcuf1' => :ed_next_char,
|
13
|
+
'kcub1' => :ed_prev_char,
|
14
|
+
'cuu' => :ed_prev_history,
|
15
|
+
'cud' => :ed_next_history,
|
16
|
+
'cuf' => :ed_next_char,
|
17
|
+
'cub' => :ed_prev_char,
|
18
|
+
}
|
19
|
+
|
20
|
+
if Reline::Terminfo.enabled?
|
21
|
+
Reline::Terminfo.setupterm(0, 2)
|
22
|
+
end
|
23
|
+
|
4
24
|
def self.encoding
|
5
25
|
Encoding.default_external
|
6
26
|
end
|
@@ -9,52 +29,108 @@ class Reline::ANSI
|
|
9
29
|
false
|
10
30
|
end
|
11
31
|
|
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
|
-
|
32
|
+
def self.set_default_key_bindings(config)
|
33
|
+
if Reline::Terminfo.enabled?
|
34
|
+
set_default_key_bindings_terminfo(config)
|
35
|
+
else
|
36
|
+
set_default_key_bindings_comprehensive_list(config)
|
37
|
+
end
|
38
|
+
{
|
39
|
+
# extended entries of terminfo
|
40
|
+
[27, 91, 49, 59, 53, 67] => :em_next_word, # Ctrl+→, extended entry
|
41
|
+
[27, 91, 49, 59, 53, 68] => :ed_prev_word, # Ctrl+←, extended entry
|
42
|
+
[27, 91, 49, 59, 51, 67] => :em_next_word, # Meta+→, extended entry
|
43
|
+
[27, 91, 49, 59, 51, 68] => :ed_prev_word, # Meta+←, extended entry
|
44
|
+
}.each_pair do |key, func|
|
45
|
+
config.add_default_key_binding_by_keymap(:emacs, key, func)
|
46
|
+
config.add_default_key_binding_by_keymap(:vi_insert, key, func)
|
47
|
+
config.add_default_key_binding_by_keymap(:vi_command, key, func)
|
48
|
+
end
|
49
|
+
{
|
50
|
+
[27, 91, 90] => :completion_journey_up, # S-Tab
|
51
|
+
}.each_pair do |key, func|
|
52
|
+
config.add_default_key_binding_by_keymap(:emacs, key, func)
|
53
|
+
config.add_default_key_binding_by_keymap(:vi_insert, key, func)
|
54
|
+
end
|
55
|
+
{
|
56
|
+
# default bindings
|
57
|
+
[27, 32] => :em_set_mark, # M-<space>
|
58
|
+
[24, 24] => :em_exchange_mark, # C-x C-x
|
59
|
+
}.each_pair do |key, func|
|
60
|
+
config.add_default_key_binding_by_keymap(:emacs, key, func)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.set_default_key_bindings_terminfo(config)
|
65
|
+
key_bindings = CAPNAME_KEY_BINDINGS.map do |capname, key_binding|
|
66
|
+
begin
|
67
|
+
key_code = Reline::Terminfo.tigetstr(capname)
|
68
|
+
case capname
|
69
|
+
# Escape sequences that omit the move distance and are set to defaults
|
70
|
+
# value 1 may be sometimes sent by pressing the arrow-key.
|
71
|
+
when 'cuu', 'cud', 'cuf', 'cub'
|
72
|
+
[ key_code.sub(/%p1%d/, '').bytes, key_binding ]
|
73
|
+
else
|
74
|
+
[ key_code.bytes, key_binding ]
|
75
|
+
end
|
76
|
+
rescue Reline::Terminfo::TerminfoError
|
77
|
+
# capname is undefined
|
78
|
+
end
|
79
|
+
end.compact.to_h
|
80
|
+
|
81
|
+
key_bindings.each_pair do |key, func|
|
82
|
+
config.add_default_key_binding_by_keymap(:emacs, key, func)
|
83
|
+
config.add_default_key_binding_by_keymap(:vi_insert, key, func)
|
84
|
+
config.add_default_key_binding_by_keymap(:vi_command, key, func)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.set_default_key_bindings_comprehensive_list(config)
|
89
|
+
{
|
90
|
+
# Console (80x25)
|
91
|
+
[27, 91, 49, 126] => :ed_move_to_beg, # Home
|
92
|
+
[27, 91, 52, 126] => :ed_move_to_end, # End
|
93
|
+
[27, 91, 51, 126] => :key_delete, # Del
|
94
|
+
[27, 91, 65] => :ed_prev_history, # ↑
|
95
|
+
[27, 91, 66] => :ed_next_history, # ↓
|
96
|
+
[27, 91, 67] => :ed_next_char, # →
|
97
|
+
[27, 91, 68] => :ed_prev_char, # ←
|
98
|
+
|
99
|
+
# KDE
|
100
|
+
[27, 91, 72] => :ed_move_to_beg, # Home
|
101
|
+
[27, 91, 70] => :ed_move_to_end, # End
|
102
|
+
# Del is 0x08
|
103
|
+
[27, 71, 65] => :ed_prev_history, # ↑
|
104
|
+
[27, 71, 66] => :ed_next_history, # ↓
|
105
|
+
[27, 71, 67] => :ed_next_char, # →
|
106
|
+
[27, 71, 68] => :ed_prev_char, # ←
|
107
|
+
|
108
|
+
# urxvt / exoterm
|
109
|
+
[27, 91, 55, 126] => :ed_move_to_beg, # Home
|
110
|
+
[27, 91, 56, 126] => :ed_move_to_end, # End
|
111
|
+
|
112
|
+
# GNOME
|
113
|
+
[27, 79, 72] => :ed_move_to_beg, # Home
|
114
|
+
[27, 79, 70] => :ed_move_to_end, # End
|
115
|
+
# Del is 0x08
|
116
|
+
# Arrow keys are the same of KDE
|
117
|
+
|
118
|
+
# iTerm2
|
119
|
+
[27, 27, 91, 67] => :em_next_word, # Option+→, extended entry
|
120
|
+
[27, 27, 91, 68] => :ed_prev_word, # Option+←, extended entry
|
121
|
+
[195, 166] => :em_next_word, # Option+f
|
122
|
+
[195, 162] => :ed_prev_word, # Option+b
|
123
|
+
|
124
|
+
[27, 79, 65] => :ed_prev_history, # ↑
|
125
|
+
[27, 79, 66] => :ed_next_history, # ↓
|
126
|
+
[27, 79, 67] => :ed_next_char, # →
|
127
|
+
[27, 79, 68] => :ed_prev_char, # ←
|
128
|
+
}.each_pair do |key, func|
|
129
|
+
config.add_default_key_binding_by_keymap(:emacs, key, func)
|
130
|
+
config.add_default_key_binding_by_keymap(:vi_insert, key, func)
|
131
|
+
config.add_default_key_binding_by_keymap(:vi_command, key, func)
|
132
|
+
end
|
133
|
+
end
|
58
134
|
|
59
135
|
@@input = STDIN
|
60
136
|
def self.input=(val)
|
@@ -67,17 +143,70 @@ class Reline::ANSI
|
|
67
143
|
end
|
68
144
|
|
69
145
|
@@buf = []
|
70
|
-
def self.
|
146
|
+
def self.inner_getc
|
71
147
|
unless @@buf.empty?
|
72
148
|
return @@buf.shift
|
73
149
|
end
|
74
|
-
until c = @@input.raw(intr: true
|
75
|
-
|
150
|
+
until c = @@input.raw(intr: true) { @@input.wait_readable(0.1) && @@input.getbyte }
|
151
|
+
Reline.core.line_editor.resize
|
76
152
|
end
|
77
153
|
(c == 0x16 && @@input.raw(min: 0, tim: 0, &:getbyte)) || c
|
78
154
|
rescue Errno::EIO
|
79
155
|
# Maybe the I/O has been closed.
|
80
156
|
nil
|
157
|
+
rescue Errno::ENOTTY
|
158
|
+
nil
|
159
|
+
end
|
160
|
+
|
161
|
+
@@in_bracketed_paste_mode = false
|
162
|
+
START_BRACKETED_PASTE = String.new("\e[200~,", encoding: Encoding::ASCII_8BIT)
|
163
|
+
END_BRACKETED_PASTE = String.new("\e[200~.", encoding: Encoding::ASCII_8BIT)
|
164
|
+
def self.getc_with_bracketed_paste
|
165
|
+
buffer = String.new(encoding: Encoding::ASCII_8BIT)
|
166
|
+
buffer << inner_getc
|
167
|
+
while START_BRACKETED_PASTE.start_with?(buffer) or END_BRACKETED_PASTE.start_with?(buffer) do
|
168
|
+
if START_BRACKETED_PASTE == buffer
|
169
|
+
@@in_bracketed_paste_mode = true
|
170
|
+
return inner_getc
|
171
|
+
elsif END_BRACKETED_PASTE == buffer
|
172
|
+
@@in_bracketed_paste_mode = false
|
173
|
+
ungetc(-1)
|
174
|
+
return inner_getc
|
175
|
+
end
|
176
|
+
begin
|
177
|
+
succ_c = nil
|
178
|
+
Timeout.timeout(Reline.core.config.keyseq_timeout * 100) {
|
179
|
+
succ_c = inner_getc
|
180
|
+
}
|
181
|
+
rescue Timeout::Error
|
182
|
+
break
|
183
|
+
else
|
184
|
+
buffer << succ_c
|
185
|
+
end
|
186
|
+
end
|
187
|
+
buffer.bytes.reverse_each do |ch|
|
188
|
+
ungetc ch
|
189
|
+
end
|
190
|
+
inner_getc
|
191
|
+
end
|
192
|
+
|
193
|
+
def self.getc
|
194
|
+
if Reline.core.config.enable_bracketed_paste
|
195
|
+
getc_with_bracketed_paste
|
196
|
+
else
|
197
|
+
inner_getc
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def self.in_pasting?
|
202
|
+
@@in_bracketed_paste_mode or (not Reline::IOGate.empty_buffer?)
|
203
|
+
end
|
204
|
+
|
205
|
+
def self.empty_buffer?
|
206
|
+
unless @@buf.empty?
|
207
|
+
return false
|
208
|
+
end
|
209
|
+
!@@input.wait_readable(0)
|
81
210
|
end
|
82
211
|
|
83
212
|
def self.ungetc(c)
|
@@ -86,8 +215,7 @@ class Reline::ANSI
|
|
86
215
|
|
87
216
|
def self.retrieve_keybuffer
|
88
217
|
begin
|
89
|
-
|
90
|
-
return if result.nil?
|
218
|
+
return unless @@input.wait_readable(0.001)
|
91
219
|
str = @@input.read_nonblock(1024)
|
92
220
|
str.bytes.each do |c|
|
93
221
|
@@buf.push(c)
|
@@ -115,7 +243,7 @@ class Reline::ANSI
|
|
115
243
|
|
116
244
|
def self.cursor_pos
|
117
245
|
begin
|
118
|
-
res = ''
|
246
|
+
res = +''
|
119
247
|
m = nil
|
120
248
|
@@input.raw do |stdin|
|
121
249
|
@@output << "\e[6n"
|
@@ -154,7 +282,7 @@ class Reline::ANSI
|
|
154
282
|
|
155
283
|
def self.move_cursor_up(x)
|
156
284
|
if x > 0
|
157
|
-
@@output.write "\e[#{x}A"
|
285
|
+
@@output.write "\e[#{x}A"
|
158
286
|
elsif x < 0
|
159
287
|
move_cursor_down(-x)
|
160
288
|
end
|
@@ -162,12 +290,36 @@ class Reline::ANSI
|
|
162
290
|
|
163
291
|
def self.move_cursor_down(x)
|
164
292
|
if x > 0
|
165
|
-
@@output.write "\e[#{x}B"
|
293
|
+
@@output.write "\e[#{x}B"
|
166
294
|
elsif x < 0
|
167
295
|
move_cursor_up(-x)
|
168
296
|
end
|
169
297
|
end
|
170
298
|
|
299
|
+
def self.hide_cursor
|
300
|
+
if Reline::Terminfo.enabled?
|
301
|
+
begin
|
302
|
+
@@output.write Reline::Terminfo.tigetstr('civis')
|
303
|
+
rescue Reline::Terminfo::TerminfoError
|
304
|
+
# civis is undefined
|
305
|
+
end
|
306
|
+
else
|
307
|
+
# ignored
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
def self.show_cursor
|
312
|
+
if Reline::Terminfo.enabled?
|
313
|
+
begin
|
314
|
+
@@output.write Reline::Terminfo.tigetstr('cnorm')
|
315
|
+
rescue Reline::Terminfo::TerminfoError
|
316
|
+
# cnorm is undefined
|
317
|
+
end
|
318
|
+
else
|
319
|
+
# ignored
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
171
323
|
def self.erase_after_cursor
|
172
324
|
@@output.write "\e[K"
|
173
325
|
end
|
@@ -189,14 +341,10 @@ class Reline::ANSI
|
|
189
341
|
|
190
342
|
def self.prep
|
191
343
|
retrieve_keybuffer
|
192
|
-
int_handle = Signal.trap('INT', 'IGNORE')
|
193
|
-
Signal.trap('INT', int_handle)
|
194
344
|
nil
|
195
345
|
end
|
196
346
|
|
197
347
|
def self.deprep(otio)
|
198
|
-
int_handle = Signal.trap('INT', 'IGNORE')
|
199
|
-
Signal.trap('INT', int_handle)
|
200
348
|
Signal.trap('WINCH', @@old_winch_handler) if @@old_winch_handler
|
201
349
|
end
|
202
350
|
end
|
data/lib/reline/config.rb
CHANGED
@@ -34,9 +34,11 @@ class Reline::Config
|
|
34
34
|
show-all-if-unmodified
|
35
35
|
visible-stats
|
36
36
|
show-mode-in-prompt
|
37
|
-
vi-cmd-mode-
|
38
|
-
vi-ins-mode-
|
37
|
+
vi-cmd-mode-string
|
38
|
+
vi-ins-mode-string
|
39
39
|
emacs-mode-string
|
40
|
+
enable-bracketed-paste
|
41
|
+
isearch-terminators
|
40
42
|
}
|
41
43
|
VARIABLE_NAME_SYMBOLS = VARIABLE_NAMES.map { |v| :"#{v.tr(?-, ?_)}" }
|
42
44
|
VARIABLE_NAME_SYMBOLS.each do |v|
|
@@ -45,7 +47,10 @@ class Reline::Config
|
|
45
47
|
|
46
48
|
def initialize
|
47
49
|
@additional_key_bindings = {} # from inputrc
|
48
|
-
@
|
50
|
+
@additional_key_bindings[:emacs] = {}
|
51
|
+
@additional_key_bindings[:vi_insert] = {}
|
52
|
+
@additional_key_bindings[:vi_command] = {}
|
53
|
+
@oneshot_key_bindings = {}
|
49
54
|
@skip_section = nil
|
50
55
|
@if_stack = nil
|
51
56
|
@editing_mode_label = :emacs
|
@@ -54,21 +59,26 @@ class Reline::Config
|
|
54
59
|
@key_actors[:emacs] = Reline::KeyActor::Emacs.new
|
55
60
|
@key_actors[:vi_insert] = Reline::KeyActor::ViInsert.new
|
56
61
|
@key_actors[:vi_command] = Reline::KeyActor::ViCommand.new
|
57
|
-
@
|
58
|
-
@
|
62
|
+
@vi_cmd_mode_string = '(cmd)'
|
63
|
+
@vi_ins_mode_string = '(ins)'
|
59
64
|
@emacs_mode_string = '@'
|
60
65
|
# https://tiswww.case.edu/php/chet/readline/readline.html#IDX25
|
61
66
|
@history_size = -1 # unlimited
|
62
67
|
@keyseq_timeout = 500
|
63
68
|
@test_mode = false
|
69
|
+
@autocompletion = false
|
70
|
+
@convert_meta = true if seven_bit_encoding?(Reline::IOGate.encoding)
|
64
71
|
end
|
65
72
|
|
66
73
|
def reset
|
67
74
|
if editing_mode_is?(:vi_command)
|
68
75
|
@editing_mode_label = :vi_insert
|
69
76
|
end
|
70
|
-
@additional_key_bindings
|
71
|
-
|
77
|
+
@additional_key_bindings.keys.each do |key|
|
78
|
+
@additional_key_bindings[key].clear
|
79
|
+
end
|
80
|
+
@oneshot_key_bindings.clear
|
81
|
+
reset_default_key_bindings
|
72
82
|
end
|
73
83
|
|
74
84
|
def editing_mode
|
@@ -83,6 +93,14 @@ class Reline::Config
|
|
83
93
|
(val.respond_to?(:any?) ? val : [val]).any?(@editing_mode_label)
|
84
94
|
end
|
85
95
|
|
96
|
+
def autocompletion=(val)
|
97
|
+
@autocompletion = val
|
98
|
+
end
|
99
|
+
|
100
|
+
def autocompletion
|
101
|
+
@autocompletion
|
102
|
+
end
|
103
|
+
|
86
104
|
def keymap
|
87
105
|
@key_actors[@keymap_label]
|
88
106
|
end
|
@@ -113,8 +131,12 @@ class Reline::Config
|
|
113
131
|
return home_rc_path
|
114
132
|
end
|
115
133
|
|
134
|
+
private def default_inputrc_path
|
135
|
+
@default_inputrc_path ||= inputrc_path
|
136
|
+
end
|
137
|
+
|
116
138
|
def read(file = nil)
|
117
|
-
file ||=
|
139
|
+
file ||= default_inputrc_path
|
118
140
|
begin
|
119
141
|
if file.respond_to?(:readlines)
|
120
142
|
lines = file.readlines
|
@@ -133,19 +155,46 @@ class Reline::Config
|
|
133
155
|
end
|
134
156
|
|
135
157
|
def key_bindings
|
136
|
-
#
|
137
|
-
@default_key_bindings.
|
158
|
+
# The key bindings for each editing mode will be overwritten by the user-defined ones.
|
159
|
+
kb = @key_actors[@editing_mode_label].default_key_bindings.dup
|
160
|
+
kb.merge!(@additional_key_bindings[@editing_mode_label])
|
161
|
+
kb.merge!(@oneshot_key_bindings)
|
162
|
+
kb
|
163
|
+
end
|
164
|
+
|
165
|
+
def add_oneshot_key_binding(keystroke, target)
|
166
|
+
@oneshot_key_bindings[keystroke] = target
|
167
|
+
end
|
168
|
+
|
169
|
+
def reset_oneshot_key_bindings
|
170
|
+
@oneshot_key_bindings.clear
|
171
|
+
end
|
172
|
+
|
173
|
+
def add_default_key_binding_by_keymap(keymap, keystroke, target)
|
174
|
+
@key_actors[keymap].default_key_bindings[keystroke] = target
|
138
175
|
end
|
139
176
|
|
140
177
|
def add_default_key_binding(keystroke, target)
|
141
|
-
@default_key_bindings[keystroke] = target
|
178
|
+
@key_actors[@keymap_label].default_key_bindings[keystroke] = target
|
142
179
|
end
|
143
180
|
|
144
181
|
def reset_default_key_bindings
|
145
|
-
@
|
182
|
+
@key_actors.values.each do |ka|
|
183
|
+
ka.reset_default_key_bindings
|
184
|
+
end
|
146
185
|
end
|
147
186
|
|
148
187
|
def read_lines(lines, file = nil)
|
188
|
+
if not lines.empty? and lines.first.encoding != Reline.encoding_system_needs
|
189
|
+
begin
|
190
|
+
lines = lines.map do |l|
|
191
|
+
l.encode(Reline.encoding_system_needs)
|
192
|
+
rescue Encoding::UndefinedConversionError
|
193
|
+
mes = "The inputrc encoded in #{lines.first.encoding.name} can't be converted to the locale #{Reline.encoding_system_needs.name}."
|
194
|
+
raise Reline::ConfigEncodingConversionError.new(mes)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
149
198
|
conditions = [@skip_section, @if_stack]
|
150
199
|
@skip_section = nil
|
151
200
|
@if_stack = []
|
@@ -172,7 +221,7 @@ class Reline::Config
|
|
172
221
|
key, func_name = $1, $2
|
173
222
|
keystroke, func = bind_key(key, func_name)
|
174
223
|
next unless keystroke
|
175
|
-
@additional_key_bindings[keystroke] = func
|
224
|
+
@additional_key_bindings[@keymap_label][keystroke] = func
|
176
225
|
end
|
177
226
|
end
|
178
227
|
unless @if_stack.empty?
|
@@ -237,7 +286,7 @@ class Reline::Config
|
|
237
286
|
when 'completion-query-items'
|
238
287
|
@completion_query_items = value.to_i
|
239
288
|
when 'isearch-terminators'
|
240
|
-
@isearch_terminators =
|
289
|
+
@isearch_terminators = retrieve_string(value)
|
241
290
|
when 'editing-mode'
|
242
291
|
case value
|
243
292
|
when 'emacs'
|
@@ -268,9 +317,9 @@ class Reline::Config
|
|
268
317
|
@show_mode_in_prompt = false
|
269
318
|
end
|
270
319
|
when 'vi-cmd-mode-string'
|
271
|
-
@
|
320
|
+
@vi_cmd_mode_string = retrieve_string(value)
|
272
321
|
when 'vi-ins-mode-string'
|
273
|
-
@
|
322
|
+
@vi_ins_mode_string = retrieve_string(value)
|
274
323
|
when 'emacs-mode-string'
|
275
324
|
@emacs_mode_string = retrieve_string(value)
|
276
325
|
when *VARIABLE_NAMES then
|
@@ -280,11 +329,8 @@ class Reline::Config
|
|
280
329
|
end
|
281
330
|
|
282
331
|
def retrieve_string(str)
|
283
|
-
if str =~ /\A"(.*)"\z/
|
284
|
-
|
285
|
-
else
|
286
|
-
parse_keyseq(str).map(&:chr).join
|
287
|
-
end
|
332
|
+
str = $1 if str =~ /\A"(.*)"\z/
|
333
|
+
parse_keyseq(str).map { |c| c.chr(Reline.encoding_system_needs) }.join
|
288
334
|
end
|
289
335
|
|
290
336
|
def bind_key(key, func_name)
|
@@ -342,4 +388,8 @@ class Reline::Config
|
|
342
388
|
end
|
343
389
|
ret
|
344
390
|
end
|
391
|
+
|
392
|
+
private def seven_bit_encoding?(encoding)
|
393
|
+
encoding == Encoding::US_ASCII
|
394
|
+
end
|
345
395
|
end
|
data/lib/reline/general_io.rb
CHANGED
@@ -1,17 +1,31 @@
|
|
1
1
|
require 'timeout'
|
2
|
+
require 'io/wait'
|
2
3
|
|
3
4
|
class Reline::GeneralIO
|
5
|
+
def self.reset(encoding: nil)
|
6
|
+
@@pasting = false
|
7
|
+
@@encoding = encoding
|
8
|
+
end
|
9
|
+
|
4
10
|
def self.encoding
|
5
|
-
|
11
|
+
if defined?(@@encoding)
|
12
|
+
@@encoding
|
13
|
+
elsif RUBY_PLATFORM =~ /mswin|mingw/
|
14
|
+
Encoding::UTF_8
|
15
|
+
else
|
16
|
+
Encoding::default_external
|
17
|
+
end
|
6
18
|
end
|
7
19
|
|
8
20
|
def self.win?
|
9
21
|
false
|
10
22
|
end
|
11
23
|
|
12
|
-
|
24
|
+
def self.set_default_key_bindings(_)
|
25
|
+
end
|
13
26
|
|
14
27
|
@@buf = []
|
28
|
+
@@input = STDIN
|
15
29
|
|
16
30
|
def self.input=(val)
|
17
31
|
@@input = val
|
@@ -23,7 +37,7 @@ class Reline::GeneralIO
|
|
23
37
|
end
|
24
38
|
c = nil
|
25
39
|
loop do
|
26
|
-
result =
|
40
|
+
result = @@input.wait_readable(0.1)
|
27
41
|
next if result.nil?
|
28
42
|
c = @@input.read(1)
|
29
43
|
break
|
@@ -67,6 +81,20 @@ class Reline::GeneralIO
|
|
67
81
|
def self.set_winch_handler(&handler)
|
68
82
|
end
|
69
83
|
|
84
|
+
@@pasting = false
|
85
|
+
|
86
|
+
def self.in_pasting?
|
87
|
+
@@pasting
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.start_pasting
|
91
|
+
@@pasting = true
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.finish_pasting
|
95
|
+
@@pasting = false
|
96
|
+
end
|
97
|
+
|
70
98
|
def self.prep
|
71
99
|
end
|
72
100
|
|
@@ -4,4 +4,16 @@ class Reline::KeyActor::Base
|
|
4
4
|
def get_method(key)
|
5
5
|
self.class::MAPPING[key]
|
6
6
|
end
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@default_key_bindings = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def default_key_bindings
|
13
|
+
@default_key_bindings
|
14
|
+
end
|
15
|
+
|
16
|
+
def reset_default_key_bindings
|
17
|
+
@default_key_bindings.clear
|
18
|
+
end
|
7
19
|
end
|
@@ -43,7 +43,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|
43
43
|
# 20 ^T
|
44
44
|
:ed_transpose_chars,
|
45
45
|
# 21 ^U
|
46
|
-
:
|
46
|
+
:unix_line_discard,
|
47
47
|
# 22 ^V
|
48
48
|
:ed_quoted_insert,
|
49
49
|
# 23 ^W
|
@@ -307,7 +307,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|
307
307
|
# 152 M-^X
|
308
308
|
:ed_unassigned,
|
309
309
|
# 153 M-^Y
|
310
|
-
:
|
310
|
+
:em_yank_pop,
|
311
311
|
# 154 M-^Z
|
312
312
|
:ed_unassigned,
|
313
313
|
# 155 M-^[
|