reline 0.5.10 → 0.6.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/lib/reline/config.rb +22 -26
- data/lib/reline/history.rb +3 -3
- data/lib/reline/io/ansi.rb +70 -124
- data/lib/reline/io/dumb.rb +16 -2
- data/lib/reline/io/windows.rb +77 -60
- data/lib/reline/io.rb +14 -0
- data/lib/reline/key_actor/base.rb +10 -4
- data/lib/reline/key_actor/emacs.rb +96 -96
- data/lib/reline/key_actor/vi_command.rb +182 -182
- data/lib/reline/key_actor/vi_insert.rb +137 -137
- data/lib/reline/key_stroke.rb +26 -16
- data/lib/reline/line_editor.rb +295 -489
- data/lib/reline/unicode/east_asian_width.rb +41 -15
- data/lib/reline/unicode.rb +141 -397
- data/lib/reline/version.rb +1 -1
- data/lib/reline.rb +40 -31
- metadata +3 -4
- data/lib/reline/terminfo.rb +0 -158
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fb74f487afccdfb3b0530a043cfb7090f2a4860f2fdd168bc94112818b5f57d
|
4
|
+
data.tar.gz: 96b74e0f611f24022f204e9551d8692ef017c52a197ae169fbfdc1074a130857
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ffdcec13818f2445bd9f639e75b36405c76a439378335fa7c05fad90a26f06965e54cd9dce1b8e1411e16df9ffc80c3c0ac356320654af2ebd40a33fd28cb247
|
7
|
+
data.tar.gz: 24be10266aebce2d07f1519010f6ce0e6b92b816b17e526ede204943880b54388aa5ebf5da086bde0212b5e1f837936e4972c09a57a2d6c94f7c9a41412966d9
|
data/lib/reline/config.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
class Reline::Config
|
2
2
|
attr_reader :test_mode
|
3
3
|
|
4
|
-
KEYSEQ_PATTERN = /\\(?:C|Control)-[A-Za-z_]|\\(?:M|Meta)-[0-9A-Za-z_]|\\(?:C|Control)
|
4
|
+
KEYSEQ_PATTERN = /\\(?:C|Control)-[A-Za-z_]|\\(?:M|Meta)-[0-9A-Za-z_]|\\(?:C|Control)-\\(?:M|Meta)-[A-Za-z_]|\\(?:M|Meta)-\\(?:C|Control)-[A-Za-z_]|\\e|\\[\\\"\'abdfnrtv]|\\\d{1,3}|\\x\h{1,2}|./
|
5
5
|
|
6
6
|
class InvalidInputrc < RuntimeError
|
7
7
|
attr_accessor :file, :lineno
|
@@ -194,13 +194,14 @@ class Reline::Config
|
|
194
194
|
# value ignores everything after a space, raw_value does not.
|
195
195
|
var, value, raw_value = $1.downcase, $2.partition(' ').first, $2
|
196
196
|
bind_variable(var, value, raw_value)
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
197
|
+
when /^\s*(?:M|Meta)-([a-zA-Z_])\s*:\s*(.*)\s*$/o
|
198
|
+
bind_key("\"\\M-#$1\"", $2)
|
199
|
+
when /^\s*(?:C|Control)-([a-zA-Z_])\s*:\s*(.*)\s*$/o
|
200
|
+
bind_key("\"\\C-#$1\"", $2)
|
201
|
+
when /^\s*(?:(?:C|Control)-(?:M|Meta)|(?:M|Meta)-(?:C|Control))-([a-zA-Z_])\s*:\s*(.*)\s*$/o
|
202
|
+
bind_key("\"\\M-\\C-#$1\"", $2)
|
203
|
+
when /^\s*("#{KEYSEQ_PATTERN}+")\s*:\s*(.*)\s*$/o
|
204
|
+
bind_key($1, $2)
|
204
205
|
end
|
205
206
|
end
|
206
207
|
unless if_stack.empty?
|
@@ -310,7 +311,12 @@ class Reline::Config
|
|
310
311
|
parse_keyseq(str).map { |c| c.chr(Reline.encoding_system_needs) }.join
|
311
312
|
end
|
312
313
|
|
313
|
-
def bind_key(key,
|
314
|
+
def bind_key(key, value)
|
315
|
+
keystroke, func = parse_key_binding(key, value)
|
316
|
+
@additional_key_bindings[@keymap_label].add(@keymap_prefix + keystroke, func) if keystroke
|
317
|
+
end
|
318
|
+
|
319
|
+
def parse_key_binding(key, func_name)
|
314
320
|
if key =~ /\A"(.*)"\z/
|
315
321
|
keyseq = parse_keyseq($1)
|
316
322
|
else
|
@@ -319,27 +325,19 @@ class Reline::Config
|
|
319
325
|
if func_name =~ /"(.*)"/
|
320
326
|
func = parse_keyseq($1)
|
321
327
|
else
|
322
|
-
func = func_name.tr(?-, ?_).to_sym # It must be macro.
|
328
|
+
func = func_name.split.first.tr(?-, ?_).to_sym # It must be macro.
|
323
329
|
end
|
324
330
|
[keyseq, func]
|
325
331
|
end
|
326
332
|
|
327
333
|
def key_notation_to_code(notation)
|
328
334
|
case notation
|
335
|
+
when /(?:\\(?:C|Control)-\\(?:M|Meta)|\\(?:M|Meta)-\\(?:C|Control))-([A-Za-z_])/
|
336
|
+
[?\e.ord, $1.ord % 32]
|
329
337
|
when /\\(?:C|Control)-([A-Za-z_])/
|
330
|
-
(
|
338
|
+
($1.upcase.ord % 32)
|
331
339
|
when /\\(?:M|Meta)-([0-9A-Za-z_])/
|
332
|
-
|
333
|
-
case $1
|
334
|
-
when /[0-9]/
|
335
|
-
?\M-0.bytes.first + (modified_key.ord - ?0.ord)
|
336
|
-
when /[A-Z]/
|
337
|
-
?\M-A.bytes.first + (modified_key.ord - ?A.ord)
|
338
|
-
when /[a-z]/
|
339
|
-
?\M-a.bytes.first + (modified_key.ord - ?a.ord)
|
340
|
-
end
|
341
|
-
when /\\(?:C|Control)-(?:M|Meta)-[A-Za-z_]/, /\\(?:M|Meta)-(?:C|Control)-[A-Za-z_]/
|
342
|
-
# 129 M-^A
|
340
|
+
[?\e.ord, $1.ord]
|
343
341
|
when /\\(\d{1,3})/ then $1.to_i(8) # octal
|
344
342
|
when /\\x(\h{1,2})/ then $1.to_i(16) # hexadecimal
|
345
343
|
when "\\e" then ?\e.ord
|
@@ -359,11 +357,9 @@ class Reline::Config
|
|
359
357
|
end
|
360
358
|
|
361
359
|
def parse_keyseq(str)
|
362
|
-
|
363
|
-
|
364
|
-
ret << key_notation_to_code($&)
|
360
|
+
str.scan(KEYSEQ_PATTERN).flat_map do |notation|
|
361
|
+
key_notation_to_code(notation)
|
365
362
|
end
|
366
|
-
ret
|
367
363
|
end
|
368
364
|
|
369
365
|
def reload
|
data/lib/reline/history.rb
CHANGED
@@ -19,7 +19,7 @@ class Reline::History < Array
|
|
19
19
|
|
20
20
|
def []=(index, val)
|
21
21
|
index = check_index(index)
|
22
|
-
super(index,
|
22
|
+
super(index, Reline::Unicode.safe_encode(val, Reline.encoding_system_needs))
|
23
23
|
end
|
24
24
|
|
25
25
|
def concat(*val)
|
@@ -45,7 +45,7 @@ class Reline::History < Array
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
super(*(val.map{ |v|
|
48
|
-
|
48
|
+
Reline::Unicode.safe_encode(v, Reline.encoding_system_needs)
|
49
49
|
}))
|
50
50
|
end
|
51
51
|
|
@@ -56,7 +56,7 @@ class Reline::History < Array
|
|
56
56
|
if @config.history_size.positive?
|
57
57
|
shift if size + 1 > @config.history_size
|
58
58
|
end
|
59
|
-
super(
|
59
|
+
super(Reline::Unicode.safe_encode(val, Reline.encoding_system_needs))
|
60
60
|
end
|
61
61
|
|
62
62
|
private def check_index(index)
|
data/lib/reline/io/ansi.rb
CHANGED
@@ -2,18 +2,6 @@ require 'io/console'
|
|
2
2
|
require 'io/wait'
|
3
3
|
|
4
4
|
class Reline::ANSI < Reline::IO
|
5
|
-
CAPNAME_KEY_BINDINGS = {
|
6
|
-
'khome' => :ed_move_to_beg,
|
7
|
-
'kend' => :ed_move_to_end,
|
8
|
-
'kdch1' => :key_delete,
|
9
|
-
'kpp' => :ed_search_prev_history,
|
10
|
-
'knp' => :ed_search_next_history,
|
11
|
-
'kcuu1' => :ed_prev_history,
|
12
|
-
'kcud1' => :ed_next_history,
|
13
|
-
'kcuf1' => :ed_next_char,
|
14
|
-
'kcub1' => :ed_prev_char,
|
15
|
-
}
|
16
|
-
|
17
5
|
ANSI_CURSOR_KEY_BINDINGS = {
|
18
6
|
# Up
|
19
7
|
'A' => [:ed_prev_history, {}],
|
@@ -29,29 +17,27 @@ class Reline::ANSI < Reline::IO
|
|
29
17
|
'H' => [:ed_move_to_beg, {}],
|
30
18
|
}
|
31
19
|
|
32
|
-
|
33
|
-
Reline::Terminfo.setupterm(0, 2)
|
34
|
-
end
|
20
|
+
attr_writer :input, :output
|
35
21
|
|
36
22
|
def initialize
|
37
23
|
@input = STDIN
|
38
24
|
@output = STDOUT
|
39
25
|
@buf = []
|
26
|
+
@output_buffer = nil
|
40
27
|
@old_winch_handler = nil
|
41
28
|
end
|
42
29
|
|
43
30
|
def encoding
|
31
|
+
@input.external_encoding || Encoding.default_external
|
32
|
+
rescue IOError
|
33
|
+
# STDIN.external_encoding raises IOError in Ruby <= 3.0 when STDIN is closed
|
44
34
|
Encoding.default_external
|
45
35
|
end
|
46
36
|
|
47
|
-
def set_default_key_bindings(config
|
37
|
+
def set_default_key_bindings(config)
|
48
38
|
set_bracketed_paste_key_bindings(config)
|
49
39
|
set_default_key_bindings_ansi_cursor(config)
|
50
|
-
|
51
|
-
set_default_key_bindings_terminfo(config)
|
52
|
-
else
|
53
|
-
set_default_key_bindings_comprehensive_list(config)
|
54
|
-
end
|
40
|
+
set_default_key_bindings_comprehensive_list(config)
|
55
41
|
{
|
56
42
|
[27, 91, 90] => :completion_journey_up, # S-Tab
|
57
43
|
}.each_pair do |key, func|
|
@@ -75,7 +61,10 @@ class Reline::ANSI < Reline::IO
|
|
75
61
|
|
76
62
|
def set_default_key_bindings_ansi_cursor(config)
|
77
63
|
ANSI_CURSOR_KEY_BINDINGS.each do |char, (default_func, modifiers)|
|
78
|
-
bindings = [
|
64
|
+
bindings = [
|
65
|
+
["\e[#{char}", default_func], # CSI + char
|
66
|
+
["\eO#{char}", default_func] # SS3 + char, application cursor key mode
|
67
|
+
]
|
79
68
|
if modifiers[:ctrl]
|
80
69
|
# CSI + ctrl_key_modifier + char
|
81
70
|
bindings << ["\e[1;5#{char}", modifiers[:ctrl]]
|
@@ -95,23 +84,6 @@ class Reline::ANSI < Reline::IO
|
|
95
84
|
end
|
96
85
|
end
|
97
86
|
|
98
|
-
def set_default_key_bindings_terminfo(config)
|
99
|
-
key_bindings = CAPNAME_KEY_BINDINGS.map do |capname, key_binding|
|
100
|
-
begin
|
101
|
-
key_code = Reline::Terminfo.tigetstr(capname)
|
102
|
-
[ key_code.bytes, key_binding ]
|
103
|
-
rescue Reline::Terminfo::TerminfoError
|
104
|
-
# capname is undefined
|
105
|
-
end
|
106
|
-
end.compact.to_h
|
107
|
-
|
108
|
-
key_bindings.each_pair do |key, func|
|
109
|
-
config.add_default_key_binding_by_keymap(:emacs, key, func)
|
110
|
-
config.add_default_key_binding_by_keymap(:vi_insert, key, func)
|
111
|
-
config.add_default_key_binding_by_keymap(:vi_command, key, func)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
87
|
def set_default_key_bindings_comprehensive_list(config)
|
116
88
|
{
|
117
89
|
# xterm
|
@@ -123,27 +95,9 @@ class Reline::ANSI < Reline::IO
|
|
123
95
|
[27, 91, 49, 126] => :ed_move_to_beg, # Home
|
124
96
|
[27, 91, 52, 126] => :ed_move_to_end, # End
|
125
97
|
|
126
|
-
# KDE
|
127
|
-
# Del is 0x08
|
128
|
-
[27, 71, 65] => :ed_prev_history, # ↑
|
129
|
-
[27, 71, 66] => :ed_next_history, # ↓
|
130
|
-
[27, 71, 67] => :ed_next_char, # →
|
131
|
-
[27, 71, 68] => :ed_prev_char, # ←
|
132
|
-
|
133
98
|
# urxvt / exoterm
|
134
99
|
[27, 91, 55, 126] => :ed_move_to_beg, # Home
|
135
100
|
[27, 91, 56, 126] => :ed_move_to_end, # End
|
136
|
-
|
137
|
-
# GNOME
|
138
|
-
[27, 79, 72] => :ed_move_to_beg, # Home
|
139
|
-
[27, 79, 70] => :ed_move_to_end, # End
|
140
|
-
# Del is 0x08
|
141
|
-
# Arrow keys are the same of KDE
|
142
|
-
|
143
|
-
[27, 79, 65] => :ed_prev_history, # ↑
|
144
|
-
[27, 79, 66] => :ed_next_history, # ↓
|
145
|
-
[27, 79, 67] => :ed_next_char, # →
|
146
|
-
[27, 79, 68] => :ed_prev_char, # ←
|
147
101
|
}.each_pair do |key, func|
|
148
102
|
config.add_default_key_binding_by_keymap(:emacs, key, func)
|
149
103
|
config.add_default_key_binding_by_keymap(:vi_insert, key, func)
|
@@ -151,14 +105,6 @@ class Reline::ANSI < Reline::IO
|
|
151
105
|
end
|
152
106
|
end
|
153
107
|
|
154
|
-
def input=(val)
|
155
|
-
@input = val
|
156
|
-
end
|
157
|
-
|
158
|
-
def output=(val)
|
159
|
-
@output = val
|
160
|
-
end
|
161
|
-
|
162
108
|
def with_raw_input
|
163
109
|
if @input.tty?
|
164
110
|
@input.raw(intr: true) { yield }
|
@@ -245,52 +191,57 @@ class Reline::ANSI < Reline::IO
|
|
245
191
|
self
|
246
192
|
end
|
247
193
|
|
248
|
-
def
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
@
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
break if m
|
194
|
+
private def cursor_pos_internal(timeout:)
|
195
|
+
match = nil
|
196
|
+
@input.raw do |stdin|
|
197
|
+
@output << "\e[6n"
|
198
|
+
@output.flush
|
199
|
+
timeout_at = Time.now + timeout
|
200
|
+
buf = +''
|
201
|
+
while (wait = timeout_at - Time.now) > 0 && stdin.wait_readable(wait)
|
202
|
+
buf << stdin.readpartial(1024)
|
203
|
+
if (match = buf.match(/\e\[(?<row>\d+);(?<column>\d+)R/))
|
204
|
+
buf = match.pre_match + match.post_match
|
205
|
+
break
|
261
206
|
end
|
262
|
-
(m.pre_match + m.post_match).chars.reverse_each do |ch|
|
263
|
-
stdin.ungetc ch
|
264
|
-
end
|
265
|
-
end
|
266
|
-
column = m[:column].to_i - 1
|
267
|
-
row = m[:row].to_i - 1
|
268
|
-
else
|
269
|
-
begin
|
270
|
-
buf = @output.pread(@output.pos, 0)
|
271
|
-
row = buf.count("\n")
|
272
|
-
column = buf.rindex("\n") ? (buf.size - buf.rindex("\n")) - 1 : 0
|
273
|
-
rescue Errno::ESPIPE, IOError
|
274
|
-
# Just returns column 1 for ambiguous width because this I/O is not
|
275
|
-
# tty and can't seek.
|
276
|
-
row = 0
|
277
|
-
column = 1
|
278
207
|
end
|
208
|
+
@buf.concat buf.bytes
|
279
209
|
end
|
280
|
-
|
210
|
+
[match[:column].to_i - 1, match[:row].to_i - 1] if match
|
211
|
+
end
|
212
|
+
|
213
|
+
def cursor_pos
|
214
|
+
col, row = cursor_pos_internal(timeout: 0.5) if both_tty?
|
215
|
+
Reline::CursorPos.new(col || 0, row || 0)
|
281
216
|
end
|
282
217
|
|
283
218
|
def both_tty?
|
284
219
|
@input.tty? && @output.tty?
|
285
220
|
end
|
286
221
|
|
222
|
+
def write(string)
|
223
|
+
if @output_buffer
|
224
|
+
@output_buffer << string
|
225
|
+
else
|
226
|
+
@output.write(string)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def buffered_output
|
231
|
+
@output_buffer = +''
|
232
|
+
yield
|
233
|
+
@output.write(@output_buffer)
|
234
|
+
ensure
|
235
|
+
@output_buffer = nil
|
236
|
+
end
|
237
|
+
|
287
238
|
def move_cursor_column(x)
|
288
|
-
|
239
|
+
write "\e[#{x + 1}G"
|
289
240
|
end
|
290
241
|
|
291
242
|
def move_cursor_up(x)
|
292
243
|
if x > 0
|
293
|
-
|
244
|
+
write "\e[#{x}A"
|
294
245
|
elsif x < 0
|
295
246
|
move_cursor_down(-x)
|
296
247
|
end
|
@@ -298,38 +249,22 @@ class Reline::ANSI < Reline::IO
|
|
298
249
|
|
299
250
|
def move_cursor_down(x)
|
300
251
|
if x > 0
|
301
|
-
|
252
|
+
write "\e[#{x}B"
|
302
253
|
elsif x < 0
|
303
254
|
move_cursor_up(-x)
|
304
255
|
end
|
305
256
|
end
|
306
257
|
|
307
258
|
def hide_cursor
|
308
|
-
|
309
|
-
if Reline::Terminfo.enabled? && Reline::Terminfo.term_supported?
|
310
|
-
begin
|
311
|
-
seq = Reline::Terminfo.tigetstr('civis')
|
312
|
-
rescue Reline::Terminfo::TerminfoError
|
313
|
-
# civis is undefined
|
314
|
-
end
|
315
|
-
end
|
316
|
-
@output.write seq
|
259
|
+
write "\e[?25l"
|
317
260
|
end
|
318
261
|
|
319
262
|
def show_cursor
|
320
|
-
|
321
|
-
if Reline::Terminfo.enabled? && Reline::Terminfo.term_supported?
|
322
|
-
begin
|
323
|
-
seq = Reline::Terminfo.tigetstr('cnorm')
|
324
|
-
rescue Reline::Terminfo::TerminfoError
|
325
|
-
# cnorm is undefined
|
326
|
-
end
|
327
|
-
end
|
328
|
-
@output.write seq
|
263
|
+
write "\e[?25h"
|
329
264
|
end
|
330
265
|
|
331
266
|
def erase_after_cursor
|
332
|
-
|
267
|
+
write "\e[K"
|
333
268
|
end
|
334
269
|
|
335
270
|
# This only works when the cursor is at the bottom of the scroll range
|
@@ -337,35 +272,46 @@ class Reline::ANSI < Reline::IO
|
|
337
272
|
def scroll_down(x)
|
338
273
|
return if x.zero?
|
339
274
|
# We use `\n` instead of CSI + S because CSI + S would cause https://github.com/ruby/reline/issues/576
|
340
|
-
|
275
|
+
write "\n" * x
|
341
276
|
end
|
342
277
|
|
343
278
|
def clear_screen
|
344
|
-
|
345
|
-
|
279
|
+
write "\e[2J"
|
280
|
+
write "\e[1;1H"
|
346
281
|
end
|
347
282
|
|
348
283
|
def set_winch_handler(&handler)
|
349
|
-
@old_winch_handler = Signal.trap('WINCH'
|
350
|
-
|
284
|
+
@old_winch_handler = Signal.trap('WINCH') do |arg|
|
285
|
+
handler.call
|
286
|
+
@old_winch_handler.call(arg) if @old_winch_handler.respond_to?(:call)
|
287
|
+
end
|
288
|
+
@old_cont_handler = Signal.trap('CONT') do |arg|
|
351
289
|
@input.raw!(intr: true) if @input.tty?
|
352
290
|
# Rerender the screen. Note that screen size might be changed while suspended.
|
353
291
|
handler.call
|
292
|
+
@old_cont_handler.call(arg) if @old_cont_handler.respond_to?(:call)
|
354
293
|
end
|
355
294
|
rescue ArgumentError
|
356
295
|
# Signal.trap may raise an ArgumentError if the platform doesn't support the signal.
|
357
296
|
end
|
358
297
|
|
298
|
+
def read_single_char(keyseq_timeout)
|
299
|
+
# Disable intr to read `C-c` `C-z` `C-\` for quoted insert
|
300
|
+
@input.raw(intr: false) do
|
301
|
+
super
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
359
305
|
def prep
|
360
306
|
# Enable bracketed paste
|
361
|
-
|
307
|
+
write "\e[?2004h" if Reline.core.config.enable_bracketed_paste && both_tty?
|
362
308
|
retrieve_keybuffer
|
363
309
|
nil
|
364
310
|
end
|
365
311
|
|
366
312
|
def deprep(otio)
|
367
313
|
# Disable bracketed paste
|
368
|
-
|
314
|
+
write "\e[?2004l" if Reline.core.config.enable_bracketed_paste && both_tty?
|
369
315
|
Signal.trap('WINCH', @old_winch_handler) if @old_winch_handler
|
370
316
|
Signal.trap('CONT', @old_cont_handler) if @old_cont_handler
|
371
317
|
end
|
data/lib/reline/io/dumb.rb
CHANGED
@@ -3,8 +3,11 @@ require 'io/wait'
|
|
3
3
|
class Reline::Dumb < Reline::IO
|
4
4
|
RESET_COLOR = '' # Do not send color reset sequence
|
5
5
|
|
6
|
+
attr_writer :output
|
7
|
+
|
6
8
|
def initialize(encoding: nil)
|
7
9
|
@input = STDIN
|
10
|
+
@output = STDOUT
|
8
11
|
@buf = []
|
9
12
|
@pasting = false
|
10
13
|
@encoding = encoding
|
@@ -21,8 +24,11 @@ class Reline::Dumb < Reline::IO
|
|
21
24
|
elsif RUBY_PLATFORM =~ /mswin|mingw/
|
22
25
|
Encoding::UTF_8
|
23
26
|
else
|
24
|
-
Encoding
|
27
|
+
@input.external_encoding || Encoding.default_external
|
25
28
|
end
|
29
|
+
rescue IOError
|
30
|
+
# STDIN.external_encoding raises IOError in Ruby <= 3.0 when STDIN is closed
|
31
|
+
Encoding.default_external
|
26
32
|
end
|
27
33
|
|
28
34
|
def set_default_key_bindings(_)
|
@@ -36,6 +42,14 @@ class Reline::Dumb < Reline::IO
|
|
36
42
|
yield
|
37
43
|
end
|
38
44
|
|
45
|
+
def write(string)
|
46
|
+
@output.write(string)
|
47
|
+
end
|
48
|
+
|
49
|
+
def buffered_output
|
50
|
+
yield
|
51
|
+
end
|
52
|
+
|
39
53
|
def getc(_timeout_second)
|
40
54
|
unless @buf.empty?
|
41
55
|
return @buf.shift
|
@@ -60,7 +74,7 @@ class Reline::Dumb < Reline::IO
|
|
60
74
|
end
|
61
75
|
|
62
76
|
def cursor_pos
|
63
|
-
Reline::CursorPos.new(
|
77
|
+
Reline::CursorPos.new(0, 0)
|
64
78
|
end
|
65
79
|
|
66
80
|
def hide_cursor
|