From 9183cc2e8b41f40398d64c51e1a27a3fad06744c Mon Sep 17 00:00:00 2001 From: aycabta Date: Tue, 28 Sep 2021 19:21:31 +0900 Subject: [PATCH] Support ed_argument_digit by M+num The vi mode can handle "argument number" before an operator or a motion, such as, "3x" (equals "xxx"), and "3l" (equals "lll"). In the emacs mode, GNU Readline can handle argument number with meta key, like "Meta+3 x" (equals "xxx"). --- lib/reline/line_editor.rb | 13 +++++++++++-- test/reline/test_key_actor_emacs.rb | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb index 5d349ecfb4..c64c2b5a46 100644 --- a/lib/reline/line_editor.rb +++ b/lib/reline/line_editor.rb @@ -2494,7 +2494,7 @@ def finish end end - private def em_delete_prev_char(key) + private def em_delete_prev_char(key, arg: 1) if @is_multiline and @cursor == 0 and @line_index > 0 @buffer_of_lines[@line_index] = @line @cursor = calculate_width(@buffer_of_lines[@line_index - 1]) @@ -2512,6 +2512,8 @@ def finish @cursor -= width @cursor_max -= width end + arg -= 1 + em_delete_prev_char(key, arg: arg) if arg > 0 end alias_method :backward_delete_char, :em_delete_prev_char @@ -3072,7 +3074,14 @@ def finish private def ed_argument_digit(key) if @vi_arg.nil? - unless key.chr.to_i.zero? + if key.chr.to_i.zero? + if key.anybits?(0b10000000) + unescaped_key = key ^ 0b10000000 + unless unescaped_key.chr.to_i.zero? + @vi_arg = unescaped_key.chr.to_i + end + end + else @vi_arg = key.chr.to_i end else diff --git a/test/reline/test_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb index a0466cb71f..5ace062cc2 100644 --- a/test/reline/test_key_actor_emacs.rb +++ b/test/reline/test_key_actor_emacs.rb @@ -2292,6 +2292,20 @@ def test_ignore_NUL_by_ed_quoted_insert assert_cursor_max(2) end + def test_ed_argument_digit_by_meta_num + input_keys('abcdef') + assert_byte_pointer_size('abcdef') + assert_cursor(6) + assert_cursor_max(6) + assert_line('abcdef') + input_keys("\M-2", false) + input_keys("\C-h", false) + assert_byte_pointer_size('abcd') + assert_cursor(4) + assert_cursor_max(4) + assert_line('abcd') + end + def test_input_unknown_char input_keys('͸') # U+0378 (unassigned) assert_line('͸')