Skip to content

Commit

Permalink
Fix waiting_operator bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
tompng committed Mar 19, 2024
1 parent 8194e61 commit 0aa9d27
Showing 1 changed file with 77 additions and 66 deletions.
143 changes: 77 additions & 66 deletions lib/reline/line_editor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,8 @@ def reset_variables(prompt = '', encoding:)
@vi_clipboard = ''
@vi_arg = nil
@waiting_proc = nil
@waiting_operator_proc = nil
@waiting_operator_vi_arg = nil
@vi_waiting_operator = nil
@vi_waiting_operator_arg = nil
@completion_journey_data = nil
@completion_state = CompletionState::NORMAL
@perfect_matched = nil
Expand Down Expand Up @@ -916,37 +916,23 @@ def editing_mode
end

private def run_for_operators(key, method_symbol, &block)
if @waiting_operator_proc
if @vi_waiting_operator
if VI_MOTIONS.include?(method_symbol)
old_byte_pointer = @byte_pointer
@vi_arg = @waiting_operator_vi_arg if @waiting_operator_vi_arg&.> 1
@vi_arg ||= @vi_waiting_operator_arg
block.(true)
unless @waiting_proc
byte_pointer_diff = @byte_pointer - old_byte_pointer
@byte_pointer = old_byte_pointer
@waiting_operator_proc.(byte_pointer_diff)
else
old_waiting_proc = @waiting_proc
old_waiting_operator_proc = @waiting_operator_proc
current_waiting_operator_proc = @waiting_operator_proc
@waiting_proc = proc { |k|
old_byte_pointer = @byte_pointer
old_waiting_proc.(k)
byte_pointer_diff = @byte_pointer - old_byte_pointer
@byte_pointer = old_byte_pointer
current_waiting_operator_proc.(byte_pointer_diff)
@waiting_operator_proc = old_waiting_operator_proc
}
send(@vi_waiting_operator, byte_pointer_diff)
cleanup_waiting
end
else
# Ignores operator when not motion is given.
block.(false)
cleanup_waiting
end
@waiting_operator_proc = nil
@waiting_operator_vi_arg = nil
if @vi_arg
@vi_arg = nil
end
@vi_arg = nil
else
block.(false)
end
Expand All @@ -963,7 +949,7 @@ def editing_mode
end

def wrap_method_call(method_symbol, method_obj, key, with_operator = false)
if @config.editing_mode_is?(:emacs, :vi_insert) and @waiting_proc.nil? and @waiting_operator_proc.nil?
if @config.editing_mode_is?(:emacs, :vi_insert) and @vi_waiting_operator.nil?
not_insertion = method_symbol != :ed_insert
process_insert(force: not_insertion)
end
Expand All @@ -982,16 +968,28 @@ def wrap_method_call(method_symbol, method_obj, key, with_operator = false)
end
end

private def cleanup_waiting
@waiting_proc = nil
@vi_waiting_operator = nil
@vi_waiting_operator_arg = nil
@searching_prompt = nil
@drop_terminate_spaces = false
end

private def process_key(key, method_symbol)
if @waiting_proc
if key.is_a?(Symbol)
@waiting_proc = nil
@searching_prompt = nil
else
@waiting_proc.call(key)
@kill_ring.process
return
if key.is_a?(Symbol)
cleanup_waiting
elsif @waiting_proc
old_byte_pointer = @byte_pointer
@waiting_proc.call(key)
if @vi_waiting_operator
byte_pointer_diff = @byte_pointer - old_byte_pointer
@byte_pointer = old_byte_pointer
send(@vi_waiting_operator, byte_pointer_diff)
cleanup_waiting
end
@kill_ring.process
return
end

if method_symbol and respond_to?(method_symbol, true)
Expand Down Expand Up @@ -2297,46 +2295,59 @@ def finish
@byte_pointer = 0
end

private def vi_change_meta(key, arg: 1)
@drop_terminate_spaces = true
@waiting_operator_proc = proc { |byte_pointer_diff|
if byte_pointer_diff > 0
line, cut = byteslice!(current_line, @byte_pointer, byte_pointer_diff)
elsif byte_pointer_diff < 0
line, cut = byteslice!(current_line, @byte_pointer + byte_pointer_diff, -byte_pointer_diff)
end
set_current_line(line)
copy_for_vi(cut)
@byte_pointer += byte_pointer_diff if byte_pointer_diff < 0
@config.editing_mode = :vi_insert
@drop_terminate_spaces = false
}
@waiting_operator_vi_arg = arg
private def vi_change_meta(key, arg: nil)
if @vi_waiting_operator
set_current_line('', 0) if @vi_waiting_operator == :vi_change_meta_confirm && arg.nil?
@vi_waiting_operator = nil
else
@drop_terminate_spaces = true
@vi_waiting_operator = :vi_change_meta_confirm
@vi_waiting_operator_arg = arg || 1
end
end

private def vi_delete_meta(key, arg: 1)
@waiting_operator_proc = proc { |byte_pointer_diff|
if byte_pointer_diff > 0
line, cut = byteslice!(current_line, @byte_pointer, byte_pointer_diff)
elsif byte_pointer_diff < 0
line, cut = byteslice!(current_line, @byte_pointer + byte_pointer_diff, -byte_pointer_diff)
end
copy_for_vi(cut)
set_current_line(line || '', @byte_pointer + (byte_pointer_diff < 0 ? byte_pointer_diff : 0))
}
@waiting_operator_vi_arg = arg
private def vi_change_meta_confirm(byte_pointer_diff)
vi_delete_meta_confirm(byte_pointer_diff)
@config.editing_mode = :vi_insert
@drop_terminate_spaces = false
end

private def vi_delete_meta(key, arg: nil)
if @vi_waiting_operator
set_current_line('', 0) if @vi_waiting_operator == :vi_delete_meta_confirm && arg.nil?
@vi_waiting_operator = nil
else
@vi_waiting_operator = :vi_delete_meta_confirm
@vi_waiting_operator_arg = arg || 1
end
end

private def vi_delete_meta_confirm(byte_pointer_diff)
if byte_pointer_diff > 0
line, cut = byteslice!(current_line, @byte_pointer, byte_pointer_diff)
elsif byte_pointer_diff < 0
line, cut = byteslice!(current_line, @byte_pointer + byte_pointer_diff, -byte_pointer_diff)
end
copy_for_vi(cut)
set_current_line(line || '', @byte_pointer + (byte_pointer_diff < 0 ? byte_pointer_diff : 0))
end

private def vi_yank(key, arg: 1)
@waiting_operator_proc = proc { |byte_pointer_diff|
if byte_pointer_diff > 0
cut = current_line.byteslice(@byte_pointer, byte_pointer_diff)
elsif byte_pointer_diff < 0
cut = current_line.byteslice(@byte_pointer + byte_pointer_diff, -byte_pointer_diff)
end
copy_for_vi(cut)
}
@waiting_operator_vi_arg = arg
if @vi_waiting_operator
@vi_waiting_operator = nil
else
@vi_waiting_operator = :vi_yank_confirm
@vi_waiting_operator_arg = arg
end
end

private def vi_yank_confirm(byte_pointer_diff)
if byte_pointer_diff > 0
cut = current_line.byteslice(@byte_pointer, byte_pointer_diff)
elsif byte_pointer_diff < 0
cut = current_line.byteslice(@byte_pointer + byte_pointer_diff, -byte_pointer_diff)
end
copy_for_vi(cut)
end

private def vi_list_or_eof(key)
Expand Down

0 comments on commit 0aa9d27

Please sign in to comment.