Skip to content

Commit 72c0ec0

Browse files
authored
Refactor handling key in LineEditor (#799)
Simplify the complicated flow of waiting_proc, wrap_method_call and run_for_operation
1 parent e6eb5d2 commit 72c0ec0

File tree

2 files changed

+57
-66
lines changed

2 files changed

+57
-66
lines changed

lib/reline/line_editor.rb

Lines changed: 47 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -911,28 +911,36 @@ def dialog_proc_scope_completion_journey_data
911911
)
912912
end
913913

914-
private def run_for_operators(key, method_symbol, &block)
914+
private def run_for_operators(key, method_symbol)
915+
# Reject multibyte input (converted to ed_insert) in vi_command mode
916+
return if method_symbol == :ed_insert && @config.editing_mode_is?(:vi_command) && !@waiting_proc
917+
918+
if ARGUMENT_DIGIT_METHODS.include?(method_symbol) && !@waiting_proc
919+
wrap_method_call(method_symbol, key, false)
920+
return
921+
end
922+
915923
if @vi_waiting_operator
916-
if VI_MOTIONS.include?(method_symbol)
924+
if @waiting_proc || VI_MOTIONS.include?(method_symbol)
917925
old_byte_pointer = @byte_pointer
918926
@vi_arg = (@vi_arg || 1) * @vi_waiting_operator_arg
919-
block.(true)
927+
wrap_method_call(method_symbol, key, true)
920928
unless @waiting_proc
921929
byte_pointer_diff = @byte_pointer - old_byte_pointer
922930
@byte_pointer = old_byte_pointer
923-
method_obj = method(@vi_waiting_operator)
924-
wrap_method_call(@vi_waiting_operator, method_obj, byte_pointer_diff)
931+
__send__(@vi_waiting_operator, byte_pointer_diff)
925932
cleanup_waiting
926933
end
927934
else
928935
# Ignores operator when not motion is given.
929-
block.(false)
936+
wrap_method_call(method_symbol, key, false)
930937
cleanup_waiting
931938
end
932-
@vi_arg = nil
933939
else
934-
block.(false)
940+
wrap_method_call(method_symbol, key, false)
935941
end
942+
@vi_arg = nil
943+
@kill_ring.process
936944
end
937945

938946
private def argumentable?(method_obj)
@@ -945,20 +953,23 @@ def dialog_proc_scope_completion_journey_data
945953
method_obj and method_obj.parameters.any? { |param| param[0] == :key and param[1] == :inclusive }
946954
end
947955

948-
def wrap_method_call(method_symbol, method_obj, key, with_operator = false)
949-
if @config.editing_mode_is?(:emacs, :vi_insert) and @vi_waiting_operator.nil?
950-
not_insertion = method_symbol != :ed_insert
951-
process_insert(force: not_insertion)
956+
def wrap_method_call(method_symbol, key, with_operator)
957+
if @waiting_proc
958+
@waiting_proc.call(key)
959+
return
952960
end
961+
962+
return unless respond_to?(method_symbol, true)
963+
method_obj = method(method_symbol)
953964
if @vi_arg and argumentable?(method_obj)
954-
if with_operator and inclusive?(method_obj)
955-
method_obj.(key, arg: @vi_arg, inclusive: true)
965+
if inclusive?(method_obj)
966+
method_obj.(key, arg: @vi_arg, inclusive: with_operator)
956967
else
957968
method_obj.(key, arg: @vi_arg)
958969
end
959970
else
960-
if with_operator and inclusive?(method_obj)
961-
method_obj.(key, inclusive: true)
971+
if inclusive?(method_obj)
972+
method_obj.(key, inclusive: with_operator)
962973
else
963974
method_obj.(key)
964975
end
@@ -984,50 +995,9 @@ def wrap_method_call(method_symbol, method_obj, key, with_operator = false)
984995
cleanup_waiting unless VI_WAITING_ACCEPT_METHODS.include?(method_symbol) || VI_MOTIONS.include?(method_symbol)
985996
end
986997

987-
if @waiting_proc
988-
old_byte_pointer = @byte_pointer
989-
@waiting_proc.call(key)
990-
if @vi_waiting_operator
991-
byte_pointer_diff = @byte_pointer - old_byte_pointer
992-
@byte_pointer = old_byte_pointer
993-
method_obj = method(@vi_waiting_operator)
994-
wrap_method_call(@vi_waiting_operator, method_obj, byte_pointer_diff)
995-
cleanup_waiting
996-
end
997-
@kill_ring.process
998-
return
999-
end
1000-
1001-
# Reject multibyte input (converted to ed_insert) in vi_command mode
1002-
return if method_symbol == :ed_insert && @config.editing_mode_is?(:vi_command)
998+
process_insert(force: method_symbol != :ed_insert)
1003999

1004-
if method_symbol and respond_to?(method_symbol, true)
1005-
method_obj = method(method_symbol)
1006-
end
1007-
if @vi_arg
1008-
if ARGUMENT_DIGIT_METHODS.include?(method_symbol)
1009-
ed_argument_digit(key)
1010-
else
1011-
if argumentable?(method_obj)
1012-
run_for_operators(key, method_symbol) do |with_operator|
1013-
wrap_method_call(method_symbol, method_obj, key, with_operator)
1014-
end
1015-
elsif method_obj
1016-
wrap_method_call(method_symbol, method_obj, key)
1017-
end
1018-
@kill_ring.process
1019-
@vi_arg = nil
1020-
end
1021-
elsif method_obj
1022-
if method_symbol == :ed_argument_digit
1023-
wrap_method_call(method_symbol, method_obj, key)
1024-
else
1025-
run_for_operators(key, method_symbol) do |with_operator|
1026-
wrap_method_call(method_symbol, method_obj, key, with_operator)
1027-
end
1028-
end
1029-
@kill_ring.process
1030-
end
1000+
run_for_operators(key, method_symbol)
10311001
end
10321002

10331003
def update(key)
@@ -1049,11 +1019,8 @@ def input_key(key)
10491019
finish
10501020
return
10511021
end
1052-
@dialogs.each do |dialog|
1053-
if key.method_symbol == dialog.name
1054-
return
1055-
end
1056-
end
1022+
return if @dialogs.any? { |dialog| dialog.name == key.method_symbol }
1023+
10571024
@completion_occurs = false
10581025

10591026
process_key(key.char, key.method_symbol)
@@ -1413,9 +1380,16 @@ def finish
14131380

14141381
insert_text(str)
14151382
end
1416-
alias_method :ed_digit, :ed_insert
14171383
alias_method :self_insert, :ed_insert
14181384

1385+
private def ed_digit(key)
1386+
if @vi_arg
1387+
ed_argument_digit(key)
1388+
else
1389+
ed_insert(key)
1390+
end
1391+
end
1392+
14191393
private def insert_raw_char(str, arg: 1)
14201394
arg.times do
14211395
if str == "\C-j" or str == "\C-m"
@@ -1461,7 +1435,14 @@ def finish
14611435
@byte_pointer = 0
14621436
end
14631437
alias_method :beginning_of_line, :ed_move_to_beg
1464-
alias_method :vi_zero, :ed_move_to_beg
1438+
1439+
private def vi_zero(key)
1440+
if @vi_arg
1441+
ed_argument_digit(key)
1442+
else
1443+
ed_move_to_beg(key)
1444+
end
1445+
end
14651446

14661447
private def ed_move_to_end(key)
14671448
@byte_pointer = current_line.bytesize

test/reline/test_key_actor_emacs.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,6 +1502,16 @@ def test_ed_argument_digit_by_meta_num
15021502
assert_line_around_cursor('abcd', '')
15031503
end
15041504

1505+
def test_ed_digit_with_ed_argument_digit
1506+
input_keys('1' * 30)
1507+
assert_line_around_cursor('1' * 30, '')
1508+
input_keys("\M-2", false)
1509+
input_keys('3')
1510+
input_keys("\C-h", false)
1511+
input_keys('4')
1512+
assert_line_around_cursor('1' * 7 + '4', '')
1513+
end
1514+
15051515
def test_halfwidth_kana_width_dakuten
15061516
omit "This test is for UTF-8 but the locale is #{Reline.core.encoding}" if Reline.core.encoding != Encoding::UTF_8
15071517
input_raw_keys('ガギゲゴ')

0 commit comments

Comments
 (0)