reline 0.3.2 → 0.5.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +33 -2
- data/lib/reline/config.rb +58 -77
- data/lib/reline/face.rb +199 -0
- data/lib/reline/history.rb +1 -1
- data/lib/reline/io/ansi.rb +364 -0
- data/lib/reline/io/dumb.rb +106 -0
- data/lib/reline/{windows.rb → io/windows.rb} +108 -102
- data/lib/reline/io.rb +41 -0
- data/lib/reline/key_actor/base.rb +20 -8
- data/lib/reline/key_actor/composite.rb +17 -0
- data/lib/reline/key_actor/emacs.rb +15 -15
- data/lib/reline/key_actor/vi_command.rb +25 -25
- data/lib/reline/key_actor/vi_insert.rb +7 -7
- data/lib/reline/key_actor.rb +1 -0
- data/lib/reline/key_stroke.rb +88 -84
- data/lib/reline/kill_ring.rb +2 -2
- data/lib/reline/line_editor.rb +1095 -1895
- data/lib/reline/terminfo.rb +13 -29
- data/lib/reline/unicode/east_asian_width.rb +91 -59
- data/lib/reline/unicode.rb +95 -64
- data/lib/reline/version.rb +1 -1
- data/lib/reline.rb +156 -240
- metadata +13 -7
- data/lib/reline/ansi.rb +0 -350
- data/lib/reline/general_io.rb +0 -109
data/lib/reline.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'io/console'
|
2
|
-
require 'timeout'
|
3
2
|
require 'forwardable'
|
4
3
|
require 'reline/version'
|
5
4
|
require 'reline/config'
|
@@ -8,38 +7,29 @@ require 'reline/key_stroke'
|
|
8
7
|
require 'reline/line_editor'
|
9
8
|
require 'reline/history'
|
10
9
|
require 'reline/terminfo'
|
10
|
+
require 'reline/io'
|
11
|
+
require 'reline/face'
|
11
12
|
require 'rbconfig'
|
12
13
|
|
13
14
|
module Reline
|
15
|
+
# NOTE: For making compatible with the rb-readline gem
|
14
16
|
FILENAME_COMPLETION_PROC = nil
|
15
17
|
USERNAME_COMPLETION_PROC = nil
|
16
18
|
|
17
19
|
class ConfigEncodingConversionError < StandardError; end
|
18
20
|
|
19
|
-
Key = Struct.new(
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
(other.char.nil? or char.nil? or char == other.char) and
|
24
|
-
(other.combined_char.nil? or combined_char.nil? or combined_char == other.combined_char) and
|
25
|
-
(other.with_meta.nil? or with_meta.nil? or with_meta == other.with_meta)
|
26
|
-
when Integer, Symbol
|
27
|
-
(combined_char and combined_char == other) or
|
28
|
-
(combined_char.nil? and char and char == other)
|
29
|
-
else
|
30
|
-
false
|
31
|
-
end
|
21
|
+
Key = Struct.new(:char, :combined_char, :with_meta) do
|
22
|
+
# For dialog_proc `key.match?(dialog.name)`
|
23
|
+
def match?(sym)
|
24
|
+
combined_char.is_a?(Symbol) && combined_char == sym
|
32
25
|
end
|
33
|
-
alias_method :==, :match?
|
34
26
|
end
|
35
27
|
CursorPos = Struct.new(:x, :y)
|
36
28
|
DialogRenderInfo = Struct.new(
|
37
29
|
:pos,
|
38
30
|
:contents,
|
39
|
-
:
|
40
|
-
:
|
41
|
-
:fg_color,
|
42
|
-
:pointer_fg_color,
|
31
|
+
:face,
|
32
|
+
:bg_color, # For the time being, this line should stay here for the compatibility with IRB.
|
43
33
|
:width,
|
44
34
|
:height,
|
45
35
|
:scrollbar,
|
@@ -76,50 +66,54 @@ module Reline
|
|
76
66
|
|
77
67
|
def initialize
|
78
68
|
self.output = STDOUT
|
69
|
+
@mutex = Mutex.new
|
79
70
|
@dialog_proc_list = {}
|
80
71
|
yield self
|
81
72
|
@completion_quote_character = nil
|
82
|
-
|
73
|
+
end
|
74
|
+
|
75
|
+
def io_gate
|
76
|
+
Reline::IOGate
|
83
77
|
end
|
84
78
|
|
85
79
|
def encoding
|
86
|
-
|
80
|
+
io_gate.encoding
|
87
81
|
end
|
88
82
|
|
89
83
|
def completion_append_character=(val)
|
90
84
|
if val.nil?
|
91
85
|
@completion_append_character = nil
|
92
86
|
elsif val.size == 1
|
93
|
-
@completion_append_character = val.encode(
|
87
|
+
@completion_append_character = val.encode(encoding)
|
94
88
|
elsif val.size > 1
|
95
|
-
@completion_append_character = val[0].encode(
|
89
|
+
@completion_append_character = val[0].encode(encoding)
|
96
90
|
else
|
97
91
|
@completion_append_character = nil
|
98
92
|
end
|
99
93
|
end
|
100
94
|
|
101
95
|
def basic_word_break_characters=(v)
|
102
|
-
@basic_word_break_characters = v.encode(
|
96
|
+
@basic_word_break_characters = v.encode(encoding)
|
103
97
|
end
|
104
98
|
|
105
99
|
def completer_word_break_characters=(v)
|
106
|
-
@completer_word_break_characters = v.encode(
|
100
|
+
@completer_word_break_characters = v.encode(encoding)
|
107
101
|
end
|
108
102
|
|
109
103
|
def basic_quote_characters=(v)
|
110
|
-
@basic_quote_characters = v.encode(
|
104
|
+
@basic_quote_characters = v.encode(encoding)
|
111
105
|
end
|
112
106
|
|
113
107
|
def completer_quote_characters=(v)
|
114
|
-
@completer_quote_characters = v.encode(
|
108
|
+
@completer_quote_characters = v.encode(encoding)
|
115
109
|
end
|
116
110
|
|
117
111
|
def filename_quote_characters=(v)
|
118
|
-
@filename_quote_characters = v.encode(
|
112
|
+
@filename_quote_characters = v.encode(encoding)
|
119
113
|
end
|
120
114
|
|
121
115
|
def special_prefixes=(v)
|
122
|
-
@special_prefixes = v.encode(
|
116
|
+
@special_prefixes = v.encode(encoding)
|
123
117
|
end
|
124
118
|
|
125
119
|
def completion_case_fold=(v)
|
@@ -165,9 +159,13 @@ module Reline
|
|
165
159
|
|
166
160
|
DialogProc = Struct.new(:dialog_proc, :context)
|
167
161
|
def add_dialog_proc(name_sym, p, context = nil)
|
168
|
-
raise ArgumentError unless p.respond_to?(:call) or p.nil?
|
169
162
|
raise ArgumentError unless name_sym.instance_of?(Symbol)
|
170
|
-
|
163
|
+
if p.nil?
|
164
|
+
@dialog_proc_list.delete(name_sym)
|
165
|
+
else
|
166
|
+
raise ArgumentError unless p.respond_to?(:call)
|
167
|
+
@dialog_proc_list[name_sym] = DialogProc.new(p, context)
|
168
|
+
end
|
171
169
|
end
|
172
170
|
|
173
171
|
def dialog_proc(name_sym)
|
@@ -176,20 +174,16 @@ module Reline
|
|
176
174
|
|
177
175
|
def input=(val)
|
178
176
|
raise TypeError unless val.respond_to?(:getc) or val.nil?
|
179
|
-
if val.respond_to?(:getc)
|
180
|
-
|
181
|
-
Reline::ANSI.input = val
|
182
|
-
elsif Reline::IOGate == Reline::GeneralIO
|
183
|
-
Reline::GeneralIO.input = val
|
184
|
-
end
|
177
|
+
if val.respond_to?(:getc) && io_gate.respond_to?(:input=)
|
178
|
+
io_gate.input = val
|
185
179
|
end
|
186
180
|
end
|
187
181
|
|
188
182
|
def output=(val)
|
189
183
|
raise TypeError unless val.respond_to?(:write) or val.nil?
|
190
184
|
@output = val
|
191
|
-
if
|
192
|
-
|
185
|
+
if io_gate.respond_to?(:output=)
|
186
|
+
io_gate.output = val
|
193
187
|
end
|
194
188
|
end
|
195
189
|
|
@@ -212,37 +206,30 @@ module Reline
|
|
212
206
|
end
|
213
207
|
|
214
208
|
def get_screen_size
|
215
|
-
|
209
|
+
io_gate.get_screen_size
|
216
210
|
end
|
217
211
|
|
218
212
|
Reline::DEFAULT_DIALOG_PROC_AUTOCOMPLETE = ->() {
|
219
213
|
# autocomplete
|
220
|
-
return
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
if
|
230
|
-
|
231
|
-
result.shift
|
232
|
-
pointer = completion_journey_data.pointer - 1
|
233
|
-
else
|
234
|
-
result = call_completion_proc_with_checking_args(pre, target, post)
|
235
|
-
pointer = nil
|
236
|
-
end
|
237
|
-
if result and result.size == 1 and result[0] == target and pointer != 0
|
238
|
-
result = nil
|
239
|
-
end
|
214
|
+
return unless config.autocompletion
|
215
|
+
|
216
|
+
journey_data = completion_journey_data
|
217
|
+
return unless journey_data
|
218
|
+
|
219
|
+
target = journey_data.list.first
|
220
|
+
completed = journey_data.list[journey_data.pointer]
|
221
|
+
result = journey_data.list.drop(1)
|
222
|
+
pointer = journey_data.pointer - 1
|
223
|
+
return if completed.empty? || (result == [completed] && pointer < 0)
|
224
|
+
|
240
225
|
target_width = Reline::Unicode.calculate_width(target)
|
241
|
-
|
242
|
-
if x
|
243
|
-
|
226
|
+
completed_width = Reline::Unicode.calculate_width(completed)
|
227
|
+
if cursor_pos.x <= completed_width - target_width
|
228
|
+
# When target is rendered on the line above cursor position
|
229
|
+
x = screen_width - completed_width
|
244
230
|
y = -1
|
245
231
|
else
|
232
|
+
x = [cursor_pos.x - completed_width, 0].max
|
246
233
|
y = 0
|
247
234
|
end
|
248
235
|
cursor_pos_to_render = Reline::CursorPos.new(x, y)
|
@@ -255,47 +242,58 @@ module Reline
|
|
255
242
|
pos: cursor_pos_to_render,
|
256
243
|
contents: result,
|
257
244
|
scrollbar: true,
|
258
|
-
height: 15,
|
259
|
-
|
260
|
-
pointer_bg_color: 45,
|
261
|
-
fg_color: 37,
|
262
|
-
pointer_fg_color: 37
|
245
|
+
height: [15, preferred_dialog_height].min,
|
246
|
+
face: :completion_dialog
|
263
247
|
)
|
264
248
|
}
|
265
249
|
Reline::DEFAULT_DIALOG_CONTEXT = Array.new
|
266
250
|
|
267
251
|
def readmultiline(prompt = '', add_hist = false, &confirm_multiline_termination)
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
252
|
+
@mutex.synchronize do
|
253
|
+
unless confirm_multiline_termination
|
254
|
+
raise ArgumentError.new('#readmultiline needs block to confirm multiline termination')
|
255
|
+
end
|
272
256
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
257
|
+
io_gate.with_raw_input do
|
258
|
+
inner_readline(prompt, add_hist, true, &confirm_multiline_termination)
|
259
|
+
end
|
260
|
+
|
261
|
+
whole_buffer = line_editor.whole_buffer.dup
|
262
|
+
whole_buffer.taint if RUBY_VERSION < '2.7'
|
263
|
+
if add_hist and whole_buffer and whole_buffer.chomp("\n").size > 0
|
264
|
+
Reline::HISTORY << whole_buffer
|
265
|
+
end
|
278
266
|
|
279
|
-
|
280
|
-
|
267
|
+
if line_editor.eof?
|
268
|
+
line_editor.reset_line
|
269
|
+
# Return nil if the input is aborted by C-d.
|
270
|
+
nil
|
271
|
+
else
|
272
|
+
whole_buffer
|
273
|
+
end
|
274
|
+
end
|
281
275
|
end
|
282
276
|
|
283
277
|
def readline(prompt = '', add_hist = false)
|
284
|
-
|
278
|
+
@mutex.synchronize do
|
279
|
+
io_gate.with_raw_input do
|
280
|
+
inner_readline(prompt, add_hist, false)
|
281
|
+
end
|
285
282
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
283
|
+
line = line_editor.line.dup
|
284
|
+
line.taint if RUBY_VERSION < '2.7'
|
285
|
+
if add_hist and line and line.chomp("\n").size > 0
|
286
|
+
Reline::HISTORY << line.chomp("\n")
|
287
|
+
end
|
291
288
|
|
292
|
-
|
293
|
-
|
289
|
+
line_editor.reset_line if line_editor.line.nil?
|
290
|
+
line
|
291
|
+
end
|
294
292
|
end
|
295
293
|
|
296
294
|
private def inner_readline(prompt, add_hist, multiline, &confirm_multiline_termination)
|
297
295
|
if ENV['RELINE_STDERR_TTY']
|
298
|
-
if
|
296
|
+
if io_gate.win?
|
299
297
|
$stderr = File.open(ENV['RELINE_STDERR_TTY'], 'a')
|
300
298
|
else
|
301
299
|
$stderr.reopen(ENV['RELINE_STDERR_TTY'], 'w')
|
@@ -303,10 +301,14 @@ module Reline
|
|
303
301
|
$stderr.sync = true
|
304
302
|
$stderr.puts "Reline is used by #{Process.pid}"
|
305
303
|
end
|
306
|
-
|
304
|
+
unless config.test_mode or config.loaded?
|
305
|
+
config.read
|
306
|
+
io_gate.set_default_key_bindings(config)
|
307
|
+
end
|
308
|
+
otio = io_gate.prep
|
307
309
|
|
308
310
|
may_req_ambiguous_char_width
|
309
|
-
line_editor.reset(prompt, encoding:
|
311
|
+
line_editor.reset(prompt, encoding: encoding)
|
310
312
|
if multiline
|
311
313
|
line_editor.multiline_on
|
312
314
|
if block_given?
|
@@ -322,157 +324,81 @@ module Reline
|
|
322
324
|
line_editor.prompt_proc = prompt_proc
|
323
325
|
line_editor.auto_indent_proc = auto_indent_proc
|
324
326
|
line_editor.dig_perfect_match_proc = dig_perfect_match_proc
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
unless config.test_mode
|
331
|
-
config.read
|
332
|
-
config.reset_default_key_bindings
|
333
|
-
Reline::IOGate.set_default_key_bindings(config)
|
327
|
+
pre_input_hook&.call
|
328
|
+
unless Reline::IOGate.dumb?
|
329
|
+
@dialog_proc_list.each_pair do |name_sym, d|
|
330
|
+
line_editor.add_dialog_proc(name_sym, d.dialog_proc, d.context)
|
331
|
+
end
|
334
332
|
end
|
335
333
|
|
334
|
+
line_editor.print_nomultiline_prompt(prompt)
|
335
|
+
line_editor.update_dialogs
|
336
336
|
line_editor.rerender
|
337
337
|
|
338
338
|
begin
|
339
339
|
line_editor.set_signal_handlers
|
340
|
-
prev_pasting_state = false
|
341
340
|
loop do
|
342
|
-
prev_pasting_state = Reline::IOGate.in_pasting?
|
343
341
|
read_io(config.keyseq_timeout) { |inputs|
|
344
|
-
line_editor.set_pasting_state(
|
345
|
-
inputs.each
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
342
|
+
line_editor.set_pasting_state(io_gate.in_pasting?)
|
343
|
+
inputs.each do |key|
|
344
|
+
if key.char == :bracketed_paste_start
|
345
|
+
text = io_gate.read_bracketed_paste
|
346
|
+
line_editor.insert_pasted_text(text)
|
347
|
+
line_editor.scroll_into_view
|
348
|
+
else
|
349
|
+
line_editor.update(key)
|
350
|
+
end
|
352
351
|
end
|
353
352
|
}
|
354
|
-
if
|
355
|
-
line_editor.
|
356
|
-
|
357
|
-
|
353
|
+
if line_editor.finished?
|
354
|
+
line_editor.render_finished
|
355
|
+
break
|
356
|
+
else
|
357
|
+
line_editor.set_pasting_state(io_gate.in_pasting?)
|
358
|
+
line_editor.rerender
|
358
359
|
end
|
359
|
-
break if line_editor.finished?
|
360
360
|
end
|
361
|
-
|
361
|
+
io_gate.move_cursor_column(0)
|
362
362
|
rescue Errno::EIO
|
363
363
|
# Maybe the I/O has been closed.
|
364
|
-
|
364
|
+
ensure
|
365
365
|
line_editor.finalize
|
366
|
-
|
367
|
-
raise e
|
368
|
-
rescue Exception
|
369
|
-
# Including Interrupt
|
370
|
-
line_editor.finalize
|
371
|
-
Reline::IOGate.deprep(otio)
|
372
|
-
raise
|
366
|
+
io_gate.deprep(otio)
|
373
367
|
end
|
374
|
-
|
375
|
-
line_editor.finalize
|
376
|
-
Reline::IOGate.deprep(otio)
|
377
368
|
end
|
378
369
|
|
379
|
-
# GNU Readline
|
380
|
-
#
|
381
|
-
#
|
382
|
-
#
|
383
|
-
#
|
384
|
-
#
|
385
|
-
#
|
386
|
-
# GNU Readline will wait for the 2nd character with "keyseq-timeout"
|
387
|
-
# milli-seconds but wait forever after 3rd characters.
|
370
|
+
# GNU Readline watis for "keyseq-timeout" milliseconds when the input is
|
371
|
+
# ambiguous whether it is matching or matched.
|
372
|
+
# If the next character does not arrive within the specified timeout, input
|
373
|
+
# is considered as matched.
|
374
|
+
# `ESC` is ambiguous because it can be a standalone ESC (matched) or part of
|
375
|
+
# `ESC char` or part of CSI sequence (matching).
|
388
376
|
private def read_io(keyseq_timeout, &block)
|
389
377
|
buffer = []
|
378
|
+
status = KeyStroke::MATCHING
|
390
379
|
loop do
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
buffer
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
when :matched
|
401
|
-
expanded = key_stroke.expand(buffer).map{ |expanded_c|
|
402
|
-
Reline::Key.new(expanded_c, expanded_c, false)
|
403
|
-
}
|
404
|
-
block.(expanded)
|
405
|
-
break
|
406
|
-
when :matching
|
407
|
-
if buffer.size == 1
|
408
|
-
case read_2nd_character_of_key_sequence(keyseq_timeout, buffer, c, block)
|
409
|
-
when :break then break
|
410
|
-
when :next then next
|
411
|
-
end
|
412
|
-
end
|
413
|
-
when :unmatched
|
414
|
-
if buffer.size == 1 and c == "\e".ord
|
415
|
-
read_escaped_key(keyseq_timeout, c, block)
|
380
|
+
timeout = status == KeyStroke::MATCHING_MATCHED ? keyseq_timeout.fdiv(1000) : Float::INFINITY
|
381
|
+
c = io_gate.getc(timeout)
|
382
|
+
if c.nil? || c == -1
|
383
|
+
if status == KeyStroke::MATCHING_MATCHED
|
384
|
+
status = KeyStroke::MATCHED
|
385
|
+
elsif buffer.empty?
|
386
|
+
# io_gate is closed and reached EOF
|
387
|
+
block.call([Key.new(nil, nil, false)])
|
388
|
+
return
|
416
389
|
else
|
417
|
-
|
418
|
-
Reline::Key.new(expanded_c, expanded_c, false)
|
419
|
-
}
|
420
|
-
block.(expanded)
|
390
|
+
status = KeyStroke::UNMATCHED
|
421
391
|
end
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
end
|
426
|
-
|
427
|
-
private def read_2nd_character_of_key_sequence(keyseq_timeout, buffer, c, block)
|
428
|
-
begin
|
429
|
-
succ_c = nil
|
430
|
-
Timeout.timeout(keyseq_timeout / 1000.0) {
|
431
|
-
succ_c = Reline::IOGate.getc
|
432
|
-
}
|
433
|
-
rescue Timeout::Error # cancel matching only when first byte
|
434
|
-
block.([Reline::Key.new(c, c, false)])
|
435
|
-
return :break
|
436
|
-
else
|
437
|
-
case key_stroke.match_status(buffer.dup.push(succ_c))
|
438
|
-
when :unmatched
|
439
|
-
if c == "\e".ord
|
440
|
-
block.([Reline::Key.new(succ_c, succ_c | 0b10000000, true)])
|
441
|
-
else
|
442
|
-
block.([Reline::Key.new(c, c, false), Reline::Key.new(succ_c, succ_c, false)])
|
443
|
-
end
|
444
|
-
return :break
|
445
|
-
when :matching
|
446
|
-
Reline::IOGate.ungetc(succ_c)
|
447
|
-
return :next
|
448
|
-
when :matched
|
449
|
-
buffer << succ_c
|
450
|
-
expanded = key_stroke.expand(buffer).map{ |expanded_c|
|
451
|
-
Reline::Key.new(expanded_c, expanded_c, false)
|
452
|
-
}
|
453
|
-
block.(expanded)
|
454
|
-
return :break
|
392
|
+
else
|
393
|
+
buffer << c
|
394
|
+
status = key_stroke.match_status(buffer)
|
455
395
|
end
|
456
|
-
end
|
457
|
-
end
|
458
396
|
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
}
|
465
|
-
rescue Timeout::Error # independent ESC
|
466
|
-
block.([Reline::Key.new(c, c, false)])
|
467
|
-
else
|
468
|
-
if escaped_c.nil?
|
469
|
-
block.([Reline::Key.new(c, c, false)])
|
470
|
-
elsif escaped_c >= 128 # maybe, first byte of multi byte
|
471
|
-
block.([Reline::Key.new(c, c, false), Reline::Key.new(escaped_c, escaped_c, false)])
|
472
|
-
elsif escaped_c == "\e".ord # escape twice
|
473
|
-
block.([Reline::Key.new(c, c, false), Reline::Key.new(c, c, false)])
|
474
|
-
else
|
475
|
-
block.([Reline::Key.new(escaped_c, escaped_c | 0b10000000, true)])
|
397
|
+
if status == KeyStroke::MATCHED || status == KeyStroke::UNMATCHED
|
398
|
+
expanded, rest_bytes = key_stroke.expand(buffer)
|
399
|
+
rest_bytes.reverse_each { |c| io_gate.ungetc(c) }
|
400
|
+
block.call(expanded)
|
401
|
+
return
|
476
402
|
end
|
477
403
|
end
|
478
404
|
end
|
@@ -483,19 +409,19 @@ module Reline
|
|
483
409
|
end
|
484
410
|
|
485
411
|
private def may_req_ambiguous_char_width
|
486
|
-
@ambiguous_width = 2 if
|
412
|
+
@ambiguous_width = 2 if io_gate.dumb? || !STDIN.tty? || !STDOUT.tty?
|
487
413
|
return if defined? @ambiguous_width
|
488
|
-
|
414
|
+
io_gate.move_cursor_column(0)
|
489
415
|
begin
|
490
416
|
output.write "\u{25bd}"
|
491
417
|
rescue Encoding::UndefinedConversionError
|
492
418
|
# LANG=C
|
493
419
|
@ambiguous_width = 1
|
494
420
|
else
|
495
|
-
@ambiguous_width =
|
421
|
+
@ambiguous_width = io_gate.cursor_pos.x
|
496
422
|
end
|
497
|
-
|
498
|
-
|
423
|
+
io_gate.move_cursor_column(0)
|
424
|
+
io_gate.erase_after_cursor
|
499
425
|
end
|
500
426
|
end
|
501
427
|
|
@@ -558,7 +484,7 @@ module Reline
|
|
558
484
|
@core ||= Core.new { |core|
|
559
485
|
core.config = Reline::Config.new
|
560
486
|
core.key_stroke = Reline::KeyStroke.new(core.config)
|
561
|
-
core.line_editor = Reline::LineEditor.new(core.config,
|
487
|
+
core.line_editor = Reline::LineEditor.new(core.config, core.encoding)
|
562
488
|
|
563
489
|
core.basic_word_break_characters = " \t\n`><=;|&{("
|
564
490
|
core.completer_word_break_characters = " \t\n`><=;|&{("
|
@@ -571,7 +497,7 @@ module Reline
|
|
571
497
|
end
|
572
498
|
|
573
499
|
def self.ungetc(c)
|
574
|
-
|
500
|
+
core.io_gate.ungetc(c)
|
575
501
|
end
|
576
502
|
|
577
503
|
def self.line_editor
|
@@ -579,22 +505,12 @@ module Reline
|
|
579
505
|
end
|
580
506
|
end
|
581
507
|
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
else
|
590
|
-
tty = $stdout.tty?
|
591
|
-
end
|
592
|
-
end
|
593
|
-
Reline::IOGate = if tty
|
594
|
-
require 'reline/ansi'
|
595
|
-
Reline::ANSI
|
596
|
-
else
|
597
|
-
io
|
598
|
-
end
|
508
|
+
|
509
|
+
Reline::IOGate = Reline::IO.decide_io_gate
|
510
|
+
|
511
|
+
# Deprecated
|
512
|
+
Reline::GeneralIO = Reline::Dumb.new
|
513
|
+
|
514
|
+
Reline::Face.load_initial_configs
|
599
515
|
|
600
516
|
Reline::HISTORY = Reline::History.new(Reline.core.config)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- aycabta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: io-console
|
@@ -35,12 +35,16 @@ files:
|
|
35
35
|
- COPYING
|
36
36
|
- README.md
|
37
37
|
- lib/reline.rb
|
38
|
-
- lib/reline/ansi.rb
|
39
38
|
- lib/reline/config.rb
|
40
|
-
- lib/reline/
|
39
|
+
- lib/reline/face.rb
|
41
40
|
- lib/reline/history.rb
|
41
|
+
- lib/reline/io.rb
|
42
|
+
- lib/reline/io/ansi.rb
|
43
|
+
- lib/reline/io/dumb.rb
|
44
|
+
- lib/reline/io/windows.rb
|
42
45
|
- lib/reline/key_actor.rb
|
43
46
|
- lib/reline/key_actor/base.rb
|
47
|
+
- lib/reline/key_actor/composite.rb
|
44
48
|
- lib/reline/key_actor/emacs.rb
|
45
49
|
- lib/reline/key_actor/vi_command.rb
|
46
50
|
- lib/reline/key_actor/vi_insert.rb
|
@@ -51,12 +55,14 @@ files:
|
|
51
55
|
- lib/reline/unicode.rb
|
52
56
|
- lib/reline/unicode/east_asian_width.rb
|
53
57
|
- lib/reline/version.rb
|
54
|
-
- lib/reline/windows.rb
|
55
58
|
- license_of_rb-readline
|
56
59
|
homepage: https://github.com/ruby/reline
|
57
60
|
licenses:
|
58
61
|
- Ruby
|
59
|
-
metadata:
|
62
|
+
metadata:
|
63
|
+
bug_tracker_uri: https://github.com/ruby/reline/issues
|
64
|
+
changelog_uri: https://github.com/ruby/reline/releases
|
65
|
+
source_code_uri: https://github.com/ruby/reline
|
60
66
|
post_install_message:
|
61
67
|
rdoc_options: []
|
62
68
|
require_paths:
|
@@ -72,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
78
|
- !ruby/object:Gem::Version
|
73
79
|
version: '0'
|
74
80
|
requirements: []
|
75
|
-
rubygems_version: 3.
|
81
|
+
rubygems_version: 3.5.9
|
76
82
|
signing_key:
|
77
83
|
specification_version: 4
|
78
84
|
summary: Alternative GNU Readline or Editline implementation by pure Ruby.
|