reline 0.3.4 → 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +23 -0
- data/lib/reline/ansi.rb +1 -1
- data/lib/reline/key_stroke.rb +50 -7
- data/lib/reline/line_editor.rb +28 -9
- data/lib/reline/terminfo.rb +1 -15
- data/lib/reline/unicode.rb +0 -20
- data/lib/reline/version.rb +1 -1
- data/lib/reline.rb +57 -43
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3075f4003cf263e4652fc0dec716c71b55b597e6cbdc8cdb5297181b72780b57
|
4
|
+
data.tar.gz: 78eb2e13f17bc0c7ae34b425effe29bf40a30b355af7d0efd271823c2cdde521
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9fd55d135c7b1aaffaff575f930bdb6365c202a1d15b5943d3dd9f678f416ba312b21c836ef8b78d11ee9942c4e0f0ac50d395633196bd649bd23a2fa6096456
|
7
|
+
data.tar.gz: 43fe692b243560a81da41a48f4cb5cdf05514f85788bbc6b54bba72aef4d5e7258e73c2a84622c80e51adf36345cd9e7595455f8301e09c1f299f7b2ec147ff2
|
data/README.md
CHANGED
@@ -55,6 +55,29 @@ end
|
|
55
55
|
|
56
56
|
See also: [test/reline/yamatanooroti/multiline_repl](https://github.com/ruby/reline/blob/master/test/reline/yamatanooroti/multiline_repl)
|
57
57
|
|
58
|
+
## Contributing
|
59
|
+
|
60
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/reline.
|
61
|
+
|
62
|
+
### Run tests
|
63
|
+
|
64
|
+
> **Note**
|
65
|
+
> Please make sure you have `libvterm` installed for `yamatanooroti` tests (integration tests).
|
66
|
+
|
67
|
+
If you use Homebrew, you can install it by running `brew install libvterm`.
|
68
|
+
|
69
|
+
```bash
|
70
|
+
WITH_VTERM=1 bundle install
|
71
|
+
WITH_VTERM=1 bundle exec rake test test_yamatanooroti
|
72
|
+
```
|
73
|
+
|
74
|
+
## Releasing
|
75
|
+
|
76
|
+
```bash
|
77
|
+
rake release
|
78
|
+
gh release create vX.Y.Z --generate-notes
|
79
|
+
```
|
80
|
+
|
58
81
|
## License
|
59
82
|
|
60
83
|
The gem is available as open source under the terms of the [Ruby License](https://www.ruby-lang.org/en/about/license.txt).
|
data/lib/reline/ansi.rb
CHANGED
data/lib/reline/key_stroke.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
class Reline::KeyStroke
|
2
|
+
ESC_BYTE = 27
|
3
|
+
CSI_PARAMETER_BYTES_RANGE = 0x30..0x3f
|
4
|
+
CSI_INTERMEDIATE_BYTES_RANGE = (0x20..0x2f)
|
5
|
+
|
2
6
|
def initialize(config)
|
3
7
|
@config = config
|
4
8
|
end
|
@@ -73,17 +77,26 @@ class Reline::KeyStroke
|
|
73
77
|
return :matched if it.max_by(&:size)&.size&.< input.size
|
74
78
|
return :matching if it.size > 1
|
75
79
|
}
|
76
|
-
key_mapping.keys.
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
80
|
+
if key_mapping.keys.any? { |lhs| start_with?(input, lhs) }
|
81
|
+
:matched
|
82
|
+
else
|
83
|
+
match_unknown_escape_sequence(input).first
|
84
|
+
end
|
81
85
|
end
|
82
86
|
|
83
87
|
def expand(input)
|
84
|
-
input = compress_meta_key(input)
|
85
88
|
lhs = key_mapping.keys.select { |item| start_with?(input, item) }.sort_by(&:size).last
|
86
|
-
|
89
|
+
unless lhs
|
90
|
+
status, size = match_unknown_escape_sequence(input)
|
91
|
+
case status
|
92
|
+
when :matched
|
93
|
+
return [:ed_unassigned] + expand(input.drop(size))
|
94
|
+
when :matching
|
95
|
+
return [:ed_unassigned]
|
96
|
+
else
|
97
|
+
return input
|
98
|
+
end
|
99
|
+
end
|
87
100
|
rhs = key_mapping[lhs]
|
88
101
|
|
89
102
|
case rhs
|
@@ -99,6 +112,36 @@ class Reline::KeyStroke
|
|
99
112
|
|
100
113
|
private
|
101
114
|
|
115
|
+
# returns match status of CSI/SS3 sequence and matched length
|
116
|
+
def match_unknown_escape_sequence(input)
|
117
|
+
idx = 0
|
118
|
+
return [:unmatched, nil] unless input[idx] == ESC_BYTE
|
119
|
+
idx += 1
|
120
|
+
idx += 1 if input[idx] == ESC_BYTE
|
121
|
+
|
122
|
+
case input[idx]
|
123
|
+
when nil
|
124
|
+
return [:matching, nil]
|
125
|
+
when 91 # == '['.ord
|
126
|
+
# CSI sequence
|
127
|
+
idx += 1
|
128
|
+
idx += 1 while idx < input.size && CSI_PARAMETER_BYTES_RANGE.cover?(input[idx])
|
129
|
+
idx += 1 while idx < input.size && CSI_INTERMEDIATE_BYTES_RANGE.cover?(input[idx])
|
130
|
+
input[idx] ? [:matched, idx + 1] : [:matching, nil]
|
131
|
+
when 79 # == 'O'.ord
|
132
|
+
# SS3 sequence
|
133
|
+
input[idx + 1] ? [:matched, idx + 2] : [:matching, nil]
|
134
|
+
else
|
135
|
+
if idx == 1
|
136
|
+
# `ESC char`, make it :unmatched so that it will be handled correctly in `read_2nd_character_of_key_sequence`
|
137
|
+
[:unmatched, nil]
|
138
|
+
else
|
139
|
+
# `ESC ESC char`
|
140
|
+
[:matched, idx + 1]
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
102
145
|
def key_mapping
|
103
146
|
@config.key_bindings
|
104
147
|
end
|
data/lib/reline/line_editor.rb
CHANGED
@@ -48,8 +48,8 @@ class Reline::LineEditor
|
|
48
48
|
PERFECT_MATCH = :perfect_match
|
49
49
|
end
|
50
50
|
|
51
|
-
CompletionJourneyData = Struct.new(
|
52
|
-
MenuInfo = Struct.new(
|
51
|
+
CompletionJourneyData = Struct.new(:preposing, :postposing, :list, :pointer)
|
52
|
+
MenuInfo = Struct.new(:target, :list)
|
53
53
|
|
54
54
|
PROMPT_LIST_CACHE_TIMEOUT = 0.5
|
55
55
|
MINIMUM_SCROLLBAR_HEIGHT = 1
|
@@ -60,6 +60,10 @@ class Reline::LineEditor
|
|
60
60
|
reset_variables(encoding: encoding)
|
61
61
|
end
|
62
62
|
|
63
|
+
def io_gate
|
64
|
+
Reline::IOGate
|
65
|
+
end
|
66
|
+
|
63
67
|
def set_pasting_state(in_pasting)
|
64
68
|
@in_pasting = in_pasting
|
65
69
|
end
|
@@ -562,6 +566,16 @@ class Reline::LineEditor
|
|
562
566
|
@line_editor.instance_variable_get(:@screen_size).last
|
563
567
|
end
|
564
568
|
|
569
|
+
def screen_height
|
570
|
+
@line_editor.instance_variable_get(:@screen_size).first
|
571
|
+
end
|
572
|
+
|
573
|
+
def preferred_dialog_height
|
574
|
+
rest_height = @line_editor.instance_variable_get(:@rest_height)
|
575
|
+
scroll_partial_screen = @line_editor.instance_variable_get(:@scroll_partial_screen) || 0
|
576
|
+
[cursor_pos.y - scroll_partial_screen, rest_height, (screen_height + 6) / 5].max
|
577
|
+
end
|
578
|
+
|
565
579
|
def completion_journey_data
|
566
580
|
@line_editor.instance_variable_get(:@completion_journey_data)
|
567
581
|
end
|
@@ -714,7 +728,7 @@ class Reline::LineEditor
|
|
714
728
|
ymax = ymax.clamp(screen_y_range.begin, screen_y_range.end)
|
715
729
|
dialog_y = @first_line_started_from + @started_from
|
716
730
|
cursor_y = dialog_y
|
717
|
-
if @highest_in_all
|
731
|
+
if @highest_in_all <= ymax
|
718
732
|
scroll_down(ymax - cursor_y)
|
719
733
|
move_cursor_up(ymax - cursor_y)
|
720
734
|
end
|
@@ -1500,11 +1514,13 @@ class Reline::LineEditor
|
|
1500
1514
|
return if key.char >= 128 # maybe, first byte of multi byte
|
1501
1515
|
method_symbol = @config.editing_mode.get_method(key.combined_char)
|
1502
1516
|
if key.with_meta and method_symbol == :ed_unassigned
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1517
|
+
if @config.editing_mode_is?(:vi_command, :vi_insert)
|
1518
|
+
# split ESC + key in vi mode
|
1519
|
+
method_symbol = @config.editing_mode.get_method("\e".ord)
|
1520
|
+
process_key("\e".ord, method_symbol)
|
1521
|
+
method_symbol = @config.editing_mode.get_method(key.char)
|
1522
|
+
process_key(key.char, method_symbol)
|
1523
|
+
end
|
1508
1524
|
else
|
1509
1525
|
process_key(key.combined_char, method_symbol)
|
1510
1526
|
end
|
@@ -1635,7 +1651,7 @@ class Reline::LineEditor
|
|
1635
1651
|
@line = ' ' * new_indent + @line.lstrip
|
1636
1652
|
|
1637
1653
|
new_indent = nil
|
1638
|
-
result = @auto_indent_proc.(new_lines[0..-2], @line_index - 1, (new_lines[-
|
1654
|
+
result = @auto_indent_proc.(new_lines[0..-2], @line_index - 1, (new_lines[@line_index - 1].bytesize + 1), false)
|
1639
1655
|
if result
|
1640
1656
|
new_indent = result
|
1641
1657
|
end
|
@@ -3276,4 +3292,7 @@ class Reline::LineEditor
|
|
3276
3292
|
@mark_pointer = new_pointer
|
3277
3293
|
end
|
3278
3294
|
alias_method :exchange_point_and_mark, :em_exchange_mark
|
3295
|
+
|
3296
|
+
private def em_meta_next(key)
|
3297
|
+
end
|
3279
3298
|
end
|
data/lib/reline/terminfo.rb
CHANGED
@@ -31,21 +31,7 @@ module Reline::Terminfo
|
|
31
31
|
@curses_dl = false
|
32
32
|
def self.curses_dl
|
33
33
|
return @curses_dl unless @curses_dl == false
|
34
|
-
if
|
35
|
-
# Gem module isn't defined in test-all of the Ruby repository, and
|
36
|
-
# Fiddle in Ruby 3.0.0 or later supports Fiddle::TYPE_VARIADIC.
|
37
|
-
fiddle_supports_variadic = true
|
38
|
-
elsif Fiddle.const_defined?(:VERSION,false) and Gem::Version.create(Fiddle::VERSION) >= Gem::Version.create('1.0.1')
|
39
|
-
# Fiddle::TYPE_VARIADIC is supported from Fiddle 1.0.1.
|
40
|
-
fiddle_supports_variadic = true
|
41
|
-
else
|
42
|
-
fiddle_supports_variadic = false
|
43
|
-
end
|
44
|
-
if fiddle_supports_variadic and not Fiddle.const_defined?(:TYPE_VARIADIC)
|
45
|
-
# If the libffi version is not 3.0.5 or higher, there isn't TYPE_VARIADIC.
|
46
|
-
fiddle_supports_variadic = false
|
47
|
-
end
|
48
|
-
if fiddle_supports_variadic
|
34
|
+
if Fiddle.const_defined?(:TYPE_VARIADIC)
|
49
35
|
curses_dl_files.each do |curses_name|
|
50
36
|
result = Fiddle::Handle.new(curses_name)
|
51
37
|
rescue Fiddle::DLError
|
data/lib/reline/unicode.rb
CHANGED
@@ -41,26 +41,6 @@ class Reline::Unicode
|
|
41
41
|
OSC_REGEXP = /\e\]\d+(?:;[^;\a\e]+)*(?:\a|\e\\)/
|
42
42
|
WIDTH_SCANNER = /\G(?:(#{NON_PRINTING_START})|(#{NON_PRINTING_END})|(#{CSI_REGEXP})|(#{OSC_REGEXP})|(\X))/o
|
43
43
|
|
44
|
-
def self.get_mbchar_byte_size_by_first_char(c)
|
45
|
-
# Checks UTF-8 character byte size
|
46
|
-
case c.ord
|
47
|
-
# 0b0xxxxxxx
|
48
|
-
when ->(code) { (code ^ 0b10000000).allbits?(0b10000000) } then 1
|
49
|
-
# 0b110xxxxx
|
50
|
-
when ->(code) { (code ^ 0b00100000).allbits?(0b11100000) } then 2
|
51
|
-
# 0b1110xxxx
|
52
|
-
when ->(code) { (code ^ 0b00010000).allbits?(0b11110000) } then 3
|
53
|
-
# 0b11110xxx
|
54
|
-
when ->(code) { (code ^ 0b00001000).allbits?(0b11111000) } then 4
|
55
|
-
# 0b111110xx
|
56
|
-
when ->(code) { (code ^ 0b00000100).allbits?(0b11111100) } then 5
|
57
|
-
# 0b1111110x
|
58
|
-
when ->(code) { (code ^ 0b00000010).allbits?(0b11111110) } then 6
|
59
|
-
# successor of mbchar
|
60
|
-
else 0
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
44
|
def self.escape_for_print(str)
|
65
45
|
str.chars.map! { |gr|
|
66
46
|
escaped = EscapedPairs[gr.ord]
|
data/lib/reline/version.rb
CHANGED
data/lib/reline.rb
CHANGED
@@ -17,7 +17,7 @@ module Reline
|
|
17
17
|
|
18
18
|
class ConfigEncodingConversionError < StandardError; end
|
19
19
|
|
20
|
-
Key = Struct.new(
|
20
|
+
Key = Struct.new(:char, :combined_char, :with_meta) do
|
21
21
|
def match?(other)
|
22
22
|
case other
|
23
23
|
when Reline::Key
|
@@ -83,44 +83,48 @@ module Reline
|
|
83
83
|
@bracketed_paste_finished = false
|
84
84
|
end
|
85
85
|
|
86
|
+
def io_gate
|
87
|
+
Reline::IOGate
|
88
|
+
end
|
89
|
+
|
86
90
|
def encoding
|
87
|
-
|
91
|
+
io_gate.encoding
|
88
92
|
end
|
89
93
|
|
90
94
|
def completion_append_character=(val)
|
91
95
|
if val.nil?
|
92
96
|
@completion_append_character = nil
|
93
97
|
elsif val.size == 1
|
94
|
-
@completion_append_character = val.encode(
|
98
|
+
@completion_append_character = val.encode(encoding)
|
95
99
|
elsif val.size > 1
|
96
|
-
@completion_append_character = val[0].encode(
|
100
|
+
@completion_append_character = val[0].encode(encoding)
|
97
101
|
else
|
98
102
|
@completion_append_character = nil
|
99
103
|
end
|
100
104
|
end
|
101
105
|
|
102
106
|
def basic_word_break_characters=(v)
|
103
|
-
@basic_word_break_characters = v.encode(
|
107
|
+
@basic_word_break_characters = v.encode(encoding)
|
104
108
|
end
|
105
109
|
|
106
110
|
def completer_word_break_characters=(v)
|
107
|
-
@completer_word_break_characters = v.encode(
|
111
|
+
@completer_word_break_characters = v.encode(encoding)
|
108
112
|
end
|
109
113
|
|
110
114
|
def basic_quote_characters=(v)
|
111
|
-
@basic_quote_characters = v.encode(
|
115
|
+
@basic_quote_characters = v.encode(encoding)
|
112
116
|
end
|
113
117
|
|
114
118
|
def completer_quote_characters=(v)
|
115
|
-
@completer_quote_characters = v.encode(
|
119
|
+
@completer_quote_characters = v.encode(encoding)
|
116
120
|
end
|
117
121
|
|
118
122
|
def filename_quote_characters=(v)
|
119
|
-
@filename_quote_characters = v.encode(
|
123
|
+
@filename_quote_characters = v.encode(encoding)
|
120
124
|
end
|
121
125
|
|
122
126
|
def special_prefixes=(v)
|
123
|
-
@special_prefixes = v.encode(
|
127
|
+
@special_prefixes = v.encode(encoding)
|
124
128
|
end
|
125
129
|
|
126
130
|
def completion_case_fold=(v)
|
@@ -181,20 +185,16 @@ module Reline
|
|
181
185
|
|
182
186
|
def input=(val)
|
183
187
|
raise TypeError unless val.respond_to?(:getc) or val.nil?
|
184
|
-
if val.respond_to?(:getc)
|
185
|
-
|
186
|
-
Reline::ANSI.input = val
|
187
|
-
elsif Reline::IOGate == Reline::GeneralIO
|
188
|
-
Reline::GeneralIO.input = val
|
189
|
-
end
|
188
|
+
if val.respond_to?(:getc) && io_gate.respond_to?(:input=)
|
189
|
+
io_gate.input = val
|
190
190
|
end
|
191
191
|
end
|
192
192
|
|
193
193
|
def output=(val)
|
194
194
|
raise TypeError unless val.respond_to?(:write) or val.nil?
|
195
195
|
@output = val
|
196
|
-
if
|
197
|
-
|
196
|
+
if io_gate.respond_to?(:output=)
|
197
|
+
io_gate.output = val
|
198
198
|
end
|
199
199
|
end
|
200
200
|
|
@@ -217,7 +217,7 @@ module Reline
|
|
217
217
|
end
|
218
218
|
|
219
219
|
def get_screen_size
|
220
|
-
|
220
|
+
io_gate.get_screen_size
|
221
221
|
end
|
222
222
|
|
223
223
|
Reline::DEFAULT_DIALOG_PROC_AUTOCOMPLETE = ->() {
|
@@ -260,7 +260,7 @@ module Reline
|
|
260
260
|
pos: cursor_pos_to_render,
|
261
261
|
contents: result,
|
262
262
|
scrollbar: true,
|
263
|
-
height: 15,
|
263
|
+
height: [15, preferred_dialog_height].min,
|
264
264
|
bg_color: 46,
|
265
265
|
pointer_bg_color: 45,
|
266
266
|
fg_color: 37,
|
@@ -270,7 +270,8 @@ module Reline
|
|
270
270
|
Reline::DEFAULT_DIALOG_CONTEXT = Array.new
|
271
271
|
|
272
272
|
def readmultiline(prompt = '', add_hist = false, &confirm_multiline_termination)
|
273
|
-
Reline
|
273
|
+
Reline.update_iogate
|
274
|
+
io_gate.with_raw_input do
|
274
275
|
unless confirm_multiline_termination
|
275
276
|
raise ArgumentError.new('#readmultiline needs block to confirm multiline termination')
|
276
277
|
end
|
@@ -288,6 +289,7 @@ module Reline
|
|
288
289
|
end
|
289
290
|
|
290
291
|
def readline(prompt = '', add_hist = false)
|
292
|
+
Reline.update_iogate
|
291
293
|
inner_readline(prompt, add_hist, false)
|
292
294
|
|
293
295
|
line = line_editor.line.dup
|
@@ -302,7 +304,7 @@ module Reline
|
|
302
304
|
|
303
305
|
private def inner_readline(prompt, add_hist, multiline, &confirm_multiline_termination)
|
304
306
|
if ENV['RELINE_STDERR_TTY']
|
305
|
-
if
|
307
|
+
if io_gate.win?
|
306
308
|
$stderr = File.open(ENV['RELINE_STDERR_TTY'], 'a')
|
307
309
|
else
|
308
310
|
$stderr.reopen(ENV['RELINE_STDERR_TTY'], 'w')
|
@@ -310,10 +312,10 @@ module Reline
|
|
310
312
|
$stderr.sync = true
|
311
313
|
$stderr.puts "Reline is used by #{Process.pid}"
|
312
314
|
end
|
313
|
-
otio =
|
315
|
+
otio = io_gate.prep
|
314
316
|
|
315
317
|
may_req_ambiguous_char_width
|
316
|
-
line_editor.reset(prompt, encoding:
|
318
|
+
line_editor.reset(prompt, encoding: encoding)
|
317
319
|
if multiline
|
318
320
|
line_editor.multiline_on
|
319
321
|
if block_given?
|
@@ -337,7 +339,7 @@ module Reline
|
|
337
339
|
unless config.test_mode
|
338
340
|
config.read
|
339
341
|
config.reset_default_key_bindings
|
340
|
-
|
342
|
+
io_gate.set_default_key_bindings(config)
|
341
343
|
end
|
342
344
|
|
343
345
|
line_editor.rerender
|
@@ -346,9 +348,9 @@ module Reline
|
|
346
348
|
line_editor.set_signal_handlers
|
347
349
|
prev_pasting_state = false
|
348
350
|
loop do
|
349
|
-
prev_pasting_state =
|
351
|
+
prev_pasting_state = io_gate.in_pasting?
|
350
352
|
read_io(config.keyseq_timeout) { |inputs|
|
351
|
-
line_editor.set_pasting_state(
|
353
|
+
line_editor.set_pasting_state(io_gate.in_pasting?)
|
352
354
|
inputs.each { |c|
|
353
355
|
line_editor.input_key(c)
|
354
356
|
line_editor.rerender
|
@@ -358,29 +360,29 @@ module Reline
|
|
358
360
|
@bracketed_paste_finished = false
|
359
361
|
end
|
360
362
|
}
|
361
|
-
if prev_pasting_state == true and not
|
363
|
+
if prev_pasting_state == true and not io_gate.in_pasting? and not line_editor.finished?
|
362
364
|
line_editor.set_pasting_state(false)
|
363
365
|
prev_pasting_state = false
|
364
366
|
line_editor.rerender_all
|
365
367
|
end
|
366
368
|
break if line_editor.finished?
|
367
369
|
end
|
368
|
-
|
370
|
+
io_gate.move_cursor_column(0)
|
369
371
|
rescue Errno::EIO
|
370
372
|
# Maybe the I/O has been closed.
|
371
373
|
rescue StandardError => e
|
372
374
|
line_editor.finalize
|
373
|
-
|
375
|
+
io_gate.deprep(otio)
|
374
376
|
raise e
|
375
377
|
rescue Exception
|
376
378
|
# Including Interrupt
|
377
379
|
line_editor.finalize
|
378
|
-
|
380
|
+
io_gate.deprep(otio)
|
379
381
|
raise
|
380
382
|
end
|
381
383
|
|
382
384
|
line_editor.finalize
|
383
|
-
|
385
|
+
io_gate.deprep(otio)
|
384
386
|
end
|
385
387
|
|
386
388
|
# GNU Readline waits for "keyseq-timeout" milliseconds to see if the ESC
|
@@ -395,7 +397,7 @@ module Reline
|
|
395
397
|
private def read_io(keyseq_timeout, &block)
|
396
398
|
buffer = []
|
397
399
|
loop do
|
398
|
-
c =
|
400
|
+
c = io_gate.getc
|
399
401
|
if c == -1
|
400
402
|
result = :unmatched
|
401
403
|
@bracketed_paste_finished = true
|
@@ -435,7 +437,7 @@ module Reline
|
|
435
437
|
begin
|
436
438
|
succ_c = nil
|
437
439
|
Timeout.timeout(keyseq_timeout / 1000.0) {
|
438
|
-
succ_c =
|
440
|
+
succ_c = io_gate.getc
|
439
441
|
}
|
440
442
|
rescue Timeout::Error # cancel matching only when first byte
|
441
443
|
block.([Reline::Key.new(c, c, false)])
|
@@ -450,7 +452,7 @@ module Reline
|
|
450
452
|
end
|
451
453
|
return :break
|
452
454
|
when :matching
|
453
|
-
|
455
|
+
io_gate.ungetc(succ_c)
|
454
456
|
return :next
|
455
457
|
when :matched
|
456
458
|
buffer << succ_c
|
@@ -467,7 +469,7 @@ module Reline
|
|
467
469
|
begin
|
468
470
|
escaped_c = nil
|
469
471
|
Timeout.timeout(keyseq_timeout / 1000.0) {
|
470
|
-
escaped_c =
|
472
|
+
escaped_c = io_gate.getc
|
471
473
|
}
|
472
474
|
rescue Timeout::Error # independent ESC
|
473
475
|
block.([Reline::Key.new(c, c, false)])
|
@@ -490,19 +492,19 @@ module Reline
|
|
490
492
|
end
|
491
493
|
|
492
494
|
private def may_req_ambiguous_char_width
|
493
|
-
@ambiguous_width = 2 if
|
495
|
+
@ambiguous_width = 2 if io_gate == Reline::GeneralIO or !STDOUT.tty?
|
494
496
|
return if defined? @ambiguous_width
|
495
|
-
|
497
|
+
io_gate.move_cursor_column(0)
|
496
498
|
begin
|
497
499
|
output.write "\u{25bd}"
|
498
500
|
rescue Encoding::UndefinedConversionError
|
499
501
|
# LANG=C
|
500
502
|
@ambiguous_width = 1
|
501
503
|
else
|
502
|
-
@ambiguous_width =
|
504
|
+
@ambiguous_width = io_gate.cursor_pos.x
|
503
505
|
end
|
504
|
-
|
505
|
-
|
506
|
+
io_gate.move_cursor_column(0)
|
507
|
+
io_gate.erase_after_cursor
|
506
508
|
end
|
507
509
|
end
|
508
510
|
|
@@ -565,7 +567,7 @@ module Reline
|
|
565
567
|
@core ||= Core.new { |core|
|
566
568
|
core.config = Reline::Config.new
|
567
569
|
core.key_stroke = Reline::KeyStroke.new(core.config)
|
568
|
-
core.line_editor = Reline::LineEditor.new(core.config,
|
570
|
+
core.line_editor = Reline::LineEditor.new(core.config, core.encoding)
|
569
571
|
|
570
572
|
core.basic_word_break_characters = " \t\n`><=;|&{("
|
571
573
|
core.completer_word_break_characters = " \t\n`><=;|&{("
|
@@ -578,12 +580,24 @@ module Reline
|
|
578
580
|
end
|
579
581
|
|
580
582
|
def self.ungetc(c)
|
581
|
-
|
583
|
+
core.io_gate.ungetc(c)
|
582
584
|
end
|
583
585
|
|
584
586
|
def self.line_editor
|
585
587
|
core.line_editor
|
586
588
|
end
|
589
|
+
|
590
|
+
def self.update_iogate
|
591
|
+
return if core.config.test_mode
|
592
|
+
|
593
|
+
# Need to change IOGate when `$stdout.tty?` change from false to true by `$stdout.reopen`
|
594
|
+
# Example: rails/spring boot the application in non-tty, then run console in tty.
|
595
|
+
if ENV['TERM'] != 'dumb' && core.io_gate == Reline::GeneralIO && $stdout.tty?
|
596
|
+
require 'reline/ansi'
|
597
|
+
remove_const(:IOGate)
|
598
|
+
const_set(:IOGate, Reline::ANSI)
|
599
|
+
end
|
600
|
+
end
|
587
601
|
end
|
588
602
|
|
589
603
|
require 'reline/general_io'
|
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.3.
|
4
|
+
version: 0.3.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- aycabta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: io-console
|