reline 0.6.1 → 0.6.3
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 +5 -0
- data/lib/reline/io/ansi.rb +7 -15
- data/lib/reline/io.rb +2 -2
- data/lib/reline/key_actor/emacs.rb +2 -2
- data/lib/reline/line_editor.rb +46 -44
- data/lib/reline/unicode/east_asian_width.rb +7 -8
- data/lib/reline/unicode.rb +22 -16
- data/lib/reline/version.rb +1 -1
- data/lib/reline.rb +2 -3
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cac4dc95dc3a9106a6f332d3503a62502f09205161a21157222e2dcd985ab706
|
|
4
|
+
data.tar.gz: 586f28ad1d6e68eefe7e5b4a15a4ee69f9d55d5469c144b686b72084b0abebe8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6f2e8fc8a404e1e8a0491c083e5ce524c5a5e465fceebcfa6eb7c0a5df20b98e07d337bb2c8703806f54e055efbeeba9c5d1f3171bd8e0faf6a611e30bbbf5da
|
|
7
|
+
data.tar.gz: a73fe51d441f70a4bb84ecfac2172251e6db0abf9f3007cbadf4f0374e5772b3ee62f71c753f10e88aa460278d1c0611b32ebca2e6f59fc6e42894377b56eb34
|
data/lib/reline/config.rb
CHANGED
|
@@ -177,6 +177,11 @@ class Reline::Config
|
|
|
177
177
|
if_stack = []
|
|
178
178
|
|
|
179
179
|
lines.each_with_index do |line, no|
|
|
180
|
+
# Even after encoding conversion, we need to verify the encoding is valid
|
|
181
|
+
# as some invalid byte sequences might pass through the conversion.
|
|
182
|
+
unless line.valid_encoding?
|
|
183
|
+
raise InvalidInputrc, "#{file}:#{no + 1}: can't be converted to the locale #{Reline.encoding_system_needs.name}"
|
|
184
|
+
end
|
|
180
185
|
next if line.match(/\A\s*#/)
|
|
181
186
|
|
|
182
187
|
no += 1
|
data/lib/reline/io/ansi.rb
CHANGED
|
@@ -124,6 +124,10 @@ class Reline::ANSI < Reline::IO
|
|
|
124
124
|
Reline.core.line_editor.handle_signal
|
|
125
125
|
end
|
|
126
126
|
c = @input.getbyte
|
|
127
|
+
|
|
128
|
+
# When "Escape non-ASCII Input with Control-V" is enabled in macOS Terminal.app,
|
|
129
|
+
# all non-ascii bytes are automatically escaped with `C-v`.
|
|
130
|
+
# "\xE3\x81\x82" (U+3042) becomes "\x16\xE3\x16\x81\x16\x82".
|
|
127
131
|
(c == 0x16 && @input.tty? && @input.raw(min: 0, time: 0, &:getbyte)) || c
|
|
128
132
|
rescue Errno::EIO
|
|
129
133
|
# Maybe the I/O has been closed.
|
|
@@ -163,31 +167,20 @@ class Reline::ANSI < Reline::IO
|
|
|
163
167
|
@buf.unshift(c)
|
|
164
168
|
end
|
|
165
169
|
|
|
166
|
-
def retrieve_keybuffer
|
|
167
|
-
begin
|
|
168
|
-
return unless @input.wait_readable(0.001)
|
|
169
|
-
str = @input.read_nonblock(1024)
|
|
170
|
-
str.bytes.each do |c|
|
|
171
|
-
@buf.push(c)
|
|
172
|
-
end
|
|
173
|
-
rescue EOFError
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
|
|
177
170
|
def get_screen_size
|
|
178
171
|
s = @input.winsize
|
|
179
172
|
return s if s[0] > 0 && s[1] > 0
|
|
180
173
|
s = [ENV["LINES"].to_i, ENV["COLUMNS"].to_i]
|
|
181
174
|
return s if s[0] > 0 && s[1] > 0
|
|
182
175
|
[24, 80]
|
|
183
|
-
rescue
|
|
176
|
+
rescue SystemCallError
|
|
184
177
|
[24, 80]
|
|
185
178
|
end
|
|
186
179
|
|
|
187
180
|
def set_screen_size(rows, columns)
|
|
188
181
|
@input.winsize = [rows, columns]
|
|
189
182
|
self
|
|
190
|
-
rescue
|
|
183
|
+
rescue SystemCallError
|
|
191
184
|
self
|
|
192
185
|
end
|
|
193
186
|
|
|
@@ -295,7 +288,7 @@ class Reline::ANSI < Reline::IO
|
|
|
295
288
|
# Signal.trap may raise an ArgumentError if the platform doesn't support the signal.
|
|
296
289
|
end
|
|
297
290
|
|
|
298
|
-
def read_single_char(
|
|
291
|
+
def read_single_char(timeout_second)
|
|
299
292
|
# Disable intr to read `C-c` `C-z` `C-\` for quoted insert
|
|
300
293
|
@input.raw(intr: false) do
|
|
301
294
|
super
|
|
@@ -305,7 +298,6 @@ class Reline::ANSI < Reline::IO
|
|
|
305
298
|
def prep
|
|
306
299
|
# Enable bracketed paste
|
|
307
300
|
write "\e[?2004h" if Reline.core.config.enable_bracketed_paste && both_tty?
|
|
308
|
-
retrieve_keybuffer
|
|
309
301
|
nil
|
|
310
302
|
end
|
|
311
303
|
|
data/lib/reline/io.rb
CHANGED
|
@@ -37,10 +37,10 @@ module Reline
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
# Read a single encoding valid character from the input.
|
|
40
|
-
def read_single_char(
|
|
40
|
+
def read_single_char(timeout_second)
|
|
41
41
|
buffer = String.new(encoding: Encoding::ASCII_8BIT)
|
|
42
42
|
loop do
|
|
43
|
-
timeout = buffer.empty? ? Float::INFINITY :
|
|
43
|
+
timeout = buffer.empty? ? Float::INFINITY : timeout_second
|
|
44
44
|
c = getc(timeout)
|
|
45
45
|
return unless c
|
|
46
46
|
|
data/lib/reline/line_editor.rb
CHANGED
|
@@ -470,14 +470,6 @@ class Reline::LineEditor
|
|
|
470
470
|
end
|
|
471
471
|
end
|
|
472
472
|
|
|
473
|
-
def print_nomultiline_prompt
|
|
474
|
-
Reline::IOGate.disable_auto_linewrap(true) if Reline::IOGate.win?
|
|
475
|
-
# Readline's test `TestRelineAsReadline#test_readline` requires first output to be prompt, not cursor reset escape sequence.
|
|
476
|
-
Reline::IOGate.write Reline::Unicode.strip_non_printing_start_end(@prompt) if @prompt && !@is_multiline
|
|
477
|
-
ensure
|
|
478
|
-
Reline::IOGate.disable_auto_linewrap(false) if Reline::IOGate.win?
|
|
479
|
-
end
|
|
480
|
-
|
|
481
473
|
def render
|
|
482
474
|
wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
|
|
483
475
|
new_lines = wrapped_prompt_and_input_lines.flatten(1)[screen_scroll_top, screen_height].map do |prompt, line|
|
|
@@ -956,7 +948,7 @@ class Reline::LineEditor
|
|
|
956
948
|
|
|
957
949
|
def wrap_method_call(method_symbol, key, with_operator)
|
|
958
950
|
if @waiting_proc
|
|
959
|
-
@waiting_proc.call(key)
|
|
951
|
+
@waiting_proc.call(key, method_symbol)
|
|
960
952
|
return
|
|
961
953
|
end
|
|
962
954
|
|
|
@@ -1442,21 +1434,24 @@ class Reline::LineEditor
|
|
|
1442
1434
|
end
|
|
1443
1435
|
alias_method :end_of_line, :ed_move_to_end
|
|
1444
1436
|
|
|
1445
|
-
private def generate_searcher(
|
|
1437
|
+
private def generate_searcher(direction)
|
|
1446
1438
|
search_word = String.new(encoding: encoding)
|
|
1447
1439
|
hit_pointer = nil
|
|
1448
|
-
lambda do |key|
|
|
1440
|
+
lambda do |key, key_symbol|
|
|
1449
1441
|
search_again = false
|
|
1450
|
-
case
|
|
1451
|
-
when
|
|
1442
|
+
case key_symbol
|
|
1443
|
+
when :em_delete_prev_char, :backward_delete_char
|
|
1452
1444
|
grapheme_clusters = search_word.grapheme_clusters
|
|
1453
1445
|
if grapheme_clusters.size > 0
|
|
1454
1446
|
grapheme_clusters.pop
|
|
1455
1447
|
search_word = grapheme_clusters.join
|
|
1456
1448
|
end
|
|
1457
|
-
when
|
|
1458
|
-
search_again =
|
|
1459
|
-
|
|
1449
|
+
when :reverse_search_history, :vi_search_prev
|
|
1450
|
+
search_again = direction == :reverse
|
|
1451
|
+
direction = :reverse
|
|
1452
|
+
when :forward_search_history, :vi_search_next
|
|
1453
|
+
search_again = direction == :forward
|
|
1454
|
+
direction = :forward
|
|
1460
1455
|
else
|
|
1461
1456
|
search_word << key
|
|
1462
1457
|
end
|
|
@@ -1470,11 +1465,11 @@ class Reline::LineEditor
|
|
|
1470
1465
|
search_word = Reline.last_incremental_search
|
|
1471
1466
|
end
|
|
1472
1467
|
if @history_pointer
|
|
1473
|
-
case
|
|
1474
|
-
when
|
|
1468
|
+
case direction
|
|
1469
|
+
when :reverse
|
|
1475
1470
|
history_pointer_base = 0
|
|
1476
1471
|
history = Reline::HISTORY[0..(@history_pointer - 1)]
|
|
1477
|
-
when
|
|
1472
|
+
when :forward
|
|
1478
1473
|
history_pointer_base = @history_pointer + 1
|
|
1479
1474
|
history = Reline::HISTORY[(@history_pointer + 1)..-1]
|
|
1480
1475
|
end
|
|
@@ -1483,11 +1478,11 @@ class Reline::LineEditor
|
|
|
1483
1478
|
history = Reline::HISTORY
|
|
1484
1479
|
end
|
|
1485
1480
|
elsif @history_pointer
|
|
1486
|
-
case
|
|
1487
|
-
when
|
|
1481
|
+
case direction
|
|
1482
|
+
when :reverse
|
|
1488
1483
|
history_pointer_base = 0
|
|
1489
1484
|
history = Reline::HISTORY[0..@history_pointer]
|
|
1490
|
-
when
|
|
1485
|
+
when :forward
|
|
1491
1486
|
history_pointer_base = @history_pointer
|
|
1492
1487
|
history = Reline::HISTORY[@history_pointer..-1]
|
|
1493
1488
|
end
|
|
@@ -1495,12 +1490,12 @@ class Reline::LineEditor
|
|
|
1495
1490
|
history_pointer_base = 0
|
|
1496
1491
|
history = Reline::HISTORY
|
|
1497
1492
|
end
|
|
1498
|
-
case
|
|
1499
|
-
when
|
|
1493
|
+
case direction
|
|
1494
|
+
when :reverse
|
|
1500
1495
|
hit_index = history.rindex { |item|
|
|
1501
1496
|
item.include?(search_word)
|
|
1502
1497
|
}
|
|
1503
|
-
when
|
|
1498
|
+
when :forward
|
|
1504
1499
|
hit_index = history.index { |item|
|
|
1505
1500
|
item.include?(search_word)
|
|
1506
1501
|
}
|
|
@@ -1510,31 +1505,28 @@ class Reline::LineEditor
|
|
|
1510
1505
|
hit = Reline::HISTORY[hit_pointer]
|
|
1511
1506
|
end
|
|
1512
1507
|
end
|
|
1513
|
-
|
|
1514
|
-
when "\C-r"
|
|
1515
|
-
prompt_name = 'reverse-i-search'
|
|
1516
|
-
when "\C-s"
|
|
1517
|
-
prompt_name = 'i-search'
|
|
1518
|
-
end
|
|
1508
|
+
prompt_name = direction == :forward ? 'i-search' : 'reverse-i-search'
|
|
1519
1509
|
prompt_name = "failed #{prompt_name}" unless hit
|
|
1520
1510
|
[search_word, prompt_name, hit_pointer]
|
|
1521
1511
|
end
|
|
1522
1512
|
end
|
|
1523
1513
|
|
|
1524
|
-
private def incremental_search_history(
|
|
1514
|
+
private def incremental_search_history(direction)
|
|
1525
1515
|
backup = @buffer_of_lines.dup, @line_index, @byte_pointer, @history_pointer, @line_backup_in_history
|
|
1526
|
-
searcher = generate_searcher(
|
|
1527
|
-
|
|
1516
|
+
searcher = generate_searcher(direction)
|
|
1517
|
+
prompt_name = direction == :forward ? 'i-search' : 'reverse-i-search'
|
|
1518
|
+
@searching_prompt = "(#{prompt_name})`': "
|
|
1528
1519
|
termination_keys = ["\C-j"]
|
|
1529
1520
|
termination_keys.concat(@config.isearch_terminators.chars) if @config.isearch_terminators
|
|
1530
|
-
|
|
1521
|
+
accept_key_syms = [:em_delete_prev_char, :backward_delete_char, :vi_search_prev, :vi_search_next, :reverse_search_history, :forward_search_history]
|
|
1522
|
+
@waiting_proc = ->(k, key_symbol) {
|
|
1531
1523
|
if k == "\C-g"
|
|
1532
1524
|
# cancel search and restore buffer
|
|
1533
1525
|
@buffer_of_lines, @line_index, @byte_pointer, @history_pointer, @line_backup_in_history = backup
|
|
1534
1526
|
@searching_prompt = nil
|
|
1535
1527
|
@waiting_proc = nil
|
|
1536
|
-
elsif !termination_keys.include?(k) && (k.match?(/[[:print:]]/) ||
|
|
1537
|
-
search_word, prompt_name, hit_pointer = searcher.call(k)
|
|
1528
|
+
elsif !termination_keys.include?(k) && (k.match?(/[[:print:]]/) || accept_key_syms.include?(key_symbol))
|
|
1529
|
+
search_word, prompt_name, hit_pointer = searcher.call(k, key_symbol)
|
|
1538
1530
|
Reline.last_incremental_search = search_word
|
|
1539
1531
|
@searching_prompt = "(%s)`%s'" % [prompt_name, search_word]
|
|
1540
1532
|
@searching_prompt += ': ' unless @is_multiline
|
|
@@ -1549,12 +1541,12 @@ class Reline::LineEditor
|
|
|
1549
1541
|
end
|
|
1550
1542
|
|
|
1551
1543
|
private def vi_search_prev(key)
|
|
1552
|
-
incremental_search_history(
|
|
1544
|
+
incremental_search_history(:reverse)
|
|
1553
1545
|
end
|
|
1554
1546
|
alias_method :reverse_search_history, :vi_search_prev
|
|
1555
1547
|
|
|
1556
1548
|
private def vi_search_next(key)
|
|
1557
|
-
incremental_search_history(
|
|
1549
|
+
incremental_search_history(:forward)
|
|
1558
1550
|
end
|
|
1559
1551
|
alias_method :forward_search_history, :vi_search_next
|
|
1560
1552
|
|
|
@@ -1654,6 +1646,16 @@ class Reline::LineEditor
|
|
|
1654
1646
|
end
|
|
1655
1647
|
alias_method :next_history, :ed_next_history
|
|
1656
1648
|
|
|
1649
|
+
private def ed_beginning_of_history(key)
|
|
1650
|
+
move_history(0, line: :end, cursor: :end)
|
|
1651
|
+
end
|
|
1652
|
+
alias_method :beginning_of_history, :ed_beginning_of_history
|
|
1653
|
+
|
|
1654
|
+
private def ed_end_of_history(key)
|
|
1655
|
+
move_history(Reline::HISTORY.size, line: :end, cursor: :end)
|
|
1656
|
+
end
|
|
1657
|
+
alias_method :end_of_history, :ed_end_of_history
|
|
1658
|
+
|
|
1657
1659
|
private def ed_newline(key)
|
|
1658
1660
|
process_insert(force: true)
|
|
1659
1661
|
if @is_multiline
|
|
@@ -2180,7 +2182,7 @@ class Reline::LineEditor
|
|
|
2180
2182
|
end
|
|
2181
2183
|
|
|
2182
2184
|
private def vi_replace_char(key, arg: 1)
|
|
2183
|
-
@waiting_proc = ->(k) {
|
|
2185
|
+
@waiting_proc = ->(k, _sym) {
|
|
2184
2186
|
if arg == 1
|
|
2185
2187
|
byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
|
|
2186
2188
|
before = current_line.byteslice(0, @byte_pointer)
|
|
@@ -2204,11 +2206,11 @@ class Reline::LineEditor
|
|
|
2204
2206
|
end
|
|
2205
2207
|
|
|
2206
2208
|
private def vi_next_char(key, arg: 1, inclusive: false)
|
|
2207
|
-
@waiting_proc = ->(key_for_proc) { search_next_char(key_for_proc, arg, inclusive: inclusive) }
|
|
2209
|
+
@waiting_proc = ->(key_for_proc, _sym) { search_next_char(key_for_proc, arg, inclusive: inclusive) }
|
|
2208
2210
|
end
|
|
2209
2211
|
|
|
2210
2212
|
private def vi_to_next_char(key, arg: 1, inclusive: false)
|
|
2211
|
-
@waiting_proc = ->(key_for_proc) { search_next_char(key_for_proc, arg, need_prev_char: true, inclusive: inclusive) }
|
|
2213
|
+
@waiting_proc = ->(key_for_proc, _sym) { search_next_char(key_for_proc, arg, need_prev_char: true, inclusive: inclusive) }
|
|
2212
2214
|
end
|
|
2213
2215
|
|
|
2214
2216
|
private def search_next_char(key, arg, need_prev_char: false, inclusive: false)
|
|
@@ -2251,11 +2253,11 @@ class Reline::LineEditor
|
|
|
2251
2253
|
end
|
|
2252
2254
|
|
|
2253
2255
|
private def vi_prev_char(key, arg: 1)
|
|
2254
|
-
@waiting_proc = ->(key_for_proc) { search_prev_char(key_for_proc, arg) }
|
|
2256
|
+
@waiting_proc = ->(key_for_proc, _sym) { search_prev_char(key_for_proc, arg) }
|
|
2255
2257
|
end
|
|
2256
2258
|
|
|
2257
2259
|
private def vi_to_prev_char(key, arg: 1)
|
|
2258
|
-
@waiting_proc = ->(key_for_proc) { search_prev_char(key_for_proc, arg, true) }
|
|
2260
|
+
@waiting_proc = ->(key_for_proc, _sym) { search_prev_char(key_for_proc, arg, true) }
|
|
2259
2261
|
end
|
|
2260
2262
|
|
|
2261
2263
|
private def search_prev_char(key, arg, need_next_char = false)
|
|
@@ -129,7 +129,7 @@ class Reline::Unicode::EastAsianWidth
|
|
|
129
129
|
[0x450, 1],
|
|
130
130
|
[0x451, -1],
|
|
131
131
|
[0x482, 1],
|
|
132
|
-
[
|
|
132
|
+
[0x489, 0],
|
|
133
133
|
[0x590, 1],
|
|
134
134
|
[0x5bd, 0],
|
|
135
135
|
[0x5be, 1],
|
|
@@ -356,6 +356,7 @@ class Reline::Unicode::EastAsianWidth
|
|
|
356
356
|
[0x109d, 0],
|
|
357
357
|
[0x10ff, 1],
|
|
358
358
|
[0x115f, 2],
|
|
359
|
+
[0x11ff, 0],
|
|
359
360
|
[0x135c, 1],
|
|
360
361
|
[0x135f, 0],
|
|
361
362
|
[0x1711, 1],
|
|
@@ -411,8 +412,6 @@ class Reline::Unicode::EastAsianWidth
|
|
|
411
412
|
[0x1a7e, 1],
|
|
412
413
|
[0x1a7f, 0],
|
|
413
414
|
[0x1aaf, 1],
|
|
414
|
-
[0x1abd, 0],
|
|
415
|
-
[0x1abe, 1],
|
|
416
415
|
[0x1ace, 0],
|
|
417
416
|
[0x1aff, 1],
|
|
418
417
|
[0x1b03, 0],
|
|
@@ -491,10 +490,6 @@ class Reline::Unicode::EastAsianWidth
|
|
|
491
490
|
[0x20ab, 1],
|
|
492
491
|
[0x20ac, -1],
|
|
493
492
|
[0x20cf, 1],
|
|
494
|
-
[0x20dc, 0],
|
|
495
|
-
[0x20e0, 1],
|
|
496
|
-
[0x20e1, 0],
|
|
497
|
-
[0x20e4, 1],
|
|
498
493
|
[0x20f0, 0],
|
|
499
494
|
[0x2102, 1],
|
|
500
495
|
[0x2103, -1],
|
|
@@ -767,7 +762,7 @@ class Reline::Unicode::EastAsianWidth
|
|
|
767
762
|
[0xa48f, 1],
|
|
768
763
|
[0xa4c6, 2],
|
|
769
764
|
[0xa66e, 1],
|
|
770
|
-
[
|
|
765
|
+
[0xa672, 0],
|
|
771
766
|
[0xa673, 1],
|
|
772
767
|
[0xa67d, 0],
|
|
773
768
|
[0xa69d, 1],
|
|
@@ -840,6 +835,10 @@ class Reline::Unicode::EastAsianWidth
|
|
|
840
835
|
[0xabed, 0],
|
|
841
836
|
[0xabff, 1],
|
|
842
837
|
[0xd7a3, 2],
|
|
838
|
+
[0xd7af, 1],
|
|
839
|
+
[0xd7c6, 0],
|
|
840
|
+
[0xd7ca, 1],
|
|
841
|
+
[0xd7fb, 0],
|
|
843
842
|
[0xdfff, 1],
|
|
844
843
|
[0xf8ff, -1],
|
|
845
844
|
[0xfaff, 2],
|
data/lib/reline/unicode.rb
CHANGED
|
@@ -37,7 +37,7 @@ class Reline::Unicode
|
|
|
37
37
|
|
|
38
38
|
NON_PRINTING_START = "\1"
|
|
39
39
|
NON_PRINTING_END = "\2"
|
|
40
|
-
CSI_REGEXP = /\e\[[\
|
|
40
|
+
CSI_REGEXP = /\e\[[\x30-\x3f]*[\x20-\x2f]*[a-zA-Z]/
|
|
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
|
|
|
@@ -72,26 +72,32 @@ class Reline::Unicode
|
|
|
72
72
|
|
|
73
73
|
require 'reline/unicode/east_asian_width'
|
|
74
74
|
|
|
75
|
+
def self.east_asian_width(ord)
|
|
76
|
+
chunk_index = EastAsianWidth::CHUNK_LAST.bsearch_index { |o| ord <= o }
|
|
77
|
+
size = EastAsianWidth::CHUNK_WIDTH[chunk_index]
|
|
78
|
+
size == -1 ? Reline.ambiguous_width : size
|
|
79
|
+
end
|
|
80
|
+
|
|
75
81
|
def self.get_mbchar_width(mbchar)
|
|
76
82
|
ord = mbchar.ord
|
|
77
83
|
if ord <= 0x1F # in EscapedPairs
|
|
78
84
|
return 2
|
|
79
|
-
elsif ord <= 0x7E # printable ASCII chars
|
|
85
|
+
elsif mbchar.length == 1 && ord <= 0x7E # printable ASCII chars
|
|
80
86
|
return 1
|
|
81
87
|
end
|
|
88
|
+
|
|
82
89
|
utf8_mbchar = mbchar.encode(Encoding::UTF_8)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
size
|
|
90
|
+
zwj = false
|
|
91
|
+
utf8_mbchar.chars.sum do |c|
|
|
92
|
+
if zwj
|
|
93
|
+
zwj = false
|
|
94
|
+
0
|
|
95
|
+
elsif c.ord == 0x200D # Zero Width Joiner
|
|
96
|
+
zwj = true
|
|
97
|
+
0
|
|
98
|
+
else
|
|
99
|
+
east_asian_width(c.ord)
|
|
100
|
+
end
|
|
95
101
|
end
|
|
96
102
|
end
|
|
97
103
|
|
|
@@ -214,7 +220,7 @@ class Reline::Unicode
|
|
|
214
220
|
next
|
|
215
221
|
elsif padding && !cover_begin && prev_width < start_col && start_col < total_width
|
|
216
222
|
# Add preceding padding. This padding might have background color.
|
|
217
|
-
chunk << ' '
|
|
223
|
+
chunk << ' ' * (total_width - start_col)
|
|
218
224
|
chunk_start_col ||= start_col
|
|
219
225
|
chunk_end_col = total_width
|
|
220
226
|
next
|
|
@@ -228,7 +234,7 @@ class Reline::Unicode
|
|
|
228
234
|
# Current character exceeds end_col
|
|
229
235
|
if padding && end_col < total_width
|
|
230
236
|
# Add succeeding padding. This padding might have background color.
|
|
231
|
-
chunk << ' '
|
|
237
|
+
chunk << ' ' * (end_col - prev_width)
|
|
232
238
|
chunk_start_col ||= prev_width
|
|
233
239
|
chunk_end_col = end_col
|
|
234
240
|
end
|
data/lib/reline/version.rb
CHANGED
data/lib/reline.rb
CHANGED
|
@@ -324,8 +324,6 @@ module Reline
|
|
|
324
324
|
line_editor.auto_indent_proc = auto_indent_proc
|
|
325
325
|
line_editor.dig_perfect_match_proc = dig_perfect_match_proc
|
|
326
326
|
|
|
327
|
-
# Readline calls pre_input_hook just after printing the first prompt.
|
|
328
|
-
line_editor.print_nomultiline_prompt
|
|
329
327
|
pre_input_hook&.call
|
|
330
328
|
|
|
331
329
|
unless Reline::IOGate.dumb?
|
|
@@ -347,7 +345,8 @@ module Reline
|
|
|
347
345
|
# io_gate is Reline::ANSI because the key :bracketed_paste_start is only assigned in Reline::ANSI
|
|
348
346
|
key = Reline::Key.new(io_gate.read_bracketed_paste, :insert_multiline_text)
|
|
349
347
|
when :quoted_insert, :ed_quoted_insert
|
|
350
|
-
|
|
348
|
+
char = io_gate.read_single_char(config.keyseq_timeout.fdiv(1000))
|
|
349
|
+
key = Reline::Key.new(char || '', :insert_raw_char)
|
|
351
350
|
end
|
|
352
351
|
line_editor.set_pasting_state(io_gate.in_pasting?)
|
|
353
352
|
line_editor.update(key)
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: reline
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- aycabta
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: io-console
|
|
@@ -75,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
75
75
|
- !ruby/object:Gem::Version
|
|
76
76
|
version: '0'
|
|
77
77
|
requirements: []
|
|
78
|
-
rubygems_version: 3.6.
|
|
78
|
+
rubygems_version: 3.6.7
|
|
79
79
|
specification_version: 4
|
|
80
80
|
summary: Alternative GNU Readline or Editline implementation by pure Ruby.
|
|
81
81
|
test_files: []
|