reline 0.3.2 → 0.5.9
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 +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.
|