reline 0.2.8.pre.4 → 0.2.8.pre.8
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 +16 -2
- data/lib/reline/general_io.rb +1 -0
- data/lib/reline/key_stroke.rb +56 -4
- data/lib/reline/line_editor.rb +157 -76
- data/lib/reline/line_editor.rb.orig +3199 -0
- data/lib/reline/unicode.rb +9 -8
- data/lib/reline/version.rb +1 -1
- data/lib/reline/windows.rb +2 -0
- data/lib/reline.rb +60 -25
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f03d46c602265d3a197f00021df365a9686e4fd0b5d0ef2a037a9ad25143b91
|
4
|
+
data.tar.gz: e97bfb610d3c9498e651b25de97e87380e624b56ea970ab7048b25dca7be9488
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be1a180b58930985ea7ba5d63be81b62c8ffb0b960daf33c5ad984652fa6021151519cc1fa41055c240d7675d628c6749ab69ca67c2c2bfa306a9deab8200c56
|
7
|
+
data.tar.gz: 68be299c9815a350c8afec2c5b27aa02905c8fcc04c6fbba331aded2aded1d0dc160d2e8b01be58a91f308b1ad1dd880209e237de770002422910c6014ddc51a
|
data/lib/reline/config.rb
CHANGED
@@ -50,6 +50,7 @@ class Reline::Config
|
|
50
50
|
@additional_key_bindings[:emacs] = {}
|
51
51
|
@additional_key_bindings[:vi_insert] = {}
|
52
52
|
@additional_key_bindings[:vi_command] = {}
|
53
|
+
@oneshot_key_bindings = {}
|
53
54
|
@skip_section = nil
|
54
55
|
@if_stack = nil
|
55
56
|
@editing_mode_label = :emacs
|
@@ -75,6 +76,7 @@ class Reline::Config
|
|
75
76
|
@additional_key_bindings.keys.each do |key|
|
76
77
|
@additional_key_bindings[key].clear
|
77
78
|
end
|
79
|
+
@oneshot_key_bindings.clear
|
78
80
|
reset_default_key_bindings
|
79
81
|
end
|
80
82
|
|
@@ -128,8 +130,12 @@ class Reline::Config
|
|
128
130
|
return home_rc_path
|
129
131
|
end
|
130
132
|
|
133
|
+
private def default_inputrc_path
|
134
|
+
@default_inputrc_path ||= inputrc_path
|
135
|
+
end
|
136
|
+
|
131
137
|
def read(file = nil)
|
132
|
-
file ||=
|
138
|
+
file ||= default_inputrc_path
|
133
139
|
begin
|
134
140
|
if file.respond_to?(:readlines)
|
135
141
|
lines = file.readlines
|
@@ -149,7 +155,15 @@ class Reline::Config
|
|
149
155
|
|
150
156
|
def key_bindings
|
151
157
|
# override @key_actors[@editing_mode_label].default_key_bindings with @additional_key_bindings[@editing_mode_label]
|
152
|
-
@key_actors[@editing_mode_label].default_key_bindings.merge(@additional_key_bindings[@editing_mode_label])
|
158
|
+
@key_actors[@editing_mode_label].default_key_bindings.merge(@additional_key_bindings[@editing_mode_label]).merge(@oneshot_key_bindings)
|
159
|
+
end
|
160
|
+
|
161
|
+
def add_oneshot_key_binding(keystroke, target)
|
162
|
+
@oneshot_key_bindings[keystroke] = target
|
163
|
+
end
|
164
|
+
|
165
|
+
def reset_oneshot_key_bindings
|
166
|
+
@oneshot_key_bindings.clear
|
153
167
|
end
|
154
168
|
|
155
169
|
def add_default_key_binding_by_keymap(keymap, keystroke, target)
|
data/lib/reline/general_io.rb
CHANGED
data/lib/reline/key_stroke.rb
CHANGED
@@ -1,8 +1,59 @@
|
|
1
1
|
class Reline::KeyStroke
|
2
2
|
using Module.new {
|
3
|
+
refine Integer do
|
4
|
+
def ==(other)
|
5
|
+
if other.is_a?(Reline::Key)
|
6
|
+
if other.combined_char == "\e".ord
|
7
|
+
false
|
8
|
+
else
|
9
|
+
other.combined_char == self
|
10
|
+
end
|
11
|
+
else
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
3
17
|
refine Array do
|
4
18
|
def start_with?(other)
|
5
|
-
|
19
|
+
compressed_me = compress_meta_key
|
20
|
+
compressed_other = other.compress_meta_key
|
21
|
+
i = 0
|
22
|
+
loop do
|
23
|
+
my_c = compressed_me[i]
|
24
|
+
other_c = compressed_other[i]
|
25
|
+
other_is_last = (i + 1) == compressed_other.size
|
26
|
+
me_is_last = (i + 1) == compressed_me.size
|
27
|
+
if my_c != other_c
|
28
|
+
if other_c == "\e".ord and other_is_last and my_c.is_a?(Reline::Key) and my_c.with_meta
|
29
|
+
return true
|
30
|
+
else
|
31
|
+
return false
|
32
|
+
end
|
33
|
+
elsif other_is_last
|
34
|
+
return true
|
35
|
+
elsif me_is_last
|
36
|
+
return false
|
37
|
+
end
|
38
|
+
i += 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def ==(other)
|
43
|
+
compressed_me = compress_meta_key
|
44
|
+
compressed_other = other.compress_meta_key
|
45
|
+
compressed_me.size == compressed_other.size and [compressed_me, compressed_other].transpose.all?{ |i| i[0] == i[1] }
|
46
|
+
end
|
47
|
+
|
48
|
+
def compress_meta_key
|
49
|
+
inject([]) { |result, key|
|
50
|
+
if result.size > 0 and result.last == "\e".ord
|
51
|
+
result[result.size - 1] = Reline::Key.new(key, key | 0b10000000, true)
|
52
|
+
else
|
53
|
+
result << key
|
54
|
+
end
|
55
|
+
result
|
56
|
+
}
|
6
57
|
end
|
7
58
|
|
8
59
|
def bytes
|
@@ -19,8 +70,8 @@ class Reline::KeyStroke
|
|
19
70
|
key_mapping.keys.select { |lhs|
|
20
71
|
lhs.start_with? input
|
21
72
|
}.tap { |it|
|
22
|
-
return :matched if it.size == 1 && (it
|
23
|
-
return :matching if it.size == 1 && (it
|
73
|
+
return :matched if it.size == 1 && (it[0] == input)
|
74
|
+
return :matching if it.size == 1 && (it[0] != input)
|
24
75
|
return :matched if it.max_by(&:size)&.size&.< input.size
|
25
76
|
return :matching if it.size > 1
|
26
77
|
}
|
@@ -32,7 +83,8 @@ class Reline::KeyStroke
|
|
32
83
|
end
|
33
84
|
|
34
85
|
def expand(input)
|
35
|
-
|
86
|
+
input = input.compress_meta_key
|
87
|
+
lhs = key_mapping.keys.select { |item| input.start_with? item }.sort_by(&:size).last
|
36
88
|
return input unless lhs
|
37
89
|
rhs = key_mapping[lhs]
|
38
90
|
|
data/lib/reline/line_editor.rb
CHANGED
@@ -251,6 +251,7 @@ class Reline::LineEditor
|
|
251
251
|
@in_pasting = false
|
252
252
|
@auto_indent_proc = nil
|
253
253
|
@dialogs = []
|
254
|
+
@last_key = nil
|
254
255
|
reset_line
|
255
256
|
end
|
256
257
|
|
@@ -512,6 +513,14 @@ class Reline::LineEditor
|
|
512
513
|
@cursor_pos.y = row
|
513
514
|
end
|
514
515
|
|
516
|
+
def set_key(key)
|
517
|
+
@key = key
|
518
|
+
end
|
519
|
+
|
520
|
+
def key
|
521
|
+
@key
|
522
|
+
end
|
523
|
+
|
515
524
|
def cursor_pos
|
516
525
|
@cursor_pos
|
517
526
|
end
|
@@ -538,12 +547,14 @@ class Reline::LineEditor
|
|
538
547
|
end
|
539
548
|
|
540
549
|
class Dialog
|
541
|
-
attr_reader :name
|
542
|
-
attr_accessor :scroll_top, :column, :vertical_offset, :
|
550
|
+
attr_reader :name, :contents, :width
|
551
|
+
attr_accessor :scroll_top, :column, :vertical_offset, :lines_backup, :trap_key
|
543
552
|
|
544
|
-
def initialize(name, proc_scope)
|
553
|
+
def initialize(name, config, proc_scope)
|
545
554
|
@name = name
|
555
|
+
@config = config
|
546
556
|
@proc_scope = proc_scope
|
557
|
+
@width = nil
|
547
558
|
@scroll_top = 0
|
548
559
|
end
|
549
560
|
|
@@ -551,54 +562,61 @@ class Reline::LineEditor
|
|
551
562
|
@proc_scope.set_cursor_pos(col, row)
|
552
563
|
end
|
553
564
|
|
554
|
-
def
|
565
|
+
def width=(v)
|
566
|
+
@width = v
|
567
|
+
end
|
568
|
+
|
569
|
+
def contents=(contents)
|
570
|
+
@contents = contents
|
571
|
+
if contents and @width.nil?
|
572
|
+
@width = contents.map{ |line| Reline::Unicode.calculate_width(line, true) }.max
|
573
|
+
end
|
574
|
+
end
|
575
|
+
|
576
|
+
def call(key)
|
555
577
|
@proc_scope.set_dialog(self)
|
556
|
-
@proc_scope.
|
578
|
+
@proc_scope.set_key(key)
|
579
|
+
dialog_render_info = @proc_scope.call
|
580
|
+
if @trap_key
|
581
|
+
if @trap_key.any?{ |i| i.is_a?(Array) } # multiple trap
|
582
|
+
@trap_key.each do |t|
|
583
|
+
@config.add_oneshot_key_binding(t, @name)
|
584
|
+
end
|
585
|
+
elsif @trap_key.is_a?(Array)
|
586
|
+
@config.add_oneshot_key_binding(@trap_key, @name)
|
587
|
+
elsif @trap_key.is_a?(Integer) or @trap_key.is_a?(Reline::Key)
|
588
|
+
@config.add_oneshot_key_binding([@trap_key], @name)
|
589
|
+
end
|
590
|
+
end
|
591
|
+
dialog_render_info
|
557
592
|
end
|
558
593
|
end
|
559
594
|
|
560
595
|
def add_dialog_proc(name, p, context = nil)
|
561
596
|
return if @dialogs.any? { |d| d.name == name }
|
562
|
-
@dialogs << Dialog.new(name, DialogProcScope.new(self, @config, p, context))
|
597
|
+
@dialogs << Dialog.new(name, @config, DialogProcScope.new(self, @config, p, context))
|
563
598
|
end
|
564
599
|
|
565
600
|
DIALOG_HEIGHT = 20
|
566
|
-
DIALOG_WIDTH = 40
|
567
601
|
private def render_dialog(cursor_column)
|
568
602
|
@dialogs.each do |dialog|
|
569
603
|
render_each_dialog(dialog, cursor_column)
|
570
604
|
end
|
571
605
|
end
|
572
606
|
|
607
|
+
private def padding_space_with_escape_sequences(str, width)
|
608
|
+
str + (' ' * (width - calculate_width(str, true)))
|
609
|
+
end
|
610
|
+
|
573
611
|
private def render_each_dialog(dialog, cursor_column)
|
574
612
|
if @in_pasting
|
575
613
|
dialog.contents = nil
|
614
|
+
dialog.trap_key = nil
|
576
615
|
return
|
577
616
|
end
|
578
617
|
dialog.set_cursor_pos(cursor_column, @first_line_started_from + @started_from)
|
579
|
-
dialog_render_info = dialog.call
|
580
|
-
|
581
|
-
old_dialog_column = dialog.column
|
582
|
-
old_dialog_vertical_offset = dialog.vertical_offset
|
583
|
-
start = 0
|
584
|
-
if dialog_render_info and dialog_render_info.contents and not dialog_render_info.contents.empty?
|
585
|
-
height = dialog_render_info.height || DIALOG_HEIGHT
|
586
|
-
pointer = dialog_render_info.pointer
|
587
|
-
dialog.contents = dialog_render_info.contents
|
588
|
-
if dialog.contents.size > height
|
589
|
-
if dialog_render_info.pointer
|
590
|
-
if dialog_render_info.pointer < 0
|
591
|
-
dialog.scroll_top = 0
|
592
|
-
elsif (dialog_render_info.pointer - dialog.scroll_top) >= (height - 1)
|
593
|
-
dialog.scroll_top = dialog_render_info.pointer - (height - 1)
|
594
|
-
elsif (dialog_render_info.pointer - dialog.scroll_top) < 0
|
595
|
-
dialog.scroll_top = dialog_render_info.pointer
|
596
|
-
end
|
597
|
-
pointer = dialog_render_info.pointer - dialog.scroll_top
|
598
|
-
end
|
599
|
-
dialog.contents = dialog.contents[dialog.scroll_top, height]
|
600
|
-
end
|
601
|
-
else
|
618
|
+
dialog_render_info = dialog.call(@last_key)
|
619
|
+
if dialog_render_info.nil? or dialog_render_info.contents.nil? or dialog_render_info.contents.empty?
|
602
620
|
dialog.lines_backup = {
|
603
621
|
lines: modify_lines(whole_lines),
|
604
622
|
line_index: @line_index,
|
@@ -608,19 +626,43 @@ class Reline::LineEditor
|
|
608
626
|
}
|
609
627
|
clear_each_dialog(dialog)
|
610
628
|
dialog.contents = nil
|
629
|
+
dialog.trap_key = nil
|
611
630
|
return
|
612
631
|
end
|
632
|
+
old_dialog = dialog.clone
|
633
|
+
dialog.contents = dialog_render_info.contents
|
634
|
+
pointer = dialog_render_info.pointer
|
635
|
+
if dialog_render_info.width
|
636
|
+
dialog.width = dialog_render_info.width
|
637
|
+
else
|
638
|
+
dialog.width = dialog.contents.map { |l| calculate_width(l, true) }.max
|
639
|
+
end
|
640
|
+
height = dialog_render_info.height || DIALOG_HEIGHT
|
641
|
+
height = dialog.contents.size if dialog.contents.size < height
|
642
|
+
if dialog.contents.size > height
|
643
|
+
if dialog_render_info.pointer
|
644
|
+
if dialog_render_info.pointer < 0
|
645
|
+
dialog.scroll_top = 0
|
646
|
+
elsif (dialog_render_info.pointer - dialog.scroll_top) >= (height - 1)
|
647
|
+
dialog.scroll_top = dialog_render_info.pointer - (height - 1)
|
648
|
+
elsif (dialog_render_info.pointer - dialog.scroll_top) < 0
|
649
|
+
dialog.scroll_top = dialog_render_info.pointer
|
650
|
+
end
|
651
|
+
pointer = dialog_render_info.pointer - dialog.scroll_top
|
652
|
+
end
|
653
|
+
dialog.contents = dialog.contents[dialog.scroll_top, height]
|
654
|
+
end
|
613
655
|
upper_space = @first_line_started_from - @started_from
|
614
656
|
lower_space = @highest_in_all - @first_line_started_from - @started_from - 1
|
615
657
|
dialog.column = dialog_render_info.pos.x
|
616
|
-
diff = (dialog.column +
|
658
|
+
diff = (dialog.column + dialog.width) - (@screen_size.last - 1)
|
617
659
|
if diff > 0
|
618
660
|
dialog.column -= diff
|
619
661
|
end
|
620
662
|
if (lower_space + @rest_height - dialog_render_info.pos.y) >= height
|
621
663
|
dialog.vertical_offset = dialog_render_info.pos.y + 1
|
622
664
|
elsif upper_space >= height
|
623
|
-
dialog.vertical_offset = dialog_render_info.pos.y
|
665
|
+
dialog.vertical_offset = dialog_render_info.pos.y - height
|
624
666
|
else
|
625
667
|
if (lower_space + @rest_height - dialog_render_info.pos.y) < height
|
626
668
|
scroll_down(height + dialog_render_info.pos.y)
|
@@ -629,9 +671,16 @@ class Reline::LineEditor
|
|
629
671
|
dialog.vertical_offset = dialog_render_info.pos.y + 1
|
630
672
|
end
|
631
673
|
Reline::IOGate.hide_cursor
|
632
|
-
reset_dialog(dialog,
|
674
|
+
reset_dialog(dialog, old_dialog)
|
633
675
|
move_cursor_down(dialog.vertical_offset)
|
634
676
|
Reline::IOGate.move_cursor_column(dialog.column)
|
677
|
+
if dialog_render_info.scrollbar and dialog_render_info.contents.size > height
|
678
|
+
bar_max_height = height * 2
|
679
|
+
moving_distance = (dialog_render_info.contents.size - height) * 2
|
680
|
+
position_ratio = dialog.scroll_top.zero? ? 0.0 : ((dialog.scroll_top * 2).to_f / moving_distance)
|
681
|
+
bar_height = (bar_max_height * ((dialog.contents.size * 2).to_f / (dialog_render_info.contents.size * 2))).floor.to_i
|
682
|
+
position = ((bar_max_height - bar_height) * position_ratio).floor.to_i
|
683
|
+
end
|
635
684
|
dialog.contents.each_with_index do |item, i|
|
636
685
|
if i == pointer
|
637
686
|
bg_color = '45'
|
@@ -642,10 +691,27 @@ class Reline::LineEditor
|
|
642
691
|
bg_color = '46'
|
643
692
|
end
|
644
693
|
end
|
645
|
-
|
694
|
+
str = padding_space_with_escape_sequences(Reline::Unicode.take_range(item, 0, dialog.width), dialog.width)
|
695
|
+
@output.write "\e[#{bg_color}m#{str}"
|
696
|
+
if dialog_render_info.scrollbar and dialog_render_info.contents.size > height
|
697
|
+
@output.write "\e[37m"
|
698
|
+
if position <= (i * 2) and (i * 2 + 1) < (position + bar_height)
|
699
|
+
@output.write '█'
|
700
|
+
elsif position <= (i * 2) and (i * 2) < (position + bar_height)
|
701
|
+
@output.write '▀'
|
702
|
+
str += ''
|
703
|
+
elsif position <= (i * 2 + 1) and (i * 2) < (position + bar_height)
|
704
|
+
@output.write '▄'
|
705
|
+
else
|
706
|
+
@output.write ' '
|
707
|
+
end
|
708
|
+
@output.write "\e[39m"
|
709
|
+
end
|
710
|
+
@output.write "\e[49m"
|
646
711
|
Reline::IOGate.move_cursor_column(dialog.column)
|
647
712
|
move_cursor_down(1) if i < (dialog.contents.size - 1)
|
648
713
|
end
|
714
|
+
dialog.width += 1 if dialog_render_info.scrollbar and dialog_render_info.contents.size > height
|
649
715
|
Reline::IOGate.move_cursor_column(cursor_column)
|
650
716
|
move_cursor_up(dialog.vertical_offset + dialog.contents.size - 1)
|
651
717
|
Reline::IOGate.show_cursor
|
@@ -658,8 +724,8 @@ class Reline::LineEditor
|
|
658
724
|
}
|
659
725
|
end
|
660
726
|
|
661
|
-
private def reset_dialog(dialog,
|
662
|
-
return if dialog.lines_backup.nil? or
|
727
|
+
private def reset_dialog(dialog, old_dialog)
|
728
|
+
return if dialog.lines_backup.nil? or old_dialog.contents.nil?
|
663
729
|
prompt, prompt_width, prompt_list = check_multiline_prompt(dialog.lines_backup[:lines], prompt)
|
664
730
|
visual_lines = []
|
665
731
|
visual_start = nil
|
@@ -675,76 +741,80 @@ class Reline::LineEditor
|
|
675
741
|
old_y = dialog.lines_backup[:first_line_started_from] + dialog.lines_backup[:started_from]
|
676
742
|
y = @first_line_started_from + @started_from
|
677
743
|
y_diff = y - old_y
|
678
|
-
if (old_y +
|
744
|
+
if (old_y + old_dialog.vertical_offset) < (y + dialog.vertical_offset)
|
679
745
|
# rerender top
|
680
|
-
move_cursor_down(
|
681
|
-
start = visual_start +
|
682
|
-
line_num = dialog.vertical_offset -
|
746
|
+
move_cursor_down(old_dialog.vertical_offset - y_diff)
|
747
|
+
start = visual_start + old_dialog.vertical_offset
|
748
|
+
line_num = dialog.vertical_offset - old_dialog.vertical_offset
|
683
749
|
line_num.times do |i|
|
684
|
-
Reline::IOGate.move_cursor_column(
|
750
|
+
Reline::IOGate.move_cursor_column(old_dialog.column)
|
685
751
|
if visual_lines[start + i].nil?
|
686
|
-
s = ' ' *
|
752
|
+
s = ' ' * dialog.width
|
687
753
|
else
|
688
|
-
s = Reline::Unicode.take_range(visual_lines[start + i],
|
754
|
+
s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column, dialog.width)
|
755
|
+
s = padding_space_with_escape_sequences(s, dialog.width)
|
689
756
|
end
|
690
|
-
@output.write "\e[39m\e[49m
|
757
|
+
@output.write "\e[39m\e[49m#{s}\e[39m\e[49m"
|
691
758
|
move_cursor_down(1) if i < (line_num - 1)
|
692
759
|
end
|
693
|
-
move_cursor_up(
|
760
|
+
move_cursor_up(old_dialog.vertical_offset + line_num - 1 - y_diff)
|
694
761
|
end
|
695
|
-
if (old_y +
|
762
|
+
if (old_y + old_dialog.vertical_offset + old_dialog.contents.size) > (y + dialog.vertical_offset + dialog.contents.size)
|
696
763
|
# rerender bottom
|
697
764
|
move_cursor_down(dialog.vertical_offset + dialog.contents.size - y_diff)
|
698
765
|
start = visual_start + dialog.vertical_offset + dialog.contents.size
|
699
|
-
line_num = (
|
766
|
+
line_num = (old_dialog.vertical_offset + old_dialog.contents.size) - (dialog.vertical_offset + dialog.contents.size)
|
700
767
|
line_num.times do |i|
|
701
|
-
Reline::IOGate.move_cursor_column(
|
768
|
+
Reline::IOGate.move_cursor_column(old_dialog.column)
|
702
769
|
if visual_lines[start + i].nil?
|
703
|
-
s = ' ' *
|
770
|
+
s = ' ' * dialog.width
|
704
771
|
else
|
705
|
-
s = Reline::Unicode.take_range(visual_lines[start + i],
|
772
|
+
s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column, dialog.width)
|
773
|
+
s = padding_space_with_escape_sequences(s, dialog.width)
|
706
774
|
end
|
707
|
-
@output.write "\e[39m\e[49m
|
775
|
+
@output.write "\e[39m\e[49m#{s}\e[39m\e[49m"
|
708
776
|
move_cursor_down(1) if i < (line_num - 1)
|
709
777
|
end
|
710
778
|
move_cursor_up(dialog.vertical_offset + dialog.contents.size + line_num - 1 - y_diff)
|
711
779
|
end
|
712
|
-
if
|
780
|
+
if old_dialog.column < dialog.column
|
713
781
|
# rerender left
|
714
|
-
move_cursor_down(
|
715
|
-
width = dialog.column -
|
716
|
-
start = visual_start +
|
717
|
-
line_num =
|
782
|
+
move_cursor_down(old_dialog.vertical_offset - y_diff)
|
783
|
+
width = dialog.column - old_dialog.column
|
784
|
+
start = visual_start + old_dialog.vertical_offset
|
785
|
+
line_num = old_dialog.contents.size
|
718
786
|
line_num.times do |i|
|
719
|
-
Reline::IOGate.move_cursor_column(
|
787
|
+
Reline::IOGate.move_cursor_column(old_dialog.column)
|
720
788
|
if visual_lines[start + i].nil?
|
721
789
|
s = ' ' * width
|
722
790
|
else
|
723
|
-
s = Reline::Unicode.take_range(visual_lines[start + i],
|
791
|
+
s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column, width)
|
792
|
+
s = padding_space_with_escape_sequences(s, dialog.width)
|
724
793
|
end
|
725
|
-
@output.write "\e[39m\e[49m
|
794
|
+
@output.write "\e[39m\e[49m#{s}\e[39m\e[49m"
|
726
795
|
move_cursor_down(1) if i < (line_num - 1)
|
727
796
|
end
|
728
|
-
move_cursor_up(
|
797
|
+
move_cursor_up(old_dialog.vertical_offset + line_num - 1 - y_diff)
|
729
798
|
end
|
730
|
-
if (
|
799
|
+
if (old_dialog.column + old_dialog.width) > (dialog.column + dialog.width)
|
731
800
|
# rerender right
|
732
|
-
move_cursor_down(
|
733
|
-
width = (
|
734
|
-
start = visual_start +
|
735
|
-
line_num =
|
801
|
+
move_cursor_down(old_dialog.vertical_offset + y_diff)
|
802
|
+
width = (old_dialog.column + old_dialog.width) - (dialog.column + dialog.width)
|
803
|
+
start = visual_start + old_dialog.vertical_offset
|
804
|
+
line_num = old_dialog.contents.size
|
736
805
|
line_num.times do |i|
|
737
|
-
Reline::IOGate.move_cursor_column(
|
806
|
+
Reline::IOGate.move_cursor_column(old_dialog.column + dialog.width)
|
738
807
|
if visual_lines[start + i].nil?
|
739
808
|
s = ' ' * width
|
740
809
|
else
|
741
|
-
s = Reline::Unicode.take_range(visual_lines[start + i],
|
810
|
+
s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column + dialog.width, width)
|
811
|
+
s = padding_space_with_escape_sequences(s, dialog.width)
|
742
812
|
end
|
743
|
-
Reline::IOGate.move_cursor_column(dialog.column +
|
744
|
-
@output.write "\e[39m\e[49m
|
813
|
+
Reline::IOGate.move_cursor_column(dialog.column + dialog.width)
|
814
|
+
@output.write "\e[39m\e[49m#{s}\e[39m\e[49m"
|
745
815
|
move_cursor_down(1) if i < (line_num - 1)
|
746
816
|
end
|
747
|
-
move_cursor_up(
|
817
|
+
move_cursor_up(old_dialog.vertical_offset + line_num - 1 + y_diff)
|
748
818
|
end
|
749
819
|
Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
|
750
820
|
end
|
@@ -756,6 +826,7 @@ class Reline::LineEditor
|
|
756
826
|
end
|
757
827
|
|
758
828
|
private def clear_each_dialog(dialog)
|
829
|
+
dialog.trap_key = nil
|
759
830
|
return unless dialog.contents
|
760
831
|
prompt, prompt_width, prompt_list = check_multiline_prompt(dialog.lines_backup[:lines], prompt)
|
761
832
|
visual_lines = []
|
@@ -777,13 +848,14 @@ class Reline::LineEditor
|
|
777
848
|
dialog_vertical_size = dialog.contents.size
|
778
849
|
dialog_vertical_size.times do |i|
|
779
850
|
if i < visual_lines_under_dialog.size
|
780
|
-
Reline::IOGate.move_cursor_column(
|
781
|
-
|
851
|
+
Reline::IOGate.move_cursor_column(dialog.column)
|
852
|
+
str = Reline::Unicode.take_range(visual_lines_under_dialog[i], dialog.column, dialog.width)
|
853
|
+
str = padding_space_with_escape_sequences(str, dialog.width)
|
854
|
+
@output.write "\e[39m\e[49m#{str}\e[39m\e[49m"
|
782
855
|
else
|
783
856
|
Reline::IOGate.move_cursor_column(dialog.column)
|
784
|
-
@output.write "\e[39m\e[49m#{' ' *
|
857
|
+
@output.write "\e[39m\e[49m#{' ' * dialog.width}\e[39m\e[49m"
|
785
858
|
end
|
786
|
-
Reline::IOGate.erase_after_cursor
|
787
859
|
move_cursor_down(1) if i < (dialog_vertical_size - 1)
|
788
860
|
end
|
789
861
|
move_cursor_up(dialog_vertical_size - 1 + dialog.vertical_offset)
|
@@ -1277,8 +1349,10 @@ class Reline::LineEditor
|
|
1277
1349
|
end
|
1278
1350
|
end
|
1279
1351
|
completed = @completion_journey_data.list[@completion_journey_data.pointer]
|
1280
|
-
|
1281
|
-
|
1352
|
+
new_line = (@completion_journey_data.preposing + completed + @completion_journey_data.postposing).split("\n")[@line_index]
|
1353
|
+
@line = new_line.nil? ? String.new(encoding: @encoding) : new_line
|
1354
|
+
line_to_pointer = (@completion_journey_data.preposing + completed).split("\n").last
|
1355
|
+
line_to_pointer = String.new(encoding: @encoding) if line_to_pointer.nil?
|
1282
1356
|
@cursor_max = calculate_width(@line)
|
1283
1357
|
@cursor = calculate_width(line_to_pointer)
|
1284
1358
|
@byte_pointer = line_to_pointer.bytesize
|
@@ -1439,6 +1513,13 @@ class Reline::LineEditor
|
|
1439
1513
|
end
|
1440
1514
|
|
1441
1515
|
def input_key(key)
|
1516
|
+
@last_key = key
|
1517
|
+
@config.reset_oneshot_key_bindings
|
1518
|
+
@dialogs.each do |dialog|
|
1519
|
+
if key.char.instance_of?(Symbol) and key.char == dialog.name
|
1520
|
+
return
|
1521
|
+
end
|
1522
|
+
end
|
1442
1523
|
@just_cursor_moving = nil
|
1443
1524
|
if key.char.nil?
|
1444
1525
|
if @first_char
|