reline 0.5.2 → 0.5.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/line_editor.rb +194 -353
- data/lib/reline/unicode.rb +2 -2
- data/lib/reline/version.rb +1 -1
- 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: 77e916d771c2f7219d8cba4be2e3b5e6102dddcb505b342375b8717e069caab1
|
4
|
+
data.tar.gz: ec4262c712ed77b4807255d12887542b37e74cf0e1ccf1dfef78d803d886ba17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0b88eb00ce703b01f691c2fc780a7f9ff43fefdcc9d42d22122bba742ddc03b20db19ecca2c21082081f66d4993f70a3a4cb53ea50ed5a0255728635360c45c
|
7
|
+
data.tar.gz: eb4b51fb15f94e2c349fe4cf19c2d6426f7fdf0800320b89a14d66e6f18ea72f327d7792a8edb6d6034df708bb7c25fbffb625fe7cc03271efdb6662d9c90deb
|
data/lib/reline/line_editor.rb
CHANGED
@@ -112,7 +112,11 @@ class Reline::LineEditor
|
|
112
112
|
else
|
113
113
|
prompt = @prompt
|
114
114
|
end
|
115
|
-
if
|
115
|
+
if !@is_multiline
|
116
|
+
mode_string = check_mode_string
|
117
|
+
prompt = mode_string + prompt if mode_string
|
118
|
+
[prompt] + [''] * (buffer.size - 1)
|
119
|
+
elsif @prompt_proc
|
116
120
|
prompt_list = @prompt_proc.(buffer).map { |pr| pr.gsub("\n", "\\n") }
|
117
121
|
prompt_list.map!{ prompt } if @vi_arg or @searching_prompt
|
118
122
|
prompt_list = [prompt] if prompt_list.empty?
|
@@ -291,8 +295,8 @@ class Reline::LineEditor
|
|
291
295
|
end
|
292
296
|
end
|
293
297
|
|
294
|
-
private def split_by_width(str, max_width)
|
295
|
-
Reline::Unicode.split_by_width(str, max_width, @encoding)
|
298
|
+
private def split_by_width(str, max_width, offset: 0)
|
299
|
+
Reline::Unicode.split_by_width(str, max_width, @encoding, offset: offset)
|
296
300
|
end
|
297
301
|
|
298
302
|
def current_byte_pointer_cursor
|
@@ -366,7 +370,7 @@ class Reline::LineEditor
|
|
366
370
|
@scroll_partial_screen
|
367
371
|
end
|
368
372
|
|
369
|
-
def
|
373
|
+
def wrapped_prompt_and_input_lines
|
370
374
|
with_cache(__method__, @buffer_of_lines.size, modified_lines, prompt_list, screen_width) do |n, lines, prompts, width, prev_cache_key, cached_value|
|
371
375
|
prev_n, prev_lines, prev_prompts, prev_width = prev_cache_key
|
372
376
|
cached_wraps = {}
|
@@ -377,9 +381,14 @@ class Reline::LineEditor
|
|
377
381
|
end
|
378
382
|
|
379
383
|
n.times.map do |i|
|
380
|
-
prompt = prompts[i]
|
381
|
-
line = lines[i]
|
382
|
-
cached_wraps[[prompt, line]]
|
384
|
+
prompt = prompts[i] || ''
|
385
|
+
line = lines[i] || ''
|
386
|
+
if (cached = cached_wraps[[prompt, line]])
|
387
|
+
next cached
|
388
|
+
end
|
389
|
+
*wrapped_prompts, code_line_prompt = split_by_width(prompt, width).first.compact
|
390
|
+
wrapped_lines = split_by_width(line, width, offset: calculate_width(code_line_prompt)).first.compact
|
391
|
+
wrapped_prompts.map { |p| [p, ''] } + [[code_line_prompt, wrapped_lines.first]] + wrapped_lines.drop(1).map { |c| ['', c] }
|
383
392
|
end
|
384
393
|
end
|
385
394
|
end
|
@@ -422,7 +431,7 @@ class Reline::LineEditor
|
|
422
431
|
prompt_width = calculate_width(prompt_list[@line_index], true)
|
423
432
|
line_before_cursor = whole_lines[@line_index].byteslice(0, @byte_pointer)
|
424
433
|
wrapped_line_before_cursor = split_by_width(' ' * prompt_width + line_before_cursor, screen_width).first.compact
|
425
|
-
wrapped_cursor_y =
|
434
|
+
wrapped_cursor_y = wrapped_prompt_and_input_lines[0...@line_index].sum(&:size) + wrapped_line_before_cursor.size - 1
|
426
435
|
wrapped_cursor_x = calculate_width(wrapped_line_before_cursor.last)
|
427
436
|
[wrapped_cursor_x, wrapped_cursor_y]
|
428
437
|
end
|
@@ -486,8 +495,9 @@ class Reline::LineEditor
|
|
486
495
|
wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
|
487
496
|
|
488
497
|
rendered_lines = @rendered_screen.lines
|
489
|
-
new_lines =
|
490
|
-
|
498
|
+
new_lines = wrapped_prompt_and_input_lines.flatten(1)[screen_scroll_top, screen_height].map do |prompt, line|
|
499
|
+
prompt_width = Reline::Unicode.calculate_width(prompt, true)
|
500
|
+
[[0, prompt_width, prompt], [prompt_width, Reline::Unicode.calculate_width(line, true), line]]
|
491
501
|
end
|
492
502
|
if @menu_info
|
493
503
|
@menu_info.lines(screen_width).each do |item|
|
@@ -503,7 +513,8 @@ class Reline::LineEditor
|
|
503
513
|
y_range.each do |row|
|
504
514
|
next if row < 0 || row >= screen_height
|
505
515
|
dialog_rows = new_lines[row] ||= []
|
506
|
-
|
516
|
+
# index 0 is for prompt, index 1 is for line, index 2.. is for dialog
|
517
|
+
dialog_rows[index + 2] = [x_range.begin, dialog.width, dialog.contents[row - y_range.begin]]
|
507
518
|
end
|
508
519
|
end
|
509
520
|
|
@@ -876,10 +887,12 @@ class Reline::LineEditor
|
|
876
887
|
@completion_state = CompletionState::PERFECT_MATCH
|
877
888
|
else
|
878
889
|
@completion_state = CompletionState::MENU_WITH_PERFECT_MATCH
|
890
|
+
complete(list, true) if @config.show_all_if_ambiguous
|
879
891
|
end
|
880
892
|
@perfect_matched = completed
|
881
893
|
else
|
882
894
|
@completion_state = CompletionState::MENU
|
895
|
+
complete(list, true) if @config.show_all_if_ambiguous
|
883
896
|
end
|
884
897
|
if not just_show_list and target < completed
|
885
898
|
@buffer_of_lines[@line_index] = (preposing + completed + completion_append_character.to_s + postposing).split("\n")[@line_index] || String.new(encoding: @encoding)
|
@@ -1220,7 +1233,7 @@ class Reline::LineEditor
|
|
1220
1233
|
end
|
1221
1234
|
|
1222
1235
|
def line()
|
1223
|
-
|
1236
|
+
@buffer_of_lines.join("\n") unless eof?
|
1224
1237
|
end
|
1225
1238
|
|
1226
1239
|
def current_line
|
@@ -1304,14 +1317,12 @@ class Reline::LineEditor
|
|
1304
1317
|
end
|
1305
1318
|
target = before
|
1306
1319
|
end
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
postposing = postposing + "\n" + lines[(@line_index + 1)..-1].join("\n")
|
1314
|
-
end
|
1320
|
+
lines = whole_lines
|
1321
|
+
if @line_index > 0
|
1322
|
+
preposing = lines[0..(@line_index - 1)].join("\n") + "\n" + preposing
|
1323
|
+
end
|
1324
|
+
if (lines.size - 1) > @line_index
|
1325
|
+
postposing = postposing + "\n" + lines[(@line_index + 1)..-1].join("\n")
|
1315
1326
|
end
|
1316
1327
|
[preposing.encode(@encoding), target.encode(@encoding), postposing.encode(@encoding)]
|
1317
1328
|
end
|
@@ -1333,20 +1344,16 @@ class Reline::LineEditor
|
|
1333
1344
|
|
1334
1345
|
def delete_text(start = nil, length = nil)
|
1335
1346
|
if start.nil? and length.nil?
|
1336
|
-
if @
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1346
|
-
@byte_pointer = 0
|
1347
|
-
end
|
1348
|
-
else
|
1349
|
-
set_current_line('', 0)
|
1347
|
+
if @buffer_of_lines.size == 1
|
1348
|
+
@buffer_of_lines[@line_index] = ''
|
1349
|
+
@byte_pointer = 0
|
1350
|
+
elsif @line_index == (@buffer_of_lines.size - 1) and @line_index > 0
|
1351
|
+
@buffer_of_lines.pop
|
1352
|
+
@line_index -= 1
|
1353
|
+
@byte_pointer = 0
|
1354
|
+
elsif @line_index < (@buffer_of_lines.size - 1)
|
1355
|
+
@buffer_of_lines.delete_at(@line_index)
|
1356
|
+
@byte_pointer = 0
|
1350
1357
|
end
|
1351
1358
|
elsif not start.nil? and not length.nil?
|
1352
1359
|
if current_line
|
@@ -1502,7 +1509,7 @@ class Reline::LineEditor
|
|
1502
1509
|
byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
|
1503
1510
|
if (@byte_pointer < current_line.bytesize)
|
1504
1511
|
@byte_pointer += byte_size
|
1505
|
-
elsif @
|
1512
|
+
elsif @config.editing_mode_is?(:emacs) and @byte_pointer == current_line.bytesize and @line_index < @buffer_of_lines.size - 1
|
1506
1513
|
@byte_pointer = 0
|
1507
1514
|
@line_index += 1
|
1508
1515
|
end
|
@@ -1515,7 +1522,7 @@ class Reline::LineEditor
|
|
1515
1522
|
if @byte_pointer > 0
|
1516
1523
|
byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer)
|
1517
1524
|
@byte_pointer -= byte_size
|
1518
|
-
elsif @
|
1525
|
+
elsif @config.editing_mode_is?(:emacs) and @byte_pointer == 0 and @line_index > 0
|
1519
1526
|
@line_index -= 1
|
1520
1527
|
@byte_pointer = current_line.bytesize
|
1521
1528
|
end
|
@@ -1543,131 +1550,95 @@ class Reline::LineEditor
|
|
1543
1550
|
end
|
1544
1551
|
alias_method :end_of_line, :ed_move_to_end
|
1545
1552
|
|
1546
|
-
private def generate_searcher
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
case
|
1553
|
-
when "\C-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1553
|
+
private def generate_searcher(search_key)
|
1554
|
+
search_word = String.new(encoding: @encoding)
|
1555
|
+
multibyte_buf = String.new(encoding: 'ASCII-8BIT')
|
1556
|
+
hit_pointer = nil
|
1557
|
+
lambda do |key|
|
1558
|
+
search_again = false
|
1559
|
+
case key
|
1560
|
+
when "\C-h".ord, "\C-?".ord
|
1561
|
+
grapheme_clusters = search_word.grapheme_clusters
|
1562
|
+
if grapheme_clusters.size > 0
|
1563
|
+
grapheme_clusters.pop
|
1564
|
+
search_word = grapheme_clusters.join
|
1565
|
+
end
|
1566
|
+
when "\C-r".ord, "\C-s".ord
|
1567
|
+
search_again = true if search_key == key
|
1568
|
+
search_key = key
|
1569
|
+
else
|
1570
|
+
multibyte_buf << key
|
1571
|
+
if multibyte_buf.dup.force_encoding(@encoding).valid_encoding?
|
1572
|
+
search_word << multibyte_buf.dup.force_encoding(@encoding)
|
1573
|
+
multibyte_buf.clear
|
1574
|
+
end
|
1557
1575
|
end
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
grapheme_clusters = search_word.grapheme_clusters
|
1567
|
-
if grapheme_clusters.size > 0
|
1568
|
-
grapheme_clusters.pop
|
1569
|
-
search_word = grapheme_clusters.join
|
1570
|
-
end
|
1571
|
-
when "\C-r".ord, "\C-s".ord
|
1572
|
-
search_again = true if prev_search_key == key
|
1573
|
-
prev_search_key = key
|
1574
|
-
else
|
1575
|
-
multibyte_buf << key
|
1576
|
-
if multibyte_buf.dup.force_encoding(@encoding).valid_encoding?
|
1577
|
-
search_word << multibyte_buf.dup.force_encoding(@encoding)
|
1578
|
-
multibyte_buf.clear
|
1576
|
+
hit = nil
|
1577
|
+
if not search_word.empty? and @line_backup_in_history&.include?(search_word)
|
1578
|
+
hit_pointer = Reline::HISTORY.size
|
1579
|
+
hit = @line_backup_in_history
|
1580
|
+
else
|
1581
|
+
if search_again
|
1582
|
+
if search_word.empty? and Reline.last_incremental_search
|
1583
|
+
search_word = Reline.last_incremental_search
|
1579
1584
|
end
|
1580
|
-
|
1581
|
-
|
1582
|
-
if not search_word.empty? and @line_backup_in_history&.include?(search_word)
|
1583
|
-
@history_pointer = nil
|
1584
|
-
hit = @line_backup_in_history
|
1585
|
-
else
|
1586
|
-
if search_again
|
1587
|
-
if search_word.empty? and Reline.last_incremental_search
|
1588
|
-
search_word = Reline.last_incremental_search
|
1589
|
-
end
|
1590
|
-
if @history_pointer
|
1591
|
-
case prev_search_key
|
1592
|
-
when "\C-r".ord
|
1593
|
-
history_pointer_base = 0
|
1594
|
-
history = Reline::HISTORY[0..(@history_pointer - 1)]
|
1595
|
-
when "\C-s".ord
|
1596
|
-
history_pointer_base = @history_pointer + 1
|
1597
|
-
history = Reline::HISTORY[(@history_pointer + 1)..-1]
|
1598
|
-
end
|
1599
|
-
else
|
1600
|
-
history_pointer_base = 0
|
1601
|
-
history = Reline::HISTORY
|
1602
|
-
end
|
1603
|
-
elsif @history_pointer
|
1604
|
-
case prev_search_key
|
1585
|
+
if @history_pointer
|
1586
|
+
case search_key
|
1605
1587
|
when "\C-r".ord
|
1606
1588
|
history_pointer_base = 0
|
1607
|
-
history = Reline::HISTORY[0
|
1589
|
+
history = Reline::HISTORY[0..(@history_pointer - 1)]
|
1608
1590
|
when "\C-s".ord
|
1609
|
-
history_pointer_base = @history_pointer
|
1610
|
-
history = Reline::HISTORY[@history_pointer..-1]
|
1591
|
+
history_pointer_base = @history_pointer + 1
|
1592
|
+
history = Reline::HISTORY[(@history_pointer + 1)..-1]
|
1611
1593
|
end
|
1612
1594
|
else
|
1613
1595
|
history_pointer_base = 0
|
1614
1596
|
history = Reline::HISTORY
|
1615
1597
|
end
|
1616
|
-
|
1598
|
+
elsif @history_pointer
|
1599
|
+
case search_key
|
1617
1600
|
when "\C-r".ord
|
1618
|
-
|
1619
|
-
|
1620
|
-
}
|
1601
|
+
history_pointer_base = 0
|
1602
|
+
history = Reline::HISTORY[0..@history_pointer]
|
1621
1603
|
when "\C-s".ord
|
1622
|
-
|
1623
|
-
|
1624
|
-
}
|
1625
|
-
end
|
1626
|
-
if hit_index
|
1627
|
-
@history_pointer = history_pointer_base + hit_index
|
1628
|
-
hit = Reline::HISTORY[@history_pointer]
|
1604
|
+
history_pointer_base = @history_pointer
|
1605
|
+
history = Reline::HISTORY[@history_pointer..-1]
|
1629
1606
|
end
|
1607
|
+
else
|
1608
|
+
history_pointer_base = 0
|
1609
|
+
history = Reline::HISTORY
|
1630
1610
|
end
|
1631
|
-
case
|
1611
|
+
case search_key
|
1632
1612
|
when "\C-r".ord
|
1633
|
-
|
1613
|
+
hit_index = history.rindex { |item|
|
1614
|
+
item.include?(search_word)
|
1615
|
+
}
|
1634
1616
|
when "\C-s".ord
|
1635
|
-
|
1617
|
+
hit_index = history.index { |item|
|
1618
|
+
item.include?(search_word)
|
1619
|
+
}
|
1636
1620
|
end
|
1637
|
-
if
|
1638
|
-
|
1639
|
-
|
1640
|
-
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
|
1641
|
-
@line_index = @buffer_of_lines.size - 1
|
1642
|
-
@byte_pointer = current_line.bytesize
|
1643
|
-
@searching_prompt = "(%s)`%s'" % [prompt_name, search_word]
|
1644
|
-
else
|
1645
|
-
@buffer_of_lines = [hit]
|
1646
|
-
@byte_pointer = hit.bytesize
|
1647
|
-
@searching_prompt = "(%s)`%s': %s" % [prompt_name, search_word, hit]
|
1648
|
-
end
|
1649
|
-
last_hit = hit
|
1650
|
-
else
|
1651
|
-
if @is_multiline
|
1652
|
-
@searching_prompt = "(failed %s)`%s'" % [prompt_name, search_word]
|
1653
|
-
else
|
1654
|
-
@searching_prompt = "(failed %s)`%s': %s" % [prompt_name, search_word, last_hit]
|
1655
|
-
end
|
1621
|
+
if hit_index
|
1622
|
+
hit_pointer = history_pointer_base + hit_index
|
1623
|
+
hit = Reline::HISTORY[hit_pointer]
|
1656
1624
|
end
|
1657
1625
|
end
|
1626
|
+
case search_key
|
1627
|
+
when "\C-r".ord
|
1628
|
+
prompt_name = 'reverse-i-search'
|
1629
|
+
when "\C-s".ord
|
1630
|
+
prompt_name = 'i-search'
|
1631
|
+
end
|
1632
|
+
prompt_name = "failed #{prompt_name}" unless hit
|
1633
|
+
[search_word, prompt_name, hit_pointer]
|
1658
1634
|
end
|
1659
1635
|
end
|
1660
1636
|
|
1661
1637
|
private def incremental_search_history(key)
|
1662
1638
|
unless @history_pointer
|
1663
|
-
|
1664
|
-
@line_backup_in_history = whole_buffer
|
1665
|
-
else
|
1666
|
-
@line_backup_in_history = current_line
|
1667
|
-
end
|
1639
|
+
@line_backup_in_history = whole_buffer
|
1668
1640
|
end
|
1669
|
-
searcher = generate_searcher
|
1670
|
-
searcher.resume(key)
|
1641
|
+
searcher = generate_searcher(key)
|
1671
1642
|
@searching_prompt = "(reverse-i-search)`': "
|
1672
1643
|
termination_keys = ["\C-j".ord]
|
1673
1644
|
termination_keys.concat(@config.isearch_terminators&.chars&.map(&:ord)) if @config.isearch_terminators
|
@@ -1679,53 +1650,41 @@ class Reline::LineEditor
|
|
1679
1650
|
else
|
1680
1651
|
buffer = @line_backup_in_history
|
1681
1652
|
end
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
@line_index = @buffer_of_lines.size - 1
|
1686
|
-
else
|
1687
|
-
@buffer_of_lines = [buffer]
|
1688
|
-
end
|
1653
|
+
@buffer_of_lines = buffer.split("\n")
|
1654
|
+
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
|
1655
|
+
@line_index = @buffer_of_lines.size - 1
|
1689
1656
|
@searching_prompt = nil
|
1690
1657
|
@waiting_proc = nil
|
1691
1658
|
@byte_pointer = 0
|
1692
|
-
searcher.resume(-1)
|
1693
1659
|
when "\C-g".ord
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
else
|
1699
|
-
@buffer_of_lines = [@line_backup_in_history]
|
1700
|
-
end
|
1701
|
-
@history_pointer = nil
|
1660
|
+
@buffer_of_lines = @line_backup_in_history.split("\n")
|
1661
|
+
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
|
1662
|
+
@line_index = @buffer_of_lines.size - 1
|
1663
|
+
move_history(nil, line: :end, cursor: :end, save_buffer: false)
|
1702
1664
|
@searching_prompt = nil
|
1703
1665
|
@waiting_proc = nil
|
1704
|
-
@line_backup_in_history = nil
|
1705
1666
|
@byte_pointer = 0
|
1706
1667
|
else
|
1707
1668
|
chr = k.is_a?(String) ? k : k.chr(Encoding::ASCII_8BIT)
|
1708
1669
|
if chr.match?(/[[:print:]]/) or k == "\C-h".ord or k == "\C-?".ord or k == "\C-r".ord or k == "\C-s".ord
|
1709
|
-
searcher.
|
1670
|
+
search_word, prompt_name, hit_pointer = searcher.call(k)
|
1671
|
+
Reline.last_incremental_search = search_word
|
1672
|
+
@searching_prompt = "(%s)`%s'" % [prompt_name, search_word]
|
1673
|
+
@searching_prompt += ': ' unless @is_multiline
|
1674
|
+
move_history(hit_pointer, line: :end, cursor: :end, save_buffer: false) if hit_pointer
|
1710
1675
|
else
|
1711
1676
|
if @history_pointer
|
1712
1677
|
line = Reline::HISTORY[@history_pointer]
|
1713
1678
|
else
|
1714
1679
|
line = @line_backup_in_history
|
1715
1680
|
end
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
@line_index = @buffer_of_lines.size - 1
|
1721
|
-
else
|
1722
|
-
@line_backup_in_history = current_line
|
1723
|
-
@buffer_of_lines = [line]
|
1724
|
-
end
|
1681
|
+
@line_backup_in_history = whole_buffer
|
1682
|
+
@buffer_of_lines = line.split("\n")
|
1683
|
+
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
|
1684
|
+
@line_index = @buffer_of_lines.size - 1
|
1725
1685
|
@searching_prompt = nil
|
1726
1686
|
@waiting_proc = nil
|
1727
1687
|
@byte_pointer = 0
|
1728
|
-
searcher.resume(-1)
|
1729
1688
|
end
|
1730
1689
|
end
|
1731
1690
|
}
|
@@ -1741,191 +1700,95 @@ class Reline::LineEditor
|
|
1741
1700
|
end
|
1742
1701
|
alias_method :forward_search_history, :vi_search_next
|
1743
1702
|
|
1744
|
-
private def
|
1745
|
-
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1749
|
-
|
1750
|
-
return if not current_line.empty? and substr.empty?
|
1751
|
-
history = Reline::HISTORY
|
1752
|
-
elsif @history_pointer.zero?
|
1753
|
-
history = nil
|
1754
|
-
h_pointer = nil
|
1755
|
-
else
|
1756
|
-
history = Reline::HISTORY.slice(0, @history_pointer)
|
1757
|
-
end
|
1758
|
-
return if history.nil?
|
1759
|
-
if @is_multiline
|
1760
|
-
h_pointer = history.rindex { |h|
|
1761
|
-
h.split("\n").each_with_index { |l, i|
|
1762
|
-
if l.start_with?(substr)
|
1763
|
-
line_no = i
|
1764
|
-
break
|
1765
|
-
end
|
1766
|
-
}
|
1767
|
-
not line_no.nil?
|
1768
|
-
}
|
1769
|
-
else
|
1770
|
-
h_pointer = history.rindex { |l|
|
1771
|
-
l.start_with?(substr)
|
1772
|
-
}
|
1773
|
-
end
|
1774
|
-
return if h_pointer.nil?
|
1775
|
-
@history_pointer = h_pointer
|
1776
|
-
cursor = current_byte_pointer_cursor
|
1777
|
-
if @is_multiline
|
1778
|
-
@buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
|
1779
|
-
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
|
1780
|
-
@line_index = line_no
|
1781
|
-
calculate_nearest_cursor(cursor)
|
1782
|
-
else
|
1783
|
-
@buffer_of_lines = [Reline::HISTORY[@history_pointer]]
|
1784
|
-
calculate_nearest_cursor(cursor)
|
1703
|
+
private def search_history(prefix, pointer_range)
|
1704
|
+
pointer_range.each do |pointer|
|
1705
|
+
lines = Reline::HISTORY[pointer].split("\n")
|
1706
|
+
lines.each_with_index do |line, index|
|
1707
|
+
return [pointer, index] if line.start_with?(prefix)
|
1708
|
+
end
|
1785
1709
|
end
|
1710
|
+
nil
|
1711
|
+
end
|
1712
|
+
|
1713
|
+
private def ed_search_prev_history(key, arg: 1)
|
1714
|
+
substr = current_line.byteslice(0, @byte_pointer)
|
1715
|
+
return if @history_pointer == 0
|
1716
|
+
return if @history_pointer.nil? && substr.empty? && !current_line.empty?
|
1717
|
+
|
1718
|
+
history_range = 0...(@history_pointer || Reline::HISTORY.size)
|
1719
|
+
h_pointer, line_index = search_history(substr, history_range.reverse_each)
|
1720
|
+
return unless h_pointer
|
1721
|
+
move_history(h_pointer, line: line_index || :start, cursor: @byte_pointer)
|
1786
1722
|
arg -= 1
|
1787
1723
|
ed_search_prev_history(key, arg: arg) if arg > 0
|
1788
1724
|
end
|
1789
1725
|
alias_method :history_search_backward, :ed_search_prev_history
|
1790
1726
|
|
1791
1727
|
private def ed_search_next_history(key, arg: 1)
|
1792
|
-
substr = current_line.
|
1793
|
-
if @history_pointer.nil?
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
end
|
1798
|
-
history = Reline::HISTORY.slice((@history_pointer + 1)..-1)
|
1799
|
-
h_pointer = nil
|
1800
|
-
line_no = nil
|
1801
|
-
if @is_multiline
|
1802
|
-
h_pointer = history.index { |h|
|
1803
|
-
h.split("\n").each_with_index { |l, i|
|
1804
|
-
if l.start_with?(substr)
|
1805
|
-
line_no = i
|
1806
|
-
break
|
1807
|
-
end
|
1808
|
-
}
|
1809
|
-
not line_no.nil?
|
1810
|
-
}
|
1811
|
-
else
|
1812
|
-
h_pointer = history.index { |l|
|
1813
|
-
l.start_with?(substr)
|
1814
|
-
}
|
1815
|
-
end
|
1816
|
-
h_pointer += @history_pointer + 1 if h_pointer and @history_pointer
|
1728
|
+
substr = current_line.byteslice(0, @byte_pointer)
|
1729
|
+
return if @history_pointer.nil?
|
1730
|
+
|
1731
|
+
history_range = @history_pointer + 1...Reline::HISTORY.size
|
1732
|
+
h_pointer, line_index = search_history(substr, history_range)
|
1817
1733
|
return if h_pointer.nil? and not substr.empty?
|
1818
|
-
|
1819
|
-
|
1820
|
-
if @history_pointer.nil? and substr.empty?
|
1821
|
-
@buffer_of_lines = []
|
1822
|
-
@line_index = 0
|
1823
|
-
@byte_pointer = 0
|
1824
|
-
else
|
1825
|
-
cursor = current_byte_pointer_cursor
|
1826
|
-
@buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
|
1827
|
-
@line_index = line_no
|
1828
|
-
calculate_nearest_cursor(cursor)
|
1829
|
-
end
|
1830
|
-
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
|
1831
|
-
else
|
1832
|
-
if @history_pointer.nil? and substr.empty?
|
1833
|
-
set_current_line('', 0)
|
1834
|
-
else
|
1835
|
-
set_current_line(Reline::HISTORY[@history_pointer])
|
1836
|
-
end
|
1837
|
-
end
|
1734
|
+
|
1735
|
+
move_history(h_pointer, line: line_index || :start, cursor: @byte_pointer)
|
1838
1736
|
arg -= 1
|
1839
1737
|
ed_search_next_history(key, arg: arg) if arg > 0
|
1840
1738
|
end
|
1841
1739
|
alias_method :history_search_forward, :ed_search_next_history
|
1842
1740
|
|
1741
|
+
private def move_history(history_pointer, line:, cursor:, save_buffer: true)
|
1742
|
+
history_pointer ||= Reline::HISTORY.size
|
1743
|
+
return if history_pointer < 0 || history_pointer > Reline::HISTORY.size
|
1744
|
+
old_history_pointer = @history_pointer || Reline::HISTORY.size
|
1745
|
+
if old_history_pointer == Reline::HISTORY.size
|
1746
|
+
@line_backup_in_history = save_buffer ? whole_buffer : ''
|
1747
|
+
else
|
1748
|
+
Reline::HISTORY[old_history_pointer] = whole_buffer if save_buffer
|
1749
|
+
end
|
1750
|
+
if history_pointer == Reline::HISTORY.size
|
1751
|
+
buf = @line_backup_in_history
|
1752
|
+
@history_pointer = @line_backup_in_history = nil
|
1753
|
+
else
|
1754
|
+
buf = Reline::HISTORY[history_pointer]
|
1755
|
+
@history_pointer = history_pointer
|
1756
|
+
end
|
1757
|
+
@buffer_of_lines = buf.split("\n")
|
1758
|
+
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
|
1759
|
+
@line_index = line == :start ? 0 : line == :end ? @buffer_of_lines.size - 1 : line
|
1760
|
+
@byte_pointer = cursor == :start ? 0 : cursor == :end ? current_line.bytesize : cursor
|
1761
|
+
end
|
1762
|
+
|
1843
1763
|
private def ed_prev_history(key, arg: 1)
|
1844
|
-
if @
|
1764
|
+
if @line_index > 0
|
1845
1765
|
cursor = current_byte_pointer_cursor
|
1846
1766
|
@line_index -= 1
|
1847
1767
|
calculate_nearest_cursor(cursor)
|
1848
1768
|
return
|
1849
1769
|
end
|
1850
|
-
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
1854
|
-
|
1855
|
-
cursor = current_byte_pointer_cursor
|
1856
|
-
if @is_multiline
|
1857
|
-
@line_backup_in_history = whole_buffer
|
1858
|
-
@buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
|
1859
|
-
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
|
1860
|
-
@line_index = @buffer_of_lines.size - 1
|
1861
|
-
calculate_nearest_cursor(cursor)
|
1862
|
-
else
|
1863
|
-
@line_backup_in_history = whole_buffer
|
1864
|
-
@buffer_of_lines = [Reline::HISTORY[@history_pointer]]
|
1865
|
-
calculate_nearest_cursor(cursor)
|
1866
|
-
end
|
1867
|
-
elsif @history_pointer.zero?
|
1868
|
-
return
|
1869
|
-
else
|
1870
|
-
if @is_multiline
|
1871
|
-
Reline::HISTORY[@history_pointer] = whole_buffer
|
1872
|
-
@history_pointer -= 1
|
1873
|
-
@buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
|
1874
|
-
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
|
1875
|
-
@line_index = @buffer_of_lines.size - 1
|
1876
|
-
else
|
1877
|
-
Reline::HISTORY[@history_pointer] = whole_buffer
|
1878
|
-
@history_pointer -= 1
|
1879
|
-
@buffer_of_lines = [Reline::HISTORY[@history_pointer]]
|
1880
|
-
end
|
1881
|
-
end
|
1882
|
-
if @config.editing_mode_is?(:emacs, :vi_insert)
|
1883
|
-
@byte_pointer = current_line.bytesize
|
1884
|
-
elsif @config.editing_mode_is?(:vi_command)
|
1885
|
-
@byte_pointer = 0
|
1886
|
-
end
|
1770
|
+
move_history(
|
1771
|
+
(@history_pointer || Reline::HISTORY.size) - 1,
|
1772
|
+
line: :end,
|
1773
|
+
cursor: @config.editing_mode_is?(:vi_command) ? :start : :end,
|
1774
|
+
)
|
1887
1775
|
arg -= 1
|
1888
1776
|
ed_prev_history(key, arg: arg) if arg > 0
|
1889
1777
|
end
|
1890
1778
|
alias_method :previous_history, :ed_prev_history
|
1891
1779
|
|
1892
1780
|
private def ed_next_history(key, arg: 1)
|
1893
|
-
if @
|
1781
|
+
if @line_index < (@buffer_of_lines.size - 1)
|
1894
1782
|
cursor = current_byte_pointer_cursor
|
1895
1783
|
@line_index += 1
|
1896
1784
|
calculate_nearest_cursor(cursor)
|
1897
1785
|
return
|
1898
1786
|
end
|
1899
|
-
|
1900
|
-
|
1901
|
-
|
1902
|
-
|
1903
|
-
|
1904
|
-
@buffer_of_lines = @line_backup_in_history.split("\n")
|
1905
|
-
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
|
1906
|
-
@line_index = 0
|
1907
|
-
else
|
1908
|
-
@history_pointer = nil
|
1909
|
-
@buffer_of_lines = [@line_backup_in_history]
|
1910
|
-
end
|
1911
|
-
else
|
1912
|
-
if @is_multiline
|
1913
|
-
Reline::HISTORY[@history_pointer] = whole_buffer
|
1914
|
-
@history_pointer += 1
|
1915
|
-
@buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
|
1916
|
-
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
|
1917
|
-
@line_index = 0
|
1918
|
-
else
|
1919
|
-
Reline::HISTORY[@history_pointer] = whole_buffer
|
1920
|
-
@history_pointer += 1
|
1921
|
-
@buffer_of_lines = [Reline::HISTORY[@history_pointer]]
|
1922
|
-
end
|
1923
|
-
end
|
1924
|
-
if @config.editing_mode_is?(:emacs, :vi_insert)
|
1925
|
-
@byte_pointer = current_line.bytesize
|
1926
|
-
elsif @config.editing_mode_is?(:vi_command)
|
1927
|
-
@byte_pointer = 0
|
1928
|
-
end
|
1787
|
+
move_history(
|
1788
|
+
(@history_pointer || Reline::HISTORY.size) + 1,
|
1789
|
+
line: :start,
|
1790
|
+
cursor: @config.editing_mode_is?(:vi_command) ? :start : :end,
|
1791
|
+
)
|
1929
1792
|
arg -= 1
|
1930
1793
|
ed_next_history(key, arg: arg) if arg > 0
|
1931
1794
|
end
|
@@ -1956,17 +1819,13 @@ class Reline::LineEditor
|
|
1956
1819
|
end
|
1957
1820
|
end
|
1958
1821
|
else
|
1959
|
-
if @history_pointer
|
1960
|
-
Reline::HISTORY[@history_pointer] = whole_buffer
|
1961
|
-
@history_pointer = nil
|
1962
|
-
end
|
1963
1822
|
finish
|
1964
1823
|
end
|
1965
1824
|
end
|
1966
1825
|
|
1967
1826
|
private def em_delete_prev_char(key, arg: 1)
|
1968
1827
|
arg.times do
|
1969
|
-
if @
|
1828
|
+
if @byte_pointer == 0 and @line_index > 0
|
1970
1829
|
@byte_pointer = @buffer_of_lines[@line_index - 1].bytesize
|
1971
1830
|
@buffer_of_lines[@line_index - 1] += @buffer_of_lines.delete_at(@line_index)
|
1972
1831
|
@line_index -= 1
|
@@ -1990,7 +1849,7 @@ class Reline::LineEditor
|
|
1990
1849
|
line, deleted = byteslice!(current_line, @byte_pointer, current_line.bytesize - @byte_pointer)
|
1991
1850
|
set_current_line(line, line.bytesize)
|
1992
1851
|
@kill_ring.append(deleted)
|
1993
|
-
elsif @
|
1852
|
+
elsif @byte_pointer == current_line.bytesize and @buffer_of_lines.size > @line_index + 1
|
1994
1853
|
set_current_line(current_line + @buffer_of_lines.delete_at(@line_index + 1), current_line.bytesize)
|
1995
1854
|
end
|
1996
1855
|
end
|
@@ -2030,7 +1889,7 @@ class Reline::LineEditor
|
|
2030
1889
|
alias_method :kill_whole_line, :em_kill_line
|
2031
1890
|
|
2032
1891
|
private def em_delete(key)
|
2033
|
-
if current_line.empty? and
|
1892
|
+
if current_line.empty? and @buffer_of_lines.size == 1 and key == "\C-d".ord
|
2034
1893
|
@eof = true
|
2035
1894
|
finish
|
2036
1895
|
elsif @byte_pointer < current_line.bytesize
|
@@ -2038,7 +1897,7 @@ class Reline::LineEditor
|
|
2038
1897
|
mbchar = splitted_last.grapheme_clusters.first
|
2039
1898
|
line, = byteslice!(current_line, @byte_pointer, mbchar.bytesize)
|
2040
1899
|
set_current_line(line)
|
2041
|
-
elsif @
|
1900
|
+
elsif @byte_pointer == current_line.bytesize and @buffer_of_lines.size > @line_index + 1
|
2042
1901
|
set_current_line(current_line + @buffer_of_lines.delete_at(@line_index + 1), current_line.bytesize)
|
2043
1902
|
end
|
2044
1903
|
end
|
@@ -2281,7 +2140,7 @@ class Reline::LineEditor
|
|
2281
2140
|
end
|
2282
2141
|
|
2283
2142
|
private def vi_delete_prev_char(key)
|
2284
|
-
if @
|
2143
|
+
if @byte_pointer == 0 and @line_index > 0
|
2285
2144
|
@byte_pointer = @buffer_of_lines[@line_index - 1].bytesize
|
2286
2145
|
@buffer_of_lines[@line_index - 1] += @buffer_of_lines.delete_at(@line_index)
|
2287
2146
|
@line_index -= 1
|
@@ -2378,7 +2237,7 @@ class Reline::LineEditor
|
|
2378
2237
|
end
|
2379
2238
|
|
2380
2239
|
private def vi_list_or_eof(key)
|
2381
|
-
if
|
2240
|
+
if current_line.empty? and @buffer_of_lines.size == 1
|
2382
2241
|
set_current_line('', 0)
|
2383
2242
|
@eof = true
|
2384
2243
|
finish
|
@@ -2409,36 +2268,18 @@ class Reline::LineEditor
|
|
2409
2268
|
if Reline::HISTORY.empty?
|
2410
2269
|
return
|
2411
2270
|
end
|
2412
|
-
|
2413
|
-
@history_pointer = 0
|
2414
|
-
@line_backup_in_history = current_line
|
2415
|
-
set_current_line(Reline::HISTORY[@history_pointer], 0)
|
2416
|
-
elsif @history_pointer.zero?
|
2417
|
-
return
|
2418
|
-
else
|
2419
|
-
Reline::HISTORY[@history_pointer] = current_line
|
2420
|
-
@history_pointer = 0
|
2421
|
-
set_current_line(Reline::HISTORY[@history_pointer], 0)
|
2422
|
-
end
|
2271
|
+
move_history(0, line: :start, cursor: :start)
|
2423
2272
|
end
|
2424
2273
|
|
2425
2274
|
private def vi_histedit(key)
|
2426
2275
|
path = Tempfile.open { |fp|
|
2427
|
-
|
2428
|
-
fp.write whole_lines.join("\n")
|
2429
|
-
else
|
2430
|
-
fp.write current_line
|
2431
|
-
end
|
2276
|
+
fp.write whole_lines.join("\n")
|
2432
2277
|
fp.path
|
2433
2278
|
}
|
2434
2279
|
system("#{ENV['EDITOR']} #{path}")
|
2435
|
-
|
2436
|
-
|
2437
|
-
|
2438
|
-
@line_index = 0
|
2439
|
-
else
|
2440
|
-
@buffer_of_lines = File.read(path).split("\n")
|
2441
|
-
end
|
2280
|
+
@buffer_of_lines = File.read(path).split("\n")
|
2281
|
+
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
|
2282
|
+
@line_index = 0
|
2442
2283
|
finish
|
2443
2284
|
end
|
2444
2285
|
|
@@ -2610,7 +2451,7 @@ class Reline::LineEditor
|
|
2610
2451
|
end
|
2611
2452
|
|
2612
2453
|
private def vi_join_lines(key, arg: 1)
|
2613
|
-
if @
|
2454
|
+
if @buffer_of_lines.size > @line_index + 1
|
2614
2455
|
next_line = @buffer_of_lines.delete_at(@line_index + 1).lstrip
|
2615
2456
|
set_current_line(current_line + ' ' + next_line, current_line.bytesize)
|
2616
2457
|
end
|
data/lib/reline/unicode.rb
CHANGED
@@ -128,10 +128,10 @@ class Reline::Unicode
|
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
131
|
-
def self.split_by_width(str, max_width, encoding = str.encoding)
|
131
|
+
def self.split_by_width(str, max_width, encoding = str.encoding, offset: 0)
|
132
132
|
lines = [String.new(encoding: encoding)]
|
133
133
|
height = 1
|
134
|
-
width =
|
134
|
+
width = offset
|
135
135
|
rest = str.encode(Encoding::UTF_8)
|
136
136
|
in_zero_width = false
|
137
137
|
seq = String.new(encoding: encoding)
|
data/lib/reline/version.rb
CHANGED
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.5.
|
4
|
+
version: 0.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- aycabta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-04-
|
11
|
+
date: 2024-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: io-console
|