reline 0.5.9 → 0.5.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/reline/config.rb +41 -50
- data/lib/reline/face.rb +1 -1
- data/lib/reline/history.rb +3 -3
- data/lib/reline/io/ansi.rb +33 -49
- data/lib/reline/io/dumb.rb +2 -2
- data/lib/reline/io/windows.rb +83 -66
- data/lib/reline/line_editor.rb +114 -135
- data/lib/reline/terminfo.rb +1 -1
- data/lib/reline/unicode/east_asian_width.rb +1262 -1191
- data/lib/reline/unicode.rb +34 -43
- data/lib/reline/version.rb +1 -1
- data/lib/reline.rb +11 -8
- metadata +3 -6
data/lib/reline/unicode.rb
CHANGED
@@ -54,53 +54,44 @@ class Reline::Unicode
|
|
54
54
|
}.join
|
55
55
|
end
|
56
56
|
|
57
|
-
|
57
|
+
def self.safe_encode(str, encoding)
|
58
|
+
# Reline only supports utf-8 convertible string.
|
59
|
+
converted = str.encode(encoding, invalid: :replace, undef: :replace)
|
60
|
+
return converted if str.encoding == Encoding::UTF_8 || converted.encoding == Encoding::UTF_8 || converted.ascii_only?
|
58
61
|
|
59
|
-
|
62
|
+
# This code is essentially doing the same thing as
|
63
|
+
# `str.encode(utf8, **replace_options).encode(encoding, **replace_options)`
|
64
|
+
# but also avoids unneccesary irreversible encoding conversion.
|
65
|
+
converted.gsub(/\X/) do |c|
|
66
|
+
c.encode(Encoding::UTF_8)
|
67
|
+
c
|
68
|
+
rescue Encoding::UndefinedConversionError
|
69
|
+
'?'
|
70
|
+
end
|
71
|
+
end
|
60
72
|
|
61
|
-
|
62
|
-
(?<width_2_1>
|
63
|
-
[#{ EscapedChars.map {|c| "\\x%02x" % c.ord }.join }] (?# ^ + char, such as ^M, ^H, ^[, ...)
|
64
|
-
)
|
65
|
-
| (?<width_3>^\u{2E3B}) (?# THREE-EM DASH)
|
66
|
-
| (?<width_0>^\p{M})
|
67
|
-
| (?<width_2_2>
|
68
|
-
#{ EastAsianWidth::TYPE_F }
|
69
|
-
| #{ EastAsianWidth::TYPE_W }
|
70
|
-
)
|
71
|
-
| (?<width_1>
|
72
|
-
#{ EastAsianWidth::TYPE_H }
|
73
|
-
| #{ EastAsianWidth::TYPE_NA }
|
74
|
-
| #{ EastAsianWidth::TYPE_N }
|
75
|
-
)(?!#{ HalfwidthDakutenHandakuten })
|
76
|
-
| (?<width_2_3>
|
77
|
-
(?: #{ EastAsianWidth::TYPE_H }
|
78
|
-
| #{ EastAsianWidth::TYPE_NA }
|
79
|
-
| #{ EastAsianWidth::TYPE_N })
|
80
|
-
#{ HalfwidthDakutenHandakuten }
|
81
|
-
)
|
82
|
-
| (?<ambiguous_width>
|
83
|
-
#{EastAsianWidth::TYPE_A}
|
84
|
-
)
|
85
|
-
/x
|
73
|
+
require 'reline/unicode/east_asian_width'
|
86
74
|
|
87
75
|
def self.get_mbchar_width(mbchar)
|
88
76
|
ord = mbchar.ord
|
89
|
-
if
|
77
|
+
if ord <= 0x1F # in EscapedPairs
|
90
78
|
return 2
|
91
|
-
elsif
|
79
|
+
elsif ord <= 0x7E # printable ASCII chars
|
92
80
|
return 1
|
93
81
|
end
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
82
|
+
utf8_mbchar = mbchar.encode(Encoding::UTF_8)
|
83
|
+
ord = utf8_mbchar.ord
|
84
|
+
chunk_index = EastAsianWidth::CHUNK_LAST.bsearch_index { |o| ord <= o }
|
85
|
+
size = EastAsianWidth::CHUNK_WIDTH[chunk_index]
|
86
|
+
if size == -1
|
87
|
+
Reline.ambiguous_width
|
88
|
+
elsif size == 1 && utf8_mbchar.size >= 2
|
89
|
+
second_char_ord = utf8_mbchar[1].ord
|
90
|
+
# Halfwidth Dakuten Handakuten
|
91
|
+
# Only these two character has Letter Modifier category and can be combined in a single grapheme cluster
|
92
|
+
(second_char_ord == 0xFF9E || second_char_ord == 0xFF9F) ? 2 : 1
|
102
93
|
else
|
103
|
-
|
94
|
+
size
|
104
95
|
end
|
105
96
|
end
|
106
97
|
|
@@ -141,10 +132,8 @@ class Reline::Unicode
|
|
141
132
|
case
|
142
133
|
when non_printing_start
|
143
134
|
in_zero_width = true
|
144
|
-
lines.last << NON_PRINTING_START
|
145
135
|
when non_printing_end
|
146
136
|
in_zero_width = false
|
147
|
-
lines.last << NON_PRINTING_END
|
148
137
|
when csi
|
149
138
|
lines.last << csi
|
150
139
|
unless in_zero_width
|
@@ -156,7 +145,7 @@ class Reline::Unicode
|
|
156
145
|
end
|
157
146
|
when osc
|
158
147
|
lines.last << osc
|
159
|
-
seq << osc
|
148
|
+
seq << osc unless in_zero_width
|
160
149
|
when gc
|
161
150
|
unless in_zero_width
|
162
151
|
mbchar_width = get_mbchar_width(gc)
|
@@ -179,6 +168,10 @@ class Reline::Unicode
|
|
179
168
|
[lines, height]
|
180
169
|
end
|
181
170
|
|
171
|
+
def self.strip_non_printing_start_end(prompt)
|
172
|
+
prompt.gsub(/\x01([^\x02]*)(?:\x02|\z)/) { $1 }
|
173
|
+
end
|
174
|
+
|
182
175
|
# Take a chunk of a String cut by width with escape sequences.
|
183
176
|
def self.take_range(str, start_col, max_width)
|
184
177
|
take_mbchar_range(str, start_col, max_width).first
|
@@ -198,10 +191,8 @@ class Reline::Unicode
|
|
198
191
|
case
|
199
192
|
when non_printing_start
|
200
193
|
in_zero_width = true
|
201
|
-
chunk << NON_PRINTING_START
|
202
194
|
when non_printing_end
|
203
195
|
in_zero_width = false
|
204
|
-
chunk << NON_PRINTING_END
|
205
196
|
when csi
|
206
197
|
has_csi = true
|
207
198
|
chunk << csi
|
data/lib/reline/version.rb
CHANGED
data/lib/reline.rb
CHANGED
@@ -308,7 +308,7 @@ module Reline
|
|
308
308
|
otio = io_gate.prep
|
309
309
|
|
310
310
|
may_req_ambiguous_char_width
|
311
|
-
line_editor.reset(prompt
|
311
|
+
line_editor.reset(prompt)
|
312
312
|
if multiline
|
313
313
|
line_editor.multiline_on
|
314
314
|
if block_given?
|
@@ -324,14 +324,17 @@ module Reline
|
|
324
324
|
line_editor.prompt_proc = prompt_proc
|
325
325
|
line_editor.auto_indent_proc = auto_indent_proc
|
326
326
|
line_editor.dig_perfect_match_proc = dig_perfect_match_proc
|
327
|
+
|
328
|
+
# Readline calls pre_input_hook just after printing the first prompt.
|
329
|
+
line_editor.print_nomultiline_prompt
|
327
330
|
pre_input_hook&.call
|
331
|
+
|
328
332
|
unless Reline::IOGate.dumb?
|
329
333
|
@dialog_proc_list.each_pair do |name_sym, d|
|
330
334
|
line_editor.add_dialog_proc(name_sym, d.dialog_proc, d.context)
|
331
335
|
end
|
332
336
|
end
|
333
337
|
|
334
|
-
line_editor.print_nomultiline_prompt(prompt)
|
335
338
|
line_editor.update_dialogs
|
336
339
|
line_editor.rerender
|
337
340
|
|
@@ -343,7 +346,7 @@ module Reline
|
|
343
346
|
inputs.each do |key|
|
344
347
|
if key.char == :bracketed_paste_start
|
345
348
|
text = io_gate.read_bracketed_paste
|
346
|
-
line_editor.
|
349
|
+
line_editor.insert_multiline_text(text)
|
347
350
|
line_editor.scroll_into_view
|
348
351
|
else
|
349
352
|
line_editor.update(key)
|
@@ -409,7 +412,7 @@ module Reline
|
|
409
412
|
end
|
410
413
|
|
411
414
|
private def may_req_ambiguous_char_width
|
412
|
-
@ambiguous_width =
|
415
|
+
@ambiguous_width = 1 if io_gate.dumb? || !STDIN.tty? || !STDOUT.tty?
|
413
416
|
return if defined? @ambiguous_width
|
414
417
|
io_gate.move_cursor_column(0)
|
415
418
|
begin
|
@@ -418,7 +421,7 @@ module Reline
|
|
418
421
|
# LANG=C
|
419
422
|
@ambiguous_width = 1
|
420
423
|
else
|
421
|
-
@ambiguous_width = io_gate.cursor_pos.x
|
424
|
+
@ambiguous_width = io_gate.cursor_pos.x == 2 ? 2 : 1
|
422
425
|
end
|
423
426
|
io_gate.move_cursor_column(0)
|
424
427
|
io_gate.erase_after_cursor
|
@@ -457,8 +460,8 @@ module Reline
|
|
457
460
|
def_single_delegator :line_editor, :byte_pointer, :point
|
458
461
|
def_single_delegator :line_editor, :byte_pointer=, :point=
|
459
462
|
|
460
|
-
def self.insert_text(
|
461
|
-
line_editor.
|
463
|
+
def self.insert_text(text)
|
464
|
+
line_editor.insert_multiline_text(text)
|
462
465
|
self
|
463
466
|
end
|
464
467
|
|
@@ -484,7 +487,7 @@ module Reline
|
|
484
487
|
@core ||= Core.new { |core|
|
485
488
|
core.config = Reline::Config.new
|
486
489
|
core.key_stroke = Reline::KeyStroke.new(core.config)
|
487
|
-
core.line_editor = Reline::LineEditor.new(core.config
|
490
|
+
core.line_editor = Reline::LineEditor.new(core.config)
|
488
491
|
|
489
492
|
core.basic_word_break_characters = " \t\n`><=;|&{("
|
490
493
|
core.completer_word_break_characters = " \t\n`><=;|&{("
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- aycabta
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date: 2024-
|
10
|
+
date: 2024-11-08 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: io-console
|
@@ -63,7 +62,6 @@ metadata:
|
|
63
62
|
bug_tracker_uri: https://github.com/ruby/reline/issues
|
64
63
|
changelog_uri: https://github.com/ruby/reline/releases
|
65
64
|
source_code_uri: https://github.com/ruby/reline
|
66
|
-
post_install_message:
|
67
65
|
rdoc_options: []
|
68
66
|
require_paths:
|
69
67
|
- lib
|
@@ -78,8 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
76
|
- !ruby/object:Gem::Version
|
79
77
|
version: '0'
|
80
78
|
requirements: []
|
81
|
-
rubygems_version: 3.
|
82
|
-
signing_key:
|
79
|
+
rubygems_version: 3.6.0.dev
|
83
80
|
specification_version: 4
|
84
81
|
summary: Alternative GNU Readline or Editline implementation by pure Ruby.
|
85
82
|
test_files: []
|