reline 0.2.8.pre.2 → 0.2.8.pre.6
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/general_io.rb +1 -0
- data/lib/reline/line_editor.rb +113 -67
- data/lib/reline/unicode.rb +6 -5
- data/lib/reline/version.rb +1 -1
- data/lib/reline.rb +5 -3
- 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: 161818586702ae2834bf5e6490adf5dcec415256925ffd83339ffe6ef3c13012
|
4
|
+
data.tar.gz: 3ab65900ed4022e1baa2213d560938339711264e3188597c4eb98bc1891c81a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 610c5367d68b627fb7e0a7bef7919d147b5a19539725f9a2d184bbed69b0988c613acf1f001d2f05857fce2490e7309e666a4327f1f15cd0541e3bb7db5089ec
|
7
|
+
data.tar.gz: b567f8283fe5637161e21536f500f6824d9a92aadf940e10386d27cf4df29940d3e3d6cb95a7a4fff6e711ac33c73f870ee419b45d44274184160b37354d9d77
|
data/lib/reline/general_io.rb
CHANGED
data/lib/reline/line_editor.rb
CHANGED
@@ -499,6 +499,14 @@ class Reline::LineEditor
|
|
499
499
|
@line_editor.call_completion_proc_with_checking_args(pre, target, post)
|
500
500
|
end
|
501
501
|
|
502
|
+
def set_dialog(dialog)
|
503
|
+
@dialog = dialog
|
504
|
+
end
|
505
|
+
|
506
|
+
def dialog
|
507
|
+
@dialog
|
508
|
+
end
|
509
|
+
|
502
510
|
def set_cursor_pos(col, row)
|
503
511
|
@cursor_pos.x = col
|
504
512
|
@cursor_pos.y = row
|
@@ -530,19 +538,33 @@ class Reline::LineEditor
|
|
530
538
|
end
|
531
539
|
|
532
540
|
class Dialog
|
533
|
-
attr_reader :name
|
534
|
-
attr_accessor :
|
541
|
+
attr_reader :name, :contents, :width
|
542
|
+
attr_accessor :scroll_top, :column, :vertical_offset, :lines_backup
|
535
543
|
|
536
544
|
def initialize(name, proc_scope)
|
537
545
|
@name = name
|
538
546
|
@proc_scope = proc_scope
|
547
|
+
@width = nil
|
548
|
+
@scroll_top = 0
|
539
549
|
end
|
540
550
|
|
541
551
|
def set_cursor_pos(col, row)
|
542
552
|
@proc_scope.set_cursor_pos(col, row)
|
543
553
|
end
|
544
554
|
|
555
|
+
def width=(v)
|
556
|
+
@width = v
|
557
|
+
end
|
558
|
+
|
559
|
+
def contents=(contents)
|
560
|
+
@contents = contents
|
561
|
+
if contents and @width.nil?
|
562
|
+
@width = contents.map{ |line| Reline::Unicode.calculate_width(line, true) }.max
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
545
566
|
def call
|
567
|
+
@proc_scope.set_dialog(self)
|
546
568
|
@proc_scope.call
|
547
569
|
end
|
548
570
|
end
|
@@ -553,27 +575,24 @@ class Reline::LineEditor
|
|
553
575
|
end
|
554
576
|
|
555
577
|
DIALOG_HEIGHT = 20
|
556
|
-
DIALOG_WIDTH = 40
|
557
578
|
private def render_dialog(cursor_column)
|
558
579
|
@dialogs.each do |dialog|
|
559
580
|
render_each_dialog(dialog, cursor_column)
|
560
581
|
end
|
561
582
|
end
|
562
583
|
|
584
|
+
private def padding_space_with_escape_sequences(str, width)
|
585
|
+
str + (' ' * (width - calculate_width(str, true)))
|
586
|
+
end
|
587
|
+
|
563
588
|
private def render_each_dialog(dialog, cursor_column)
|
564
589
|
if @in_pasting
|
565
590
|
dialog.contents = nil
|
566
591
|
return
|
567
592
|
end
|
568
593
|
dialog.set_cursor_pos(cursor_column, @first_line_started_from + @started_from)
|
569
|
-
|
570
|
-
|
571
|
-
old_dialog_column = dialog.column
|
572
|
-
old_dialog_vertical_offset = dialog.vertical_offset
|
573
|
-
if result and not result.empty?
|
574
|
-
dialog.contents = result
|
575
|
-
dialog.contents = dialog.contents[0...DIALOG_HEIGHT] if dialog.contents.size > DIALOG_HEIGHT
|
576
|
-
else
|
594
|
+
dialog_render_info = dialog.call
|
595
|
+
if dialog_render_info.nil? or dialog_render_info.contents.nil? or dialog_render_info.contents.empty?
|
577
596
|
dialog.lines_backup = {
|
578
597
|
lines: modify_lines(whole_lines),
|
579
598
|
line_index: @line_index,
|
@@ -585,39 +604,59 @@ class Reline::LineEditor
|
|
585
604
|
dialog.contents = nil
|
586
605
|
return
|
587
606
|
end
|
607
|
+
old_dialog = dialog.clone
|
608
|
+
dialog.width = dialog_render_info.width if dialog_render_info.width
|
609
|
+
height = dialog_render_info.height || DIALOG_HEIGHT
|
610
|
+
pointer = dialog_render_info.pointer
|
611
|
+
dialog.contents = dialog_render_info.contents
|
612
|
+
height = dialog.contents.size if dialog.contents.size < height
|
613
|
+
if dialog.contents.size > height
|
614
|
+
if dialog_render_info.pointer
|
615
|
+
if dialog_render_info.pointer < 0
|
616
|
+
dialog.scroll_top = 0
|
617
|
+
elsif (dialog_render_info.pointer - dialog.scroll_top) >= (height - 1)
|
618
|
+
dialog.scroll_top = dialog_render_info.pointer - (height - 1)
|
619
|
+
elsif (dialog_render_info.pointer - dialog.scroll_top) < 0
|
620
|
+
dialog.scroll_top = dialog_render_info.pointer
|
621
|
+
end
|
622
|
+
pointer = dialog_render_info.pointer - dialog.scroll_top
|
623
|
+
end
|
624
|
+
dialog.contents = dialog.contents[dialog.scroll_top, height]
|
625
|
+
end
|
588
626
|
upper_space = @first_line_started_from - @started_from
|
589
627
|
lower_space = @highest_in_all - @first_line_started_from - @started_from - 1
|
590
|
-
dialog.column = pos.x
|
591
|
-
diff = (dialog.column +
|
628
|
+
dialog.column = dialog_render_info.pos.x
|
629
|
+
diff = (dialog.column + dialog.width) - (@screen_size.last - 1)
|
592
630
|
if diff > 0
|
593
631
|
dialog.column -= diff
|
594
632
|
end
|
595
|
-
if (lower_space + @rest_height) >=
|
596
|
-
dialog.vertical_offset = pos.y + 1
|
597
|
-
elsif upper_space >=
|
598
|
-
dialog.vertical_offset = pos.y
|
633
|
+
if (lower_space + @rest_height - dialog_render_info.pos.y) >= height
|
634
|
+
dialog.vertical_offset = dialog_render_info.pos.y + 1
|
635
|
+
elsif upper_space >= height
|
636
|
+
dialog.vertical_offset = dialog_render_info.pos.y - height
|
599
637
|
else
|
600
|
-
if (lower_space + @rest_height) <
|
601
|
-
scroll_down(
|
602
|
-
move_cursor_up(
|
638
|
+
if (lower_space + @rest_height - dialog_render_info.pos.y) < height
|
639
|
+
scroll_down(height + dialog_render_info.pos.y)
|
640
|
+
move_cursor_up(height + dialog_render_info.pos.y)
|
603
641
|
end
|
604
|
-
dialog.vertical_offset = pos.y + 1
|
642
|
+
dialog.vertical_offset = dialog_render_info.pos.y + 1
|
605
643
|
end
|
606
644
|
Reline::IOGate.hide_cursor
|
607
|
-
reset_dialog(dialog,
|
645
|
+
reset_dialog(dialog, old_dialog)
|
608
646
|
move_cursor_down(dialog.vertical_offset)
|
609
647
|
Reline::IOGate.move_cursor_column(dialog.column)
|
610
648
|
dialog.contents.each_with_index do |item, i|
|
611
649
|
if i == pointer
|
612
650
|
bg_color = '45'
|
613
651
|
else
|
614
|
-
if
|
615
|
-
bg_color =
|
652
|
+
if dialog_render_info.bg_color
|
653
|
+
bg_color = dialog_render_info.bg_color
|
616
654
|
else
|
617
655
|
bg_color = '46'
|
618
656
|
end
|
619
657
|
end
|
620
|
-
|
658
|
+
str = padding_space_with_escape_sequences(Reline::Unicode.take_range(item, 0, dialog.width), dialog.width)
|
659
|
+
@output.write "\e[#{bg_color}m#{str}\e[49m"
|
621
660
|
Reline::IOGate.move_cursor_column(dialog.column)
|
622
661
|
move_cursor_down(1) if i < (dialog.contents.size - 1)
|
623
662
|
end
|
@@ -633,8 +672,8 @@ class Reline::LineEditor
|
|
633
672
|
}
|
634
673
|
end
|
635
674
|
|
636
|
-
private def reset_dialog(dialog,
|
637
|
-
return if dialog.lines_backup.nil? or
|
675
|
+
private def reset_dialog(dialog, old_dialog)
|
676
|
+
return if dialog.lines_backup.nil? or old_dialog.contents.nil?
|
638
677
|
prompt, prompt_width, prompt_list = check_multiline_prompt(dialog.lines_backup[:lines], prompt)
|
639
678
|
visual_lines = []
|
640
679
|
visual_start = nil
|
@@ -650,76 +689,80 @@ class Reline::LineEditor
|
|
650
689
|
old_y = dialog.lines_backup[:first_line_started_from] + dialog.lines_backup[:started_from]
|
651
690
|
y = @first_line_started_from + @started_from
|
652
691
|
y_diff = y - old_y
|
653
|
-
if (old_y +
|
692
|
+
if (old_y + old_dialog.vertical_offset) < (y + dialog.vertical_offset)
|
654
693
|
# rerender top
|
655
|
-
move_cursor_down(
|
656
|
-
start = visual_start +
|
657
|
-
line_num = dialog.vertical_offset -
|
694
|
+
move_cursor_down(old_dialog.vertical_offset - y_diff)
|
695
|
+
start = visual_start + old_dialog.vertical_offset
|
696
|
+
line_num = dialog.vertical_offset - old_dialog.vertical_offset
|
658
697
|
line_num.times do |i|
|
659
|
-
Reline::IOGate.move_cursor_column(
|
698
|
+
Reline::IOGate.move_cursor_column(old_dialog.column)
|
660
699
|
if visual_lines[start + i].nil?
|
661
|
-
s = ' ' *
|
700
|
+
s = ' ' * dialog.width
|
662
701
|
else
|
663
|
-
s = Reline::Unicode.take_range(visual_lines[start + i],
|
702
|
+
s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column, dialog.width)
|
703
|
+
s = padding_space_with_escape_sequences(s, dialog.width)
|
664
704
|
end
|
665
|
-
@output.write "\e[39m\e[49m
|
705
|
+
@output.write "\e[39m\e[49m#{s}\e[39m\e[49m"
|
666
706
|
move_cursor_down(1) if i < (line_num - 1)
|
667
707
|
end
|
668
|
-
move_cursor_up(
|
708
|
+
move_cursor_up(old_dialog.vertical_offset + line_num - 1 - y_diff)
|
669
709
|
end
|
670
|
-
if (old_y +
|
710
|
+
if (old_y + old_dialog.vertical_offset + old_dialog.contents.size) > (y + dialog.vertical_offset + dialog.contents.size)
|
671
711
|
# rerender bottom
|
672
712
|
move_cursor_down(dialog.vertical_offset + dialog.contents.size - y_diff)
|
673
713
|
start = visual_start + dialog.vertical_offset + dialog.contents.size
|
674
|
-
line_num = (
|
714
|
+
line_num = (old_dialog.vertical_offset + old_dialog.contents.size) - (dialog.vertical_offset + dialog.contents.size)
|
675
715
|
line_num.times do |i|
|
676
|
-
Reline::IOGate.move_cursor_column(
|
716
|
+
Reline::IOGate.move_cursor_column(old_dialog.column)
|
677
717
|
if visual_lines[start + i].nil?
|
678
|
-
s = ' ' *
|
718
|
+
s = ' ' * dialog.width
|
679
719
|
else
|
680
|
-
s = Reline::Unicode.take_range(visual_lines[start + i],
|
720
|
+
s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column, dialog.width)
|
721
|
+
s = padding_space_with_escape_sequences(s, dialog.width)
|
681
722
|
end
|
682
|
-
@output.write "\e[39m\e[49m
|
723
|
+
@output.write "\e[39m\e[49m#{s}\e[39m\e[49m"
|
683
724
|
move_cursor_down(1) if i < (line_num - 1)
|
684
725
|
end
|
685
726
|
move_cursor_up(dialog.vertical_offset + dialog.contents.size + line_num - 1 - y_diff)
|
686
727
|
end
|
687
|
-
if
|
728
|
+
if old_dialog.column < dialog.column
|
688
729
|
# rerender left
|
689
|
-
move_cursor_down(
|
690
|
-
width = dialog.column -
|
691
|
-
start = visual_start +
|
692
|
-
line_num =
|
730
|
+
move_cursor_down(old_dialog.vertical_offset - y_diff)
|
731
|
+
width = dialog.column - old_dialog.column
|
732
|
+
start = visual_start + old_dialog.vertical_offset
|
733
|
+
line_num = old_dialog.contents.size
|
693
734
|
line_num.times do |i|
|
694
|
-
Reline::IOGate.move_cursor_column(
|
735
|
+
Reline::IOGate.move_cursor_column(old_dialog.column)
|
695
736
|
if visual_lines[start + i].nil?
|
696
737
|
s = ' ' * width
|
697
738
|
else
|
698
|
-
s = Reline::Unicode.take_range(visual_lines[start + i],
|
739
|
+
s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column, width)
|
740
|
+
s = padding_space_with_escape_sequences(s, dialog.width)
|
699
741
|
end
|
700
|
-
@output.write "\e[39m\e[49m
|
742
|
+
@output.write "\e[39m\e[49m#{s}\e[39m\e[49m"
|
701
743
|
move_cursor_down(1) if i < (line_num - 1)
|
702
744
|
end
|
703
|
-
move_cursor_up(
|
745
|
+
move_cursor_up(old_dialog.vertical_offset + line_num - 1 - y_diff)
|
704
746
|
end
|
705
|
-
if (
|
747
|
+
if (old_dialog.column + old_dialog.width) > (dialog.column + dialog.width)
|
706
748
|
# rerender right
|
707
|
-
move_cursor_down(
|
708
|
-
width = (
|
709
|
-
start = visual_start +
|
710
|
-
line_num =
|
749
|
+
move_cursor_down(old_dialog.vertical_offset + y_diff)
|
750
|
+
width = (old_dialog.column + old_dialog.width) - (dialog.column + dialog.width)
|
751
|
+
start = visual_start + old_dialog.vertical_offset
|
752
|
+
line_num = old_dialog.contents.size
|
711
753
|
line_num.times do |i|
|
712
|
-
Reline::IOGate.move_cursor_column(
|
754
|
+
Reline::IOGate.move_cursor_column(old_dialog.column + dialog.width)
|
713
755
|
if visual_lines[start + i].nil?
|
714
756
|
s = ' ' * width
|
715
757
|
else
|
716
|
-
s = Reline::Unicode.take_range(visual_lines[start + i],
|
758
|
+
s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column + dialog.width, width)
|
759
|
+
s = padding_space_with_escape_sequences(s, dialog.width)
|
717
760
|
end
|
718
|
-
Reline::IOGate.move_cursor_column(dialog.column +
|
719
|
-
@output.write "\e[39m\e[49m
|
761
|
+
Reline::IOGate.move_cursor_column(dialog.column + dialog.width)
|
762
|
+
@output.write "\e[39m\e[49m#{s}\e[39m\e[49m"
|
720
763
|
move_cursor_down(1) if i < (line_num - 1)
|
721
764
|
end
|
722
|
-
move_cursor_up(
|
765
|
+
move_cursor_up(old_dialog.vertical_offset + line_num - 1 + y_diff)
|
723
766
|
end
|
724
767
|
Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
|
725
768
|
end
|
@@ -752,13 +795,14 @@ class Reline::LineEditor
|
|
752
795
|
dialog_vertical_size = dialog.contents.size
|
753
796
|
dialog_vertical_size.times do |i|
|
754
797
|
if i < visual_lines_under_dialog.size
|
755
|
-
Reline::IOGate.move_cursor_column(
|
756
|
-
|
798
|
+
Reline::IOGate.move_cursor_column(dialog.column)
|
799
|
+
str = Reline::Unicode.take_range(visual_lines_under_dialog[i], dialog.column, dialog.width)
|
800
|
+
str = padding_space_with_escape_sequences(str, dialog.width)
|
801
|
+
@output.write "\e[39m\e[49m#{str}\e[39m\e[49m"
|
757
802
|
else
|
758
803
|
Reline::IOGate.move_cursor_column(dialog.column)
|
759
|
-
@output.write "\e[39m\e[49m#{' ' *
|
804
|
+
@output.write "\e[39m\e[49m#{' ' * dialog.width}\e[39m\e[49m"
|
760
805
|
end
|
761
|
-
Reline::IOGate.erase_after_cursor
|
762
806
|
move_cursor_down(1) if i < (dialog_vertical_size - 1)
|
763
807
|
end
|
764
808
|
move_cursor_up(dialog_vertical_size - 1 + dialog.vertical_offset)
|
@@ -1252,8 +1296,10 @@ class Reline::LineEditor
|
|
1252
1296
|
end
|
1253
1297
|
end
|
1254
1298
|
completed = @completion_journey_data.list[@completion_journey_data.pointer]
|
1255
|
-
|
1256
|
-
|
1299
|
+
new_line = (@completion_journey_data.preposing + completed + @completion_journey_data.postposing).split("\n")[@line_index]
|
1300
|
+
@line = new_line.nil? ? String.new(encoding: @encoding) : new_line
|
1301
|
+
line_to_pointer = (@completion_journey_data.preposing + completed).split("\n").last
|
1302
|
+
line_to_pointer = String.new(encoding: @encoding) if line_to_pointer.nil?
|
1257
1303
|
@cursor_max = calculate_width(@line)
|
1258
1304
|
@cursor = calculate_width(line_to_pointer)
|
1259
1305
|
@byte_pointer = line_to_pointer.bytesize
|
data/lib/reline/unicode.rb
CHANGED
@@ -186,9 +186,9 @@ class Reline::Unicode
|
|
186
186
|
end
|
187
187
|
|
188
188
|
# Take a chunk of a String with escape sequences.
|
189
|
-
def self.take_range(str,
|
189
|
+
def self.take_range(str, start_col, max_width, encoding = str.encoding)
|
190
190
|
chunk = String.new(encoding: encoding)
|
191
|
-
|
191
|
+
total_width = 0
|
192
192
|
rest = str.encode(Encoding::UTF_8)
|
193
193
|
in_zero_width = false
|
194
194
|
rest.scan(WIDTH_SCANNER) do |gc|
|
@@ -206,9 +206,10 @@ class Reline::Unicode
|
|
206
206
|
if in_zero_width
|
207
207
|
chunk << gc
|
208
208
|
else
|
209
|
-
|
210
|
-
|
211
|
-
|
209
|
+
mbchar_width = get_mbchar_width(gc)
|
210
|
+
total_width += mbchar_width
|
211
|
+
break if (start_col + max_width) < total_width
|
212
|
+
chunk << gc if start_col < total_width
|
212
213
|
end
|
213
214
|
end
|
214
215
|
end
|
data/lib/reline/version.rb
CHANGED
data/lib/reline.rb
CHANGED
@@ -18,6 +18,7 @@ module Reline
|
|
18
18
|
|
19
19
|
Key = Struct.new('Key', :char, :combined_char, :with_meta)
|
20
20
|
CursorPos = Struct.new(:x, :y)
|
21
|
+
DialogRenderInfo = Struct.new(:pos, :contents, :pointer, :bg_color, :width, :height, keyword_init: true)
|
21
22
|
|
22
23
|
class Core
|
23
24
|
ATTR_READER_NAMES = %i(
|
@@ -193,7 +194,7 @@ module Reline
|
|
193
194
|
# Auto complete starts only when edited
|
194
195
|
return nil
|
195
196
|
end
|
196
|
-
pre, target, post= retrieve_completion_block(true)
|
197
|
+
pre, target, post = retrieve_completion_block(true)
|
197
198
|
if target.nil? or target.empty?# or target.size <= 3
|
198
199
|
return nil
|
199
200
|
end
|
@@ -219,9 +220,9 @@ module Reline
|
|
219
220
|
cursor_pos_to_render = Reline::CursorPos.new(x, y)
|
220
221
|
if context and context.is_a?(Array)
|
221
222
|
context.clear
|
222
|
-
context.push(cursor_pos_to_render, result, pointer)
|
223
|
+
context.push(cursor_pos_to_render, result, pointer, dialog)
|
223
224
|
end
|
224
|
-
|
225
|
+
DialogRenderInfo.new(pos: cursor_pos_to_render, contents: result, pointer: pointer, height: 15)
|
225
226
|
}
|
226
227
|
Reline::DEFAULT_DIALOG_CONTEXT = Array.new
|
227
228
|
|
@@ -483,6 +484,7 @@ module Reline
|
|
483
484
|
def_single_delegators :core, :last_incremental_search
|
484
485
|
def_single_delegators :core, :last_incremental_search=
|
485
486
|
def_single_delegators :core, :add_dialog_proc
|
487
|
+
def_single_delegators :core, :autocompletion, :autocompletion=
|
486
488
|
|
487
489
|
def_single_delegators :core, :readmultiline
|
488
490
|
def_instance_delegators self, :readmultiline
|
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.2.8.pre.
|
4
|
+
version: 0.2.8.pre.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- aycabta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: io-console
|