reline 0.5.9 → 0.5.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -72,17 +72,21 @@ class Reline::LineEditor
72
72
 
73
73
  MINIMUM_SCROLLBAR_HEIGHT = 1
74
74
 
75
- def initialize(config, encoding)
75
+ def initialize(config)
76
76
  @config = config
77
77
  @completion_append_character = ''
78
78
  @screen_size = [0, 0] # Should be initialized with actual winsize in LineEditor#reset
79
- reset_variables(encoding: encoding)
79
+ reset_variables
80
80
  end
81
81
 
82
82
  def io_gate
83
83
  Reline::IOGate
84
84
  end
85
85
 
86
+ def encoding
87
+ io_gate.encoding
88
+ end
89
+
86
90
  def set_pasting_state(in_pasting)
87
91
  # While pasting, text to be inserted is stored to @continuous_insertion_buffer.
88
92
  # After pasting, this buffer should be force inserted.
@@ -136,9 +140,9 @@ class Reline::LineEditor
136
140
  end
137
141
  end
138
142
 
139
- def reset(prompt = '', encoding:)
143
+ def reset(prompt = '')
140
144
  @screen_size = Reline::IOGate.get_screen_size
141
- reset_variables(prompt, encoding: encoding)
145
+ reset_variables(prompt)
142
146
  @rendered_screen.base_y = Reline::IOGate.cursor_pos.y
143
147
  if ENV.key?('RELINE_ALT_SCROLLBAR')
144
148
  @full_block = '::'
@@ -150,7 +154,7 @@ class Reline::LineEditor
150
154
  @upper_half_block = '▀'
151
155
  @lower_half_block = '▄'
152
156
  @block_elem_width = 1
153
- elsif @encoding == Encoding::UTF_8
157
+ elsif encoding == Encoding::UTF_8
154
158
  @full_block = '█'
155
159
  @upper_half_block = '▀'
156
160
  @lower_half_block = '▄'
@@ -176,9 +180,8 @@ class Reline::LineEditor
176
180
  scroll_into_view
177
181
  Reline::IOGate.move_cursor_up @rendered_screen.cursor_y
178
182
  @rendered_screen.base_y = Reline::IOGate.cursor_pos.y
179
- @rendered_screen.lines = []
180
- @rendered_screen.cursor_y = 0
181
- render_differential
183
+ clear_rendered_screen_cache
184
+ render
182
185
  end
183
186
 
184
187
  private def handle_interrupted
@@ -186,11 +189,11 @@ class Reline::LineEditor
186
189
 
187
190
  @interrupted = false
188
191
  clear_dialogs
189
- scrolldown = render_differential
190
- Reline::IOGate.scroll_down scrolldown
192
+ render
193
+ cursor_to_bottom_offset = @rendered_screen.lines.size - @rendered_screen.cursor_y
194
+ Reline::IOGate.scroll_down cursor_to_bottom_offset
191
195
  Reline::IOGate.move_cursor_column 0
192
- @rendered_screen.lines = []
193
- @rendered_screen.cursor_y = 0
196
+ clear_rendered_screen_cache
194
197
  case @old_trap
195
198
  when 'DEFAULT', 'SYSTEM_DEFAULT'
196
199
  raise Interrupt
@@ -220,10 +223,9 @@ class Reline::LineEditor
220
223
  @eof
221
224
  end
222
225
 
223
- def reset_variables(prompt = '', encoding:)
226
+ def reset_variables(prompt = '')
224
227
  @prompt = prompt.gsub("\n", "\\n")
225
228
  @mark_pointer = nil
226
- @encoding = encoding
227
229
  @is_multiline = false
228
230
  @finished = false
229
231
  @history_pointer = nil
@@ -240,7 +242,7 @@ class Reline::LineEditor
240
242
  @searching_prompt = nil
241
243
  @just_cursor_moving = false
242
244
  @eof = false
243
- @continuous_insertion_buffer = String.new(encoding: @encoding)
245
+ @continuous_insertion_buffer = String.new(encoding: encoding)
244
246
  @scroll_partial_screen = 0
245
247
  @drop_terminate_spaces = false
246
248
  @in_pasting = false
@@ -260,7 +262,7 @@ class Reline::LineEditor
260
262
 
261
263
  def reset_line
262
264
  @byte_pointer = 0
263
- @buffer_of_lines = [String.new(encoding: @encoding)]
265
+ @buffer_of_lines = [String.new(encoding: encoding)]
264
266
  @line_index = 0
265
267
  @cache.clear
266
268
  @line_backup_in_history = nil
@@ -276,7 +278,7 @@ class Reline::LineEditor
276
278
  end
277
279
 
278
280
  private def insert_new_line(cursor_line, next_line)
279
- @buffer_of_lines.insert(@line_index + 1, String.new(next_line, encoding: @encoding))
281
+ @buffer_of_lines.insert(@line_index + 1, String.new(next_line, encoding: encoding))
280
282
  @buffer_of_lines[@line_index] = cursor_line
281
283
  @line_index += 1
282
284
  @byte_pointer = 0
@@ -299,7 +301,7 @@ class Reline::LineEditor
299
301
  end
300
302
 
301
303
  private def split_by_width(str, max_width, offset: 0)
302
- Reline::Unicode.split_by_width(str, max_width, @encoding, offset: offset)
304
+ Reline::Unicode.split_by_width(str, max_width, encoding, offset: offset)
303
305
  end
304
306
 
305
307
  def current_byte_pointer_cursor
@@ -460,49 +462,25 @@ class Reline::LineEditor
460
462
  end
461
463
 
462
464
  def render_finished
463
- clear_rendered_lines
464
- render_full_content
465
- end
466
-
467
- def clear_rendered_lines
468
- Reline::IOGate.move_cursor_up @rendered_screen.cursor_y
469
- Reline::IOGate.move_cursor_column 0
470
-
471
- num_lines = @rendered_screen.lines.size
472
- return unless num_lines && num_lines >= 1
473
-
474
- Reline::IOGate.move_cursor_down num_lines - 1
475
- (num_lines - 1).times do
476
- Reline::IOGate.erase_after_cursor
477
- Reline::IOGate.move_cursor_up 1
478
- end
479
- Reline::IOGate.erase_after_cursor
480
- @rendered_screen.lines = []
481
- @rendered_screen.cursor_y = 0
482
- end
483
-
484
- def render_full_content
465
+ render_differential([], 0, 0)
485
466
  lines = @buffer_of_lines.size.times.map do |i|
486
- line = prompt_list[i] + modified_lines[i]
467
+ line = Reline::Unicode.strip_non_printing_start_end(prompt_list[i]) + modified_lines[i]
487
468
  wrapped_lines, = split_by_width(line, screen_width)
488
469
  wrapped_lines.last.empty? ? "#{line} " : line
489
470
  end
490
471
  @output.puts lines.map { |l| "#{l}\r\n" }.join
491
472
  end
492
473
 
493
- def print_nomultiline_prompt(prompt)
494
- return unless prompt && !@is_multiline
495
-
474
+ def print_nomultiline_prompt
475
+ Reline::IOGate.disable_auto_linewrap(true) if Reline::IOGate.win?
496
476
  # Readline's test `TestRelineAsReadline#test_readline` requires first output to be prompt, not cursor reset escape sequence.
497
- @rendered_screen.lines = [[[0, Reline::Unicode.calculate_width(prompt, true), prompt]]]
498
- @rendered_screen.cursor_y = 0
499
- @output.write prompt
477
+ @output.write Reline::Unicode.strip_non_printing_start_end(@prompt) if @prompt && !@is_multiline
478
+ ensure
479
+ Reline::IOGate.disable_auto_linewrap(false) if Reline::IOGate.win?
500
480
  end
501
481
 
502
- def render_differential
482
+ def render
503
483
  wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
504
-
505
- rendered_lines = @rendered_screen.lines
506
484
  new_lines = wrapped_prompt_and_input_lines.flatten(1)[screen_scroll_top, screen_height].map do |prompt, line|
507
485
  prompt_width = Reline::Unicode.calculate_width(prompt, true)
508
486
  [[0, prompt_width, prompt], [prompt_width, Reline::Unicode.calculate_width(line, true), line]]
@@ -520,12 +498,22 @@ class Reline::LineEditor
520
498
  x_range, y_range = dialog_range dialog, wrapped_cursor_y - screen_scroll_top
521
499
  y_range.each do |row|
522
500
  next if row < 0 || row >= screen_height
501
+
523
502
  dialog_rows = new_lines[row] ||= []
524
503
  # index 0 is for prompt, index 1 is for line, index 2.. is for dialog
525
504
  dialog_rows[index + 2] = [x_range.begin, dialog.width, dialog.contents[row - y_range.begin]]
526
505
  end
527
506
  end
528
507
 
508
+ render_differential new_lines, wrapped_cursor_x, wrapped_cursor_y - screen_scroll_top
509
+ end
510
+
511
+ # Reflects lines to be rendered and new cursor position to the screen
512
+ # by calculating the difference from the previous render.
513
+
514
+ private def render_differential(new_lines, new_cursor_x, new_cursor_y)
515
+ Reline::IOGate.disable_auto_linewrap(true) if Reline::IOGate.win?
516
+ rendered_lines = @rendered_screen.lines
529
517
  cursor_y = @rendered_screen.cursor_y
530
518
  if new_lines != rendered_lines
531
519
  # Hide cursor while rendering to avoid cursor flickering.
@@ -552,11 +540,16 @@ class Reline::LineEditor
552
540
  @rendered_screen.lines = new_lines
553
541
  Reline::IOGate.show_cursor
554
542
  end
555
- y = wrapped_cursor_y - screen_scroll_top
556
- Reline::IOGate.move_cursor_column wrapped_cursor_x
557
- Reline::IOGate.move_cursor_down y - cursor_y
558
- @rendered_screen.cursor_y = y
559
- new_lines.size - y
543
+ Reline::IOGate.move_cursor_column new_cursor_x
544
+ Reline::IOGate.move_cursor_down new_cursor_y - cursor_y
545
+ @rendered_screen.cursor_y = new_cursor_y
546
+ ensure
547
+ Reline::IOGate.disable_auto_linewrap(false) if Reline::IOGate.win?
548
+ end
549
+
550
+ private def clear_rendered_screen_cache
551
+ @rendered_screen.lines = []
552
+ @rendered_screen.cursor_y = 0
560
553
  end
561
554
 
562
555
  def upper_space_height(wrapped_cursor_y)
@@ -568,7 +561,7 @@ class Reline::LineEditor
568
561
  end
569
562
 
570
563
  def rerender
571
- render_differential unless @in_pasting
564
+ render unless @in_pasting
572
565
  end
573
566
 
574
567
  class DialogProcScope
@@ -813,7 +806,7 @@ class Reline::LineEditor
813
806
 
814
807
  private def complete_internal_proc(list, is_menu)
815
808
  preposing, target, postposing = retrieve_completion_block
816
- list = list.select { |i|
809
+ candidates = list.select { |i|
817
810
  if i and not Encoding.compatible?(target.encoding, i.encoding)
818
811
  raise Encoding::CompatibilityError, "#{target.encoding.name} is not compatible with #{i.encoding.name}"
819
812
  end
@@ -824,10 +817,10 @@ class Reline::LineEditor
824
817
  end
825
818
  }.uniq
826
819
  if is_menu
827
- menu(target, list)
820
+ menu(target, candidates)
828
821
  return nil
829
822
  end
830
- completed = list.inject { |memo, item|
823
+ completed = candidates.inject { |memo, item|
831
824
  begin
832
825
  memo_mbchars = memo.unicode_normalize.grapheme_clusters
833
826
  item_mbchars = item.unicode_normalize.grapheme_clusters
@@ -854,7 +847,8 @@ class Reline::LineEditor
854
847
  end
855
848
  result
856
849
  }
857
- [target, preposing, completed, postposing]
850
+
851
+ [target, preposing, completed, postposing, candidates]
858
852
  end
859
853
 
860
854
  private def perform_completion(list, just_show_list)
@@ -862,7 +856,11 @@ class Reline::LineEditor
862
856
  when CompletionState::NORMAL
863
857
  @completion_state = CompletionState::COMPLETION
864
858
  when CompletionState::PERFECT_MATCH
865
- @dig_perfect_match_proc&.(@perfect_matched)
859
+ if @dig_perfect_match_proc
860
+ @dig_perfect_match_proc.(@perfect_matched)
861
+ else
862
+ @completion_state = CompletionState::COMPLETION
863
+ end
866
864
  end
867
865
  if just_show_list
868
866
  is_menu = true
@@ -878,24 +876,26 @@ class Reline::LineEditor
878
876
  @completion_state = CompletionState::PERFECT_MATCH
879
877
  end
880
878
  return if result.nil?
881
- target, preposing, completed, postposing = result
879
+ target, preposing, completed, postposing, candidates = result
882
880
  return if completed.nil?
883
881
  if target <= completed and (@completion_state == CompletionState::COMPLETION)
884
- if list.include?(completed)
885
- if list.one?
882
+ append_character = ''
883
+ if candidates.include?(completed)
884
+ if candidates.one?
885
+ append_character = completion_append_character.to_s
886
886
  @completion_state = CompletionState::PERFECT_MATCH
887
887
  else
888
888
  @completion_state = CompletionState::MENU_WITH_PERFECT_MATCH
889
- perform_completion(list, true) if @config.show_all_if_ambiguous
889
+ perform_completion(candidates, true) if @config.show_all_if_ambiguous
890
890
  end
891
891
  @perfect_matched = completed
892
892
  else
893
893
  @completion_state = CompletionState::MENU
894
- perform_completion(list, true) if @config.show_all_if_ambiguous
894
+ perform_completion(candidates, true) if @config.show_all_if_ambiguous
895
895
  end
896
- if not just_show_list and target < completed
897
- @buffer_of_lines[@line_index] = (preposing + completed + completion_append_character.to_s + postposing).split("\n")[@line_index] || String.new(encoding: @encoding)
898
- line_to_pointer = (preposing + completed + completion_append_character.to_s).split("\n")[@line_index] || String.new(encoding: @encoding)
896
+ unless just_show_list
897
+ @buffer_of_lines[@line_index] = (preposing + completed + append_character + postposing).split("\n")[@line_index] || String.new(encoding: encoding)
898
+ line_to_pointer = (preposing + completed + append_character).split("\n")[@line_index] || String.new(encoding: encoding)
899
899
  @byte_pointer = line_to_pointer.bytesize
900
900
  end
901
901
  end
@@ -1070,8 +1070,8 @@ class Reline::LineEditor
1070
1070
  private def normal_char(key)
1071
1071
  @multibyte_buffer << key.combined_char
1072
1072
  if @multibyte_buffer.size > 1
1073
- if @multibyte_buffer.dup.force_encoding(@encoding).valid_encoding?
1074
- process_key(@multibyte_buffer.dup.force_encoding(@encoding), nil)
1073
+ if @multibyte_buffer.dup.force_encoding(encoding).valid_encoding?
1074
+ process_key(@multibyte_buffer.dup.force_encoding(encoding), nil)
1075
1075
  @multibyte_buffer.clear
1076
1076
  else
1077
1077
  # invalid
@@ -1329,7 +1329,7 @@ class Reline::LineEditor
1329
1329
  if (lines.size - 1) > @line_index
1330
1330
  postposing = postposing + "\n" + lines[(@line_index + 1)..-1].join("\n")
1331
1331
  end
1332
- [preposing.encode(@encoding), target.encode(@encoding), postposing.encode(@encoding)]
1332
+ [preposing.encode(encoding), target.encode(encoding), postposing.encode(encoding)]
1333
1333
  end
1334
1334
 
1335
1335
  def confirm_multiline_termination
@@ -1337,11 +1337,11 @@ class Reline::LineEditor
1337
1337
  @confirm_multiline_termination_proc.(temp_buffer.join("\n") + "\n")
1338
1338
  end
1339
1339
 
1340
- def insert_pasted_text(text)
1340
+ def insert_multiline_text(text)
1341
1341
  save_old_buffer
1342
1342
  pre = @buffer_of_lines[@line_index].byteslice(0, @byte_pointer)
1343
1343
  post = @buffer_of_lines[@line_index].byteslice(@byte_pointer..)
1344
- lines = (pre + text.gsub(/\r\n?/, "\n") + post).split("\n", -1)
1344
+ lines = (pre + Reline::Unicode.safe_encode(text, encoding).gsub(/\r\n?/, "\n") + post).split("\n", -1)
1345
1345
  lines << '' if lines.empty?
1346
1346
  @buffer_of_lines[@line_index, 1] = lines
1347
1347
  @line_index += lines.size - 1
@@ -1386,7 +1386,7 @@ class Reline::LineEditor
1386
1386
  last += current_line.bytesize if last < 0
1387
1387
  first += current_line.bytesize if first < 0
1388
1388
  range = range.exclude_end? ? first...last : first..last
1389
- line = current_line.bytes.reject.with_index{ |c, i| range.include?(i) }.map{ |c| c.chr(Encoding::ASCII_8BIT) }.join.force_encoding(@encoding)
1389
+ line = current_line.bytes.reject.with_index{ |c, i| range.include?(i) }.map{ |c| c.chr(Encoding::ASCII_8BIT) }.join.force_encoding(encoding)
1390
1390
  set_current_line(line)
1391
1391
  else
1392
1392
  set_current_line(current_line.byteslice(0, start))
@@ -1597,7 +1597,7 @@ class Reline::LineEditor
1597
1597
  alias_method :end_of_line, :ed_move_to_end
1598
1598
 
1599
1599
  private def generate_searcher(search_key)
1600
- search_word = String.new(encoding: @encoding)
1600
+ search_word = String.new(encoding: encoding)
1601
1601
  multibyte_buf = String.new(encoding: 'ASCII-8BIT')
1602
1602
  hit_pointer = nil
1603
1603
  lambda do |key|
@@ -1614,8 +1614,8 @@ class Reline::LineEditor
1614
1614
  search_key = key
1615
1615
  else
1616
1616
  multibyte_buf << key
1617
- if multibyte_buf.dup.force_encoding(@encoding).valid_encoding?
1618
- search_word << multibyte_buf.dup.force_encoding(@encoding)
1617
+ if multibyte_buf.dup.force_encoding(encoding).valid_encoding?
1618
+ search_word << multibyte_buf.dup.force_encoding(encoding)
1619
1619
  multibyte_buf.clear
1620
1620
  end
1621
1621
  end
@@ -1681,57 +1681,29 @@ class Reline::LineEditor
1681
1681
  end
1682
1682
 
1683
1683
  private def incremental_search_history(key)
1684
- unless @history_pointer
1685
- @line_backup_in_history = whole_buffer
1686
- end
1684
+ backup = @buffer_of_lines.dup, @line_index, @byte_pointer, @history_pointer, @line_backup_in_history
1687
1685
  searcher = generate_searcher(key)
1688
1686
  @searching_prompt = "(reverse-i-search)`': "
1689
1687
  termination_keys = ["\C-j".ord]
1690
- termination_keys.concat(@config.isearch_terminators&.chars&.map(&:ord)) if @config.isearch_terminators
1688
+ termination_keys.concat(@config.isearch_terminators.chars.map(&:ord)) if @config.isearch_terminators
1691
1689
  @waiting_proc = ->(k) {
1692
- case k
1693
- when *termination_keys
1694
- if @history_pointer
1695
- buffer = Reline::HISTORY[@history_pointer]
1696
- else
1697
- buffer = @line_backup_in_history
1698
- end
1699
- @buffer_of_lines = buffer.split("\n")
1700
- @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
1701
- @line_index = @buffer_of_lines.size - 1
1690
+ chr = k.is_a?(String) ? k : k.chr(Encoding::ASCII_8BIT)
1691
+ if k == "\C-g".ord
1692
+ # cancel search and restore buffer
1693
+ @buffer_of_lines, @line_index, @byte_pointer, @history_pointer, @line_backup_in_history = backup
1702
1694
  @searching_prompt = nil
1703
1695
  @waiting_proc = nil
1704
- @byte_pointer = 0
1705
- when "\C-g".ord
1706
- @buffer_of_lines = @line_backup_in_history.split("\n")
1707
- @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
1708
- @line_index = @buffer_of_lines.size - 1
1709
- move_history(nil, line: :end, cursor: :end, save_buffer: false)
1696
+ elsif !termination_keys.include?(k) && (chr.match?(/[[:print:]]/) || k == "\C-h".ord || k == "\C-?".ord || k == "\C-r".ord || k == "\C-s".ord)
1697
+ search_word, prompt_name, hit_pointer = searcher.call(k)
1698
+ Reline.last_incremental_search = search_word
1699
+ @searching_prompt = "(%s)`%s'" % [prompt_name, search_word]
1700
+ @searching_prompt += ': ' unless @is_multiline
1701
+ move_history(hit_pointer, line: :end, cursor: :end) if hit_pointer
1702
+ else
1703
+ # terminaton_keys and other keys will terminalte
1704
+ move_history(@history_pointer, line: :end, cursor: :start)
1710
1705
  @searching_prompt = nil
1711
1706
  @waiting_proc = nil
1712
- @byte_pointer = 0
1713
- else
1714
- chr = k.is_a?(String) ? k : k.chr(Encoding::ASCII_8BIT)
1715
- if chr.match?(/[[:print:]]/) or k == "\C-h".ord or k == "\C-?".ord or k == "\C-r".ord or k == "\C-s".ord
1716
- search_word, prompt_name, hit_pointer = searcher.call(k)
1717
- Reline.last_incremental_search = search_word
1718
- @searching_prompt = "(%s)`%s'" % [prompt_name, search_word]
1719
- @searching_prompt += ': ' unless @is_multiline
1720
- move_history(hit_pointer, line: :end, cursor: :end, save_buffer: false) if hit_pointer
1721
- else
1722
- if @history_pointer
1723
- line = Reline::HISTORY[@history_pointer]
1724
- else
1725
- line = @line_backup_in_history
1726
- end
1727
- @line_backup_in_history = whole_buffer
1728
- @buffer_of_lines = line.split("\n")
1729
- @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
1730
- @line_index = @buffer_of_lines.size - 1
1731
- @searching_prompt = nil
1732
- @waiting_proc = nil
1733
- @byte_pointer = 0
1734
- end
1735
1707
  end
1736
1708
  }
1737
1709
  end
@@ -1786,14 +1758,14 @@ class Reline::LineEditor
1786
1758
  end
1787
1759
  alias_method :history_search_forward, :ed_search_next_history
1788
1760
 
1789
- private def move_history(history_pointer, line:, cursor:, save_buffer: true)
1761
+ private def move_history(history_pointer, line:, cursor:)
1790
1762
  history_pointer ||= Reline::HISTORY.size
1791
1763
  return if history_pointer < 0 || history_pointer > Reline::HISTORY.size
1792
1764
  old_history_pointer = @history_pointer || Reline::HISTORY.size
1793
1765
  if old_history_pointer == Reline::HISTORY.size
1794
- @line_backup_in_history = save_buffer ? whole_buffer : ''
1766
+ @line_backup_in_history = whole_buffer
1795
1767
  else
1796
- Reline::HISTORY[old_history_pointer] = whole_buffer if save_buffer
1768
+ Reline::HISTORY[old_history_pointer] = whole_buffer
1797
1769
  end
1798
1770
  if history_pointer == Reline::HISTORY.size
1799
1771
  buf = @line_backup_in_history
@@ -1803,7 +1775,7 @@ class Reline::LineEditor
1803
1775
  @history_pointer = history_pointer
1804
1776
  end
1805
1777
  @buffer_of_lines = buf.split("\n")
1806
- @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
1778
+ @buffer_of_lines = [String.new(encoding: encoding)] if @buffer_of_lines.empty?
1807
1779
  @line_index = line == :start ? 0 : line == :end ? @buffer_of_lines.size - 1 : line
1808
1780
  @byte_pointer = cursor == :start ? 0 : cursor == :end ? current_line.bytesize : cursor
1809
1781
  end
@@ -1982,9 +1954,8 @@ class Reline::LineEditor
1982
1954
  private def ed_clear_screen(key)
1983
1955
  Reline::IOGate.clear_screen
1984
1956
  @screen_size = Reline::IOGate.get_screen_size
1985
- @rendered_screen.lines = []
1986
1957
  @rendered_screen.base_y = 0
1987
- @rendered_screen.cursor_y = 0
1958
+ clear_rendered_screen_cache
1988
1959
  end
1989
1960
  alias_method :clear_screen, :ed_clear_screen
1990
1961
 
@@ -2259,9 +2230,11 @@ class Reline::LineEditor
2259
2230
  line, cut = byteslice!(current_line, @byte_pointer, byte_pointer_diff)
2260
2231
  elsif byte_pointer_diff < 0
2261
2232
  line, cut = byteslice!(current_line, @byte_pointer + byte_pointer_diff, -byte_pointer_diff)
2233
+ else
2234
+ return
2262
2235
  end
2263
2236
  copy_for_vi(cut)
2264
- set_current_line(line || '', @byte_pointer + (byte_pointer_diff < 0 ? byte_pointer_diff : 0))
2237
+ set_current_line(line, @byte_pointer + (byte_pointer_diff < 0 ? byte_pointer_diff : 0))
2265
2238
  end
2266
2239
 
2267
2240
  private def vi_yank(key, arg: nil)
@@ -2280,6 +2253,8 @@ class Reline::LineEditor
2280
2253
  cut = current_line.byteslice(@byte_pointer, byte_pointer_diff)
2281
2254
  elsif byte_pointer_diff < 0
2282
2255
  cut = current_line.byteslice(@byte_pointer + byte_pointer_diff, -byte_pointer_diff)
2256
+ else
2257
+ return
2283
2258
  end
2284
2259
  copy_for_vi(cut)
2285
2260
  end
@@ -2325,7 +2300,7 @@ class Reline::LineEditor
2325
2300
  }
2326
2301
  system("#{ENV['EDITOR']} #{path}")
2327
2302
  @buffer_of_lines = File.read(path).split("\n")
2328
- @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
2303
+ @buffer_of_lines = [String.new(encoding: encoding)] if @buffer_of_lines.empty?
2329
2304
  @line_index = 0
2330
2305
  finish
2331
2306
  end
@@ -2409,9 +2384,9 @@ class Reline::LineEditor
2409
2384
 
2410
2385
  private def search_next_char(key, arg, need_prev_char: false, inclusive: false)
2411
2386
  if key.instance_of?(String)
2412
- inputed_char = key
2387
+ inputted_char = key
2413
2388
  else
2414
- inputed_char = key.chr
2389
+ inputted_char = key.chr
2415
2390
  end
2416
2391
  prev_total = nil
2417
2392
  total = nil
@@ -2423,7 +2398,7 @@ class Reline::LineEditor
2423
2398
  width = Reline::Unicode.get_mbchar_width(mbchar)
2424
2399
  total = [mbchar.bytesize, width]
2425
2400
  else
2426
- if inputed_char == mbchar
2401
+ if inputted_char == mbchar
2427
2402
  arg -= 1
2428
2403
  if arg.zero?
2429
2404
  found = true
@@ -2461,9 +2436,9 @@ class Reline::LineEditor
2461
2436
 
2462
2437
  private def search_prev_char(key, arg, need_next_char = false)
2463
2438
  if key.instance_of?(String)
2464
- inputed_char = key
2439
+ inputted_char = key
2465
2440
  else
2466
- inputed_char = key.chr
2441
+ inputted_char = key.chr
2467
2442
  end
2468
2443
  prev_total = nil
2469
2444
  total = nil
@@ -2475,7 +2450,7 @@ class Reline::LineEditor
2475
2450
  width = Reline::Unicode.get_mbchar_width(mbchar)
2476
2451
  total = [mbchar.bytesize, width]
2477
2452
  else
2478
- if inputed_char == mbchar
2453
+ if inputted_char == mbchar
2479
2454
  arg -= 1
2480
2455
  if arg.zero?
2481
2456
  found = true
@@ -2554,4 +2529,8 @@ class Reline::LineEditor
2554
2529
  private def set_next_action_state(type, value)
2555
2530
  @next_action_state = [type, value]
2556
2531
  end
2532
+
2533
+ private def re_read_init_file(_key)
2534
+ @config.reload
2535
+ end
2557
2536
  end
@@ -83,7 +83,7 @@ module Reline::Terminfo
83
83
  end
84
84
 
85
85
  def self.setupterm(term, fildes)
86
- errret_int = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT)
86
+ errret_int = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT, Fiddle::RUBY_FREE)
87
87
  ret = @setupterm.(term, fildes, errret_int)
88
88
  case ret
89
89
  when 0 # OK