reline 0.2.8.pre.4 → 0.2.8.pre.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/reline/config.rb +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
|