reline 0.5.0.pre.1 → 0.5.0
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/ansi.rb +2 -0
- data/lib/reline/face.rb +3 -3
- data/lib/reline/general_io.rb +2 -8
- data/lib/reline/history.rb +1 -1
- data/lib/reline/kill_ring.rb +2 -2
- data/lib/reline/line_editor.rb +100 -117
- data/lib/reline/version.rb +1 -1
- data/lib/reline/windows.rb +3 -1
- data/lib/reline.rb +13 -17
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b325efda8753fa1ecea3b1dabfd685416016ee334876673bf0d965c3a02095d
|
4
|
+
data.tar.gz: 4b22612ebce12cc96593f98535bfb9223eebbded388931ccbd8bbdb4d13ce1d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29f19adce6163f38399da6119c3605039593d244c7119d601b413279a678cd87a5ad5eba5679f2ea7ccc1bdf7b4743987b2840cf4c0f69fa316c0d2fa84b5f45
|
7
|
+
data.tar.gz: be0b1ad84d01936ff721b3a18f196d0ee19817da6baf9200e4e6a96681e4b87594c55d1aa71071fcda63f35c4c8d0aefa7aa7a016c62c538d165e19f82e7d3b8
|
data/lib/reline/ansi.rb
CHANGED
data/lib/reline/face.rb
CHANGED
@@ -186,9 +186,9 @@ class Reline::Face
|
|
186
186
|
conf.define :scrollbar, style: :reset
|
187
187
|
end
|
188
188
|
config(:completion_dialog) do |conf|
|
189
|
-
conf.define :default, foreground: :
|
190
|
-
conf.define :enhanced, foreground: :
|
191
|
-
conf.define :scrollbar, foreground: :white, background: :
|
189
|
+
conf.define :default, foreground: :bright_white, background: :gray
|
190
|
+
conf.define :enhanced, foreground: :black, background: :white
|
191
|
+
conf.define :scrollbar, foreground: :white, background: :gray
|
192
192
|
end
|
193
193
|
end
|
194
194
|
|
data/lib/reline/general_io.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'io/wait'
|
2
2
|
|
3
3
|
class Reline::GeneralIO
|
4
|
+
RESET_COLOR = '' # Do not send color reset sequence
|
5
|
+
|
4
6
|
def self.reset(encoding: nil)
|
5
7
|
@@pasting = false
|
6
8
|
if encoding
|
@@ -100,14 +102,6 @@ class Reline::GeneralIO
|
|
100
102
|
@@pasting
|
101
103
|
end
|
102
104
|
|
103
|
-
def self.start_pasting
|
104
|
-
@@pasting = true
|
105
|
-
end
|
106
|
-
|
107
|
-
def self.finish_pasting
|
108
|
-
@@pasting = false
|
109
|
-
end
|
110
|
-
|
111
105
|
def self.prep
|
112
106
|
end
|
113
107
|
|
data/lib/reline/history.rb
CHANGED
@@ -62,7 +62,7 @@ class Reline::History < Array
|
|
62
62
|
private def check_index(index)
|
63
63
|
index += size if index < 0
|
64
64
|
if index < -2147483648 or 2147483647 < index
|
65
|
-
raise RangeError.new("integer #{index} too big to convert to
|
65
|
+
raise RangeError.new("integer #{index} too big to convert to 'int'")
|
66
66
|
end
|
67
67
|
# If history_size is negative, history size is unlimited.
|
68
68
|
if @config.history_size.positive?
|
data/lib/reline/kill_ring.rb
CHANGED
@@ -14,7 +14,7 @@ class Reline::KillRing
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def ==(other)
|
17
|
-
|
17
|
+
equal?(other)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -68,7 +68,7 @@ class Reline::KillRing
|
|
68
68
|
def append(string, before_p = false)
|
69
69
|
case @state
|
70
70
|
when State::FRESH, State::YANK
|
71
|
-
@ring << RingPoint.new(string)
|
71
|
+
@ring << RingPoint.new(+string)
|
72
72
|
@state = State::CONTINUED
|
73
73
|
when State::CONTINUED, State::PROCESSED
|
74
74
|
if before_p
|
data/lib/reline/line_editor.rb
CHANGED
@@ -46,16 +46,16 @@ class Reline::LineEditor
|
|
46
46
|
PERFECT_MATCH = :perfect_match
|
47
47
|
end
|
48
48
|
|
49
|
+
RenderedScreen = Struct.new(:base_y, :lines, :cursor_y, keyword_init: true)
|
50
|
+
|
49
51
|
CompletionJourneyData = Struct.new(:preposing, :postposing, :list, :pointer)
|
50
52
|
MenuInfo = Struct.new(:target, :list)
|
51
53
|
|
52
|
-
PROMPT_LIST_CACHE_TIMEOUT = 0.5
|
53
54
|
MINIMUM_SCROLLBAR_HEIGHT = 1
|
54
55
|
|
55
56
|
def initialize(config, encoding)
|
56
57
|
@config = config
|
57
58
|
@completion_append_character = ''
|
58
|
-
@cursor_base_y = 0
|
59
59
|
@screen_size = Reline::IOGate.get_screen_size
|
60
60
|
reset_variables(encoding: encoding)
|
61
61
|
end
|
@@ -65,6 +65,9 @@ class Reline::LineEditor
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def set_pasting_state(in_pasting)
|
68
|
+
# While pasting, text to be inserted is stored to @continuous_insertion_buffer.
|
69
|
+
# After pasting, this buffer should be force inserted.
|
70
|
+
process_insert(force: true) if @in_pasting && !in_pasting
|
68
71
|
@in_pasting = in_pasting
|
69
72
|
end
|
70
73
|
|
@@ -82,7 +85,7 @@ class Reline::LineEditor
|
|
82
85
|
end
|
83
86
|
end
|
84
87
|
|
85
|
-
private def check_multiline_prompt(buffer)
|
88
|
+
private def check_multiline_prompt(buffer, mode_string)
|
86
89
|
if @vi_arg
|
87
90
|
prompt = "(arg: #{@vi_arg}) "
|
88
91
|
elsif @searching_prompt
|
@@ -94,7 +97,6 @@ class Reline::LineEditor
|
|
94
97
|
prompt_list = @prompt_proc.(buffer).map { |pr| pr.gsub("\n", "\\n") }
|
95
98
|
prompt_list.map!{ prompt } if @vi_arg or @searching_prompt
|
96
99
|
prompt_list = [prompt] if prompt_list.empty?
|
97
|
-
mode_string = check_mode_string
|
98
100
|
prompt_list = prompt_list.map{ |pr| mode_string + pr } if mode_string
|
99
101
|
prompt = prompt_list[@line_index]
|
100
102
|
prompt = prompt_list[0] if prompt.nil?
|
@@ -106,16 +108,15 @@ class Reline::LineEditor
|
|
106
108
|
end
|
107
109
|
prompt_list
|
108
110
|
else
|
109
|
-
mode_string = check_mode_string
|
110
111
|
prompt = mode_string + prompt if mode_string
|
111
112
|
[prompt] * buffer.size
|
112
113
|
end
|
113
114
|
end
|
114
115
|
|
115
116
|
def reset(prompt = '', encoding:)
|
116
|
-
@cursor_base_y = Reline::IOGate.cursor_pos.y
|
117
117
|
@screen_size = Reline::IOGate.get_screen_size
|
118
118
|
reset_variables(prompt, encoding: encoding)
|
119
|
+
@rendered_screen.base_y = Reline::IOGate.cursor_pos.y
|
119
120
|
Reline::IOGate.set_winch_handler do
|
120
121
|
@resized = true
|
121
122
|
end
|
@@ -145,27 +146,24 @@ class Reline::LineEditor
|
|
145
146
|
def resize
|
146
147
|
return unless @resized
|
147
148
|
|
148
|
-
Reline::IOGate.hide_cursor
|
149
149
|
@screen_size = Reline::IOGate.get_screen_size
|
150
150
|
@resized = false
|
151
151
|
scroll_into_view
|
152
|
-
Reline::IOGate.move_cursor_up @cursor_y
|
153
|
-
@
|
154
|
-
@
|
155
|
-
@
|
152
|
+
Reline::IOGate.move_cursor_up @rendered_screen.cursor_y
|
153
|
+
@rendered_screen.base_y = Reline::IOGate.cursor_pos.y
|
154
|
+
@rendered_screen.lines = []
|
155
|
+
@rendered_screen.cursor_y = 0
|
156
156
|
render_differential
|
157
|
-
Reline::IOGate.show_cursor
|
158
157
|
end
|
159
158
|
|
160
159
|
def set_signal_handlers
|
161
160
|
@old_trap = Signal.trap('INT') {
|
162
|
-
Reline::IOGate.hide_cursor
|
163
161
|
clear_dialogs
|
164
162
|
scrolldown = render_differential
|
165
163
|
Reline::IOGate.scroll_down scrolldown
|
166
164
|
Reline::IOGate.move_cursor_column 0
|
167
|
-
@
|
168
|
-
|
165
|
+
@rendered_screen.lines = []
|
166
|
+
@rendered_screen.cursor_y = 0
|
169
167
|
case @old_trap
|
170
168
|
when 'DEFAULT', 'SYSTEM_DEFAULT'
|
171
169
|
raise Interrupt
|
@@ -205,9 +203,9 @@ class Reline::LineEditor
|
|
205
203
|
@completion_state = CompletionState::NORMAL
|
206
204
|
@perfect_matched = nil
|
207
205
|
@menu_info = nil
|
208
|
-
@first_prompt = true
|
209
206
|
@searching_prompt = nil
|
210
207
|
@first_char = true
|
208
|
+
@just_cursor_moving = false
|
211
209
|
@eof = false
|
212
210
|
@continuous_insertion_buffer = String.new(encoding: @encoding)
|
213
211
|
@scroll_partial_screen = 0
|
@@ -216,9 +214,8 @@ class Reline::LineEditor
|
|
216
214
|
@auto_indent_proc = nil
|
217
215
|
@dialogs = []
|
218
216
|
@resized = false
|
219
|
-
@cursor_y = 0
|
220
217
|
@cache = {}
|
221
|
-
@
|
218
|
+
@rendered_screen = RenderedScreen.new(base_y: 0, lines: [], cursor_y: 0)
|
222
219
|
reset_line
|
223
220
|
end
|
224
221
|
|
@@ -266,20 +263,6 @@ class Reline::LineEditor
|
|
266
263
|
Reline::Unicode.split_by_width(str, max_width, @encoding)
|
267
264
|
end
|
268
265
|
|
269
|
-
private def scroll_down(val)
|
270
|
-
if @cursor_base_y + @cursor_y + val < screen_height
|
271
|
-
Reline::IOGate.move_cursor_down(val)
|
272
|
-
@cursor_y += val
|
273
|
-
else
|
274
|
-
move = screen_height - @cursor_base_y - @cursor_y - 1
|
275
|
-
scroll = val - move
|
276
|
-
Reline::IOGate.scroll_down(move)
|
277
|
-
Reline::IOGate.scroll_down(scroll)
|
278
|
-
@cursor_y += move
|
279
|
-
@cursor_base_y = [@cursor_base_y - scroll, 0].max
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
266
|
def current_byte_pointer_cursor
|
284
267
|
calculate_width(current_line.byteslice(0, @byte_pointer))
|
285
268
|
end
|
@@ -334,8 +317,8 @@ class Reline::LineEditor
|
|
334
317
|
end
|
335
318
|
|
336
319
|
def prompt_list
|
337
|
-
with_cache(__method__, whole_lines, @vi_arg, @searching_prompt) do |lines|
|
338
|
-
check_multiline_prompt(lines)
|
320
|
+
with_cache(__method__, whole_lines, check_mode_string, @vi_arg, @searching_prompt) do |lines, mode_string|
|
321
|
+
check_multiline_prompt(lines, mode_string)
|
339
322
|
end
|
340
323
|
end
|
341
324
|
|
@@ -387,12 +370,12 @@ class Reline::LineEditor
|
|
387
370
|
# do nothing
|
388
371
|
elsif level == :blank
|
389
372
|
Reline::IOGate.move_cursor_column base_x
|
390
|
-
@output.write "
|
373
|
+
@output.write "#{Reline::IOGate::RESET_COLOR}#{' ' * width}"
|
391
374
|
else
|
392
375
|
x, w, content = new_items[level]
|
393
376
|
content = Reline::Unicode.take_range(content, base_x - x, width) unless x == base_x && w == width
|
394
377
|
Reline::IOGate.move_cursor_column base_x
|
395
|
-
@output.write "
|
378
|
+
@output.write "#{Reline::IOGate::RESET_COLOR}#{content}#{Reline::IOGate::RESET_COLOR}"
|
396
379
|
end
|
397
380
|
base_x += width
|
398
381
|
end
|
@@ -402,12 +385,14 @@ class Reline::LineEditor
|
|
402
385
|
end
|
403
386
|
end
|
404
387
|
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
[
|
388
|
+
# Calculate cursor position in word wrapped content.
|
389
|
+
def wrapped_cursor_position
|
390
|
+
prompt_width = calculate_width(prompt_list[@line_index], true)
|
391
|
+
line_before_cursor = whole_lines[@line_index].byteslice(0, @byte_pointer)
|
392
|
+
wrapped_line_before_cursor = split_by_width(' ' * prompt_width + line_before_cursor, screen_width).first.compact
|
393
|
+
wrapped_cursor_y = wrapped_lines[0...@line_index].sum(&:size) + wrapped_line_before_cursor.size - 1
|
394
|
+
wrapped_cursor_x = calculate_width(wrapped_line_before_cursor.last)
|
395
|
+
[wrapped_cursor_x, wrapped_cursor_y]
|
411
396
|
end
|
412
397
|
|
413
398
|
def clear_dialogs
|
@@ -418,19 +403,23 @@ class Reline::LineEditor
|
|
418
403
|
end
|
419
404
|
|
420
405
|
def update_dialogs(key = nil)
|
421
|
-
|
422
|
-
editor_cursor_x, editor_cursor_y = editor_cursor_position
|
406
|
+
wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
|
423
407
|
@dialogs.each do |dialog|
|
424
408
|
dialog.trap_key = nil
|
425
|
-
update_each_dialog(dialog,
|
409
|
+
update_each_dialog(dialog, wrapped_cursor_x, wrapped_cursor_y - screen_scroll_top, key)
|
426
410
|
end
|
427
411
|
end
|
428
412
|
|
413
|
+
def render_finished
|
414
|
+
clear_rendered_lines
|
415
|
+
render_full_content
|
416
|
+
end
|
417
|
+
|
429
418
|
def clear_rendered_lines
|
430
|
-
Reline::IOGate.move_cursor_up @cursor_y
|
419
|
+
Reline::IOGate.move_cursor_up @rendered_screen.cursor_y
|
431
420
|
Reline::IOGate.move_cursor_column 0
|
432
421
|
|
433
|
-
num_lines = @
|
422
|
+
num_lines = @rendered_screen.lines.size
|
434
423
|
return unless num_lines && num_lines >= 1
|
435
424
|
|
436
425
|
Reline::IOGate.move_cursor_down num_lines - 1
|
@@ -439,7 +428,8 @@ class Reline::LineEditor
|
|
439
428
|
Reline::IOGate.move_cursor_up 1
|
440
429
|
end
|
441
430
|
Reline::IOGate.erase_after_cursor
|
442
|
-
@
|
431
|
+
@rendered_screen.lines = []
|
432
|
+
@rendered_screen.cursor_y = 0
|
443
433
|
end
|
444
434
|
|
445
435
|
def render_full_content
|
@@ -455,18 +445,15 @@ class Reline::LineEditor
|
|
455
445
|
return unless prompt && !@is_multiline
|
456
446
|
|
457
447
|
# Readline's test `TestRelineAsReadline#test_readline` requires first output to be prompt, not cursor reset escape sequence.
|
458
|
-
@
|
448
|
+
@rendered_screen.lines = [[[0, Reline::Unicode.calculate_width(prompt, true), prompt]]]
|
449
|
+
@rendered_screen.cursor_y = 0
|
459
450
|
@output.write prompt
|
460
451
|
end
|
461
452
|
|
462
453
|
def render_differential
|
463
|
-
|
464
|
-
update_dialogs
|
465
|
-
end
|
466
|
-
|
467
|
-
editor_cursor_x, editor_cursor_y = editor_cursor_position
|
454
|
+
wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
|
468
455
|
|
469
|
-
rendered_lines = @
|
456
|
+
rendered_lines = @rendered_screen.lines
|
470
457
|
new_lines = wrapped_lines.flatten[screen_scroll_top, screen_height].map do |l|
|
471
458
|
[[0, Reline::Unicode.calculate_width(l, true), l]]
|
472
459
|
end
|
@@ -480,7 +467,7 @@ class Reline::LineEditor
|
|
480
467
|
@dialogs.each_with_index do |dialog, index|
|
481
468
|
next unless dialog.contents
|
482
469
|
|
483
|
-
x_range, y_range = dialog_range dialog,
|
470
|
+
x_range, y_range = dialog_range dialog, wrapped_cursor_y - screen_scroll_top
|
484
471
|
y_range.each do |row|
|
485
472
|
next if row < 0 || row >= screen_height
|
486
473
|
dialog_rows = new_lines[row] ||= []
|
@@ -488,74 +475,65 @@ class Reline::LineEditor
|
|
488
475
|
end
|
489
476
|
end
|
490
477
|
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
478
|
+
cursor_y = @rendered_screen.cursor_y
|
479
|
+
if new_lines != rendered_lines
|
480
|
+
# Hide cursor while rendering to avoid cursor flickering.
|
481
|
+
Reline::IOGate.hide_cursor
|
482
|
+
num_lines = [[new_lines.size, rendered_lines.size].max, screen_height].min
|
483
|
+
if @rendered_screen.base_y + num_lines > screen_height
|
484
|
+
Reline::IOGate.scroll_down(num_lines - cursor_y - 1)
|
485
|
+
@rendered_screen.base_y = screen_height - num_lines
|
486
|
+
cursor_y = num_lines - 1
|
487
|
+
end
|
488
|
+
num_lines.times do |i|
|
489
|
+
rendered_line = rendered_lines[i] || []
|
490
|
+
line_to_render = new_lines[i] || []
|
491
|
+
next if rendered_line == line_to_render
|
492
|
+
|
493
|
+
Reline::IOGate.move_cursor_down i - cursor_y
|
494
|
+
cursor_y = i
|
495
|
+
unless rendered_lines[i]
|
496
|
+
Reline::IOGate.move_cursor_column 0
|
497
|
+
Reline::IOGate.erase_after_cursor
|
498
|
+
end
|
499
|
+
render_line_differential(rendered_line, line_to_render)
|
504
500
|
end
|
505
|
-
|
501
|
+
@rendered_screen.lines = new_lines
|
502
|
+
Reline::IOGate.show_cursor
|
506
503
|
end
|
507
|
-
|
508
|
-
|
509
|
-
Reline::IOGate.
|
510
|
-
|
511
|
-
|
512
|
-
new_lines.size - @cursor_y
|
504
|
+
y = wrapped_cursor_y - screen_scroll_top
|
505
|
+
Reline::IOGate.move_cursor_column wrapped_cursor_x
|
506
|
+
Reline::IOGate.move_cursor_down y - cursor_y
|
507
|
+
@rendered_screen.cursor_y = y
|
508
|
+
new_lines.size - y
|
513
509
|
end
|
514
510
|
|
515
511
|
def current_row
|
516
|
-
wrapped_lines.flatten[
|
512
|
+
wrapped_lines.flatten[wrapped_cursor_y]
|
517
513
|
end
|
518
514
|
|
519
|
-
def upper_space_height
|
520
|
-
|
515
|
+
def upper_space_height(wrapped_cursor_y)
|
516
|
+
wrapped_cursor_y - screen_scroll_top
|
521
517
|
end
|
522
518
|
|
523
|
-
def rest_height
|
524
|
-
screen_height -
|
525
|
-
end
|
526
|
-
|
527
|
-
def rerender_all
|
528
|
-
Reline::IOGate.hide_cursor
|
529
|
-
process_insert(force: true)
|
530
|
-
handle_cleared
|
531
|
-
render_differential unless @in_pasting
|
532
|
-
Reline::IOGate.show_cursor
|
519
|
+
def rest_height(wrapped_cursor_y)
|
520
|
+
screen_height - wrapped_cursor_y + screen_scroll_top - @rendered_screen.base_y - 1
|
533
521
|
end
|
534
522
|
|
535
523
|
def handle_cleared
|
536
524
|
return unless @cleared
|
537
525
|
|
538
526
|
@cleared = false
|
539
|
-
@rendered_screen_cache = nil
|
540
527
|
Reline::IOGate.clear_screen
|
541
528
|
@screen_size = Reline::IOGate.get_screen_size
|
542
|
-
@
|
543
|
-
@
|
544
|
-
|
545
|
-
render_differential
|
529
|
+
@rendered_screen.lines = []
|
530
|
+
@rendered_screen.base_y = 0
|
531
|
+
@rendered_screen.cursor_y = 0
|
546
532
|
end
|
547
533
|
|
548
534
|
def rerender
|
549
|
-
Reline::IOGate.hide_cursor
|
550
|
-
finished = finished?
|
551
535
|
handle_cleared
|
552
|
-
|
553
|
-
clear_rendered_lines
|
554
|
-
render_full_content
|
555
|
-
elsif !@in_pasting
|
556
|
-
render_differential
|
557
|
-
end
|
558
|
-
Reline::IOGate.show_cursor
|
536
|
+
render_differential unless @in_pasting
|
559
537
|
end
|
560
538
|
|
561
539
|
class DialogProcScope
|
@@ -617,8 +595,8 @@ class Reline::LineEditor
|
|
617
595
|
end
|
618
596
|
|
619
597
|
def preferred_dialog_height
|
620
|
-
|
621
|
-
[
|
598
|
+
_wrapped_cursor_x, wrapped_cursor_y = @line_editor.wrapped_cursor_position
|
599
|
+
[@line_editor.upper_space_height(wrapped_cursor_y), @line_editor.rest_height(wrapped_cursor_y), (screen_height + 6) / 5].max
|
622
600
|
end
|
623
601
|
|
624
602
|
def completion_journey_data
|
@@ -747,16 +725,15 @@ class Reline::LineEditor
|
|
747
725
|
else
|
748
726
|
scrollbar_pos = nil
|
749
727
|
end
|
750
|
-
upper_space = upper_space_height
|
751
728
|
dialog.column = dialog_render_info.pos.x
|
752
729
|
dialog.width += @block_elem_width if scrollbar_pos
|
753
730
|
diff = (dialog.column + dialog.width) - screen_width
|
754
731
|
if diff > 0
|
755
732
|
dialog.column -= diff
|
756
733
|
end
|
757
|
-
if (
|
734
|
+
if rest_height(screen_scroll_top + cursor_row) - dialog_render_info.pos.y >= height
|
758
735
|
dialog.vertical_offset = dialog_render_info.pos.y + 1
|
759
|
-
elsif
|
736
|
+
elsif cursor_row >= height
|
760
737
|
dialog.vertical_offset = dialog_render_info.pos.y - height
|
761
738
|
else
|
762
739
|
dialog.vertical_offset = dialog_render_info.pos.y + 1
|
@@ -831,7 +808,7 @@ class Reline::LineEditor
|
|
831
808
|
item_mbchars = item.grapheme_clusters
|
832
809
|
end
|
833
810
|
size = [memo_mbchars.size, item_mbchars.size].min
|
834
|
-
result = ''
|
811
|
+
result = +''
|
835
812
|
size.times do |i|
|
836
813
|
if @config.completion_ignore_case
|
837
814
|
if memo_mbchars[i].casecmp?(item_mbchars[i])
|
@@ -888,7 +865,7 @@ class Reline::LineEditor
|
|
888
865
|
end
|
889
866
|
if not just_show_list and target < completed
|
890
867
|
@buffer_of_lines[@line_index] = (preposing + completed + completion_append_character.to_s + postposing).split("\n")[@line_index] || String.new(encoding: @encoding)
|
891
|
-
line_to_pointer = (preposing + completed + completion_append_character.to_s).split("\n")
|
868
|
+
line_to_pointer = (preposing + completed + completion_append_character.to_s).split("\n")[@line_index] || String.new(encoding: @encoding)
|
892
869
|
@byte_pointer = line_to_pointer.bytesize
|
893
870
|
end
|
894
871
|
end
|
@@ -1169,12 +1146,12 @@ class Reline::LineEditor
|
|
1169
1146
|
end
|
1170
1147
|
|
1171
1148
|
def scroll_into_view
|
1172
|
-
|
1173
|
-
if
|
1174
|
-
@scroll_partial_screen =
|
1149
|
+
_wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
|
1150
|
+
if wrapped_cursor_y < screen_scroll_top
|
1151
|
+
@scroll_partial_screen = wrapped_cursor_y
|
1175
1152
|
end
|
1176
|
-
if
|
1177
|
-
@scroll_partial_screen =
|
1153
|
+
if wrapped_cursor_y >= screen_scroll_top + screen_height
|
1154
|
+
@scroll_partial_screen = wrapped_cursor_y - screen_height + 1
|
1178
1155
|
end
|
1179
1156
|
end
|
1180
1157
|
|
@@ -1233,7 +1210,6 @@ class Reline::LineEditor
|
|
1233
1210
|
end
|
1234
1211
|
|
1235
1212
|
def set_current_line(line, byte_pointer = nil)
|
1236
|
-
@modified = true
|
1237
1213
|
cursor = current_byte_pointer_cursor
|
1238
1214
|
@buffer_of_lines[@line_index] = line
|
1239
1215
|
if byte_pointer
|
@@ -1993,6 +1969,13 @@ class Reline::LineEditor
|
|
1993
1969
|
end
|
1994
1970
|
alias_method :kill_line, :ed_kill_line
|
1995
1971
|
|
1972
|
+
# Editline:: +vi_change_to_eol+ (vi command: +C+) + Kill and change from the cursor to the end of the line.
|
1973
|
+
private def vi_change_to_eol(key)
|
1974
|
+
ed_kill_line(key)
|
1975
|
+
|
1976
|
+
@config.editing_mode = :vi_insert
|
1977
|
+
end
|
1978
|
+
|
1996
1979
|
# Editline:: +vi-kill-line-prev+ (vi: +Ctrl-U+) Delete the string from the
|
1997
1980
|
# beginning of the edit buffer to the cursor and save it to the
|
1998
1981
|
# cut buffer.
|
@@ -2291,7 +2274,7 @@ class Reline::LineEditor
|
|
2291
2274
|
end
|
2292
2275
|
|
2293
2276
|
private def ed_delete_prev_char(key, arg: 1)
|
2294
|
-
deleted = ''
|
2277
|
+
deleted = +''
|
2295
2278
|
arg.times do
|
2296
2279
|
if @byte_pointer > 0
|
2297
2280
|
byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer)
|
data/lib/reline/version.rb
CHANGED
data/lib/reline/windows.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'fiddle/import'
|
2
2
|
|
3
3
|
class Reline::Windows
|
4
|
+
RESET_COLOR = "\e[0m"
|
5
|
+
|
4
6
|
def self.encoding
|
5
7
|
Encoding::UTF_8
|
6
8
|
end
|
@@ -85,7 +87,7 @@ class Reline::Windows
|
|
85
87
|
def call(*args)
|
86
88
|
import = @proto.split("")
|
87
89
|
args.each_with_index do |x, i|
|
88
|
-
args[i], = [x == 0 ? nil : x].pack("p").unpack(POINTER_TYPE) if import[i] == "S"
|
90
|
+
args[i], = [x == 0 ? nil : +x].pack("p").unpack(POINTER_TYPE) if import[i] == "S"
|
89
91
|
args[i], = [x].pack("I").unpack("i") if import[i] == "I"
|
90
92
|
end
|
91
93
|
ret, = @func.call(*args)
|
data/lib/reline.rb
CHANGED
@@ -78,7 +78,6 @@ module Reline
|
|
78
78
|
@dialog_proc_list = {}
|
79
79
|
yield self
|
80
80
|
@completion_quote_character = nil
|
81
|
-
@bracketed_paste_finished = false
|
82
81
|
end
|
83
82
|
|
84
83
|
def io_gate
|
@@ -280,6 +279,7 @@ module Reline
|
|
280
279
|
|
281
280
|
if line_editor.eof?
|
282
281
|
line_editor.reset_line
|
282
|
+
# Return nil if the input is aborted by C-d.
|
283
283
|
nil
|
284
284
|
else
|
285
285
|
whole_buffer
|
@@ -331,8 +331,10 @@ module Reline
|
|
331
331
|
line_editor.auto_indent_proc = auto_indent_proc
|
332
332
|
line_editor.dig_perfect_match_proc = dig_perfect_match_proc
|
333
333
|
pre_input_hook&.call
|
334
|
-
|
335
|
-
|
334
|
+
unless Reline::IOGate == Reline::GeneralIO
|
335
|
+
@dialog_proc_list.each_pair do |name_sym, d|
|
336
|
+
line_editor.add_dialog_proc(name_sym, d.dialog_proc, d.context)
|
337
|
+
end
|
336
338
|
end
|
337
339
|
|
338
340
|
unless config.test_mode
|
@@ -342,28 +344,23 @@ module Reline
|
|
342
344
|
end
|
343
345
|
|
344
346
|
line_editor.print_nomultiline_prompt(prompt)
|
347
|
+
line_editor.update_dialogs
|
345
348
|
line_editor.rerender
|
346
349
|
|
347
350
|
begin
|
348
351
|
line_editor.set_signal_handlers
|
349
|
-
prev_pasting_state = false
|
350
352
|
loop do
|
351
|
-
prev_pasting_state = io_gate.in_pasting?
|
352
353
|
read_io(config.keyseq_timeout) { |inputs|
|
353
354
|
line_editor.set_pasting_state(io_gate.in_pasting?)
|
354
|
-
inputs.each { |
|
355
|
-
line_editor.rerender
|
356
|
-
if @bracketed_paste_finished
|
357
|
-
line_editor.rerender_all
|
358
|
-
@bracketed_paste_finished = false
|
359
|
-
end
|
355
|
+
inputs.each { |key| line_editor.update(key) }
|
360
356
|
}
|
361
|
-
if
|
362
|
-
line_editor.
|
363
|
-
|
364
|
-
|
357
|
+
if line_editor.finished?
|
358
|
+
line_editor.render_finished
|
359
|
+
break
|
360
|
+
else
|
361
|
+
line_editor.set_pasting_state(io_gate.in_pasting?)
|
362
|
+
line_editor.rerender
|
365
363
|
end
|
366
|
-
break if line_editor.finished?
|
367
364
|
end
|
368
365
|
io_gate.move_cursor_column(0)
|
369
366
|
rescue Errno::EIO
|
@@ -398,7 +395,6 @@ module Reline
|
|
398
395
|
c = io_gate.getc(Float::INFINITY)
|
399
396
|
if c == -1
|
400
397
|
result = :unmatched
|
401
|
-
@bracketed_paste_finished = true
|
402
398
|
else
|
403
399
|
buffer << c
|
404
400
|
result = key_stroke.match_status(buffer)
|
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.0
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- aycabta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: io-console
|
@@ -57,7 +57,10 @@ files:
|
|
57
57
|
homepage: https://github.com/ruby/reline
|
58
58
|
licenses:
|
59
59
|
- Ruby
|
60
|
-
metadata:
|
60
|
+
metadata:
|
61
|
+
bug_tracker_uri: https://github.com/ruby/reline/issues
|
62
|
+
changelog_uri: https://github.com/ruby/reline/releases
|
63
|
+
source_code_uri: https://github.com/ruby/reline
|
61
64
|
post_install_message:
|
62
65
|
rdoc_options: []
|
63
66
|
require_paths:
|
@@ -69,11 +72,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
69
72
|
version: '2.6'
|
70
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
74
|
requirements:
|
72
|
-
- - "
|
75
|
+
- - ">="
|
73
76
|
- !ruby/object:Gem::Version
|
74
|
-
version:
|
77
|
+
version: '0'
|
75
78
|
requirements: []
|
76
|
-
rubygems_version: 3.
|
79
|
+
rubygems_version: 3.5.3
|
77
80
|
signing_key:
|
78
81
|
specification_version: 4
|
79
82
|
summary: Alternative GNU Readline or Editline implementation by pure Ruby.
|