From 42e2a322f100c7c798fcfbcbbfe0b4cdaf3f5855 Mon Sep 17 00:00:00 2001 From: aycabta Date: Tue, 24 Dec 2019 18:32:50 +0900 Subject: The delete-char-or-list shows completed list when called at end of line It doesn't behave the same as the delete-char. --- lib/reline/key_actor/emacs.rb | 2 +- lib/reline/line_editor.rb | 31 +++++++++++++++++++++----- test/reline/test_key_actor_emacs.rb | 43 ++++++++++++++++++++++++++++++++++--- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/lib/reline/key_actor/emacs.rb b/lib/reline/key_actor/emacs.rb index ab5c214600..3886d17f22 100644 --- a/lib/reline/key_actor/emacs.rb +++ b/lib/reline/key_actor/emacs.rb @@ -9,7 +9,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base # 3 ^C :ed_ignore, # 4 ^D - :em_delete_or_list, + :em_delete, # 5 ^E :ed_move_to_end, # 6 ^F diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb index 0ddafb420b..010ceb981c 100644 --- a/lib/reline/line_editor.rb +++ b/lib/reline/line_editor.rb @@ -595,14 +595,22 @@ class Reline::LineEditor [target, preposing, completed, postposing] end - private def complete(list) + private def complete(list, just_show_list = false) case @completion_state when CompletionState::NORMAL, CompletionState::JOURNEY @completion_state = CompletionState::COMPLETION when CompletionState::PERFECT_MATCH @dig_perfect_match_proc&.(@perfect_matched) end - is_menu = (@completion_state == CompletionState::MENU or @completion_state == CompletionState::MENU_WITH_PERFECT_MATCH) + if just_show_list + is_menu = true + elsif @completion_state == CompletionState::MENU + is_menu = true + elsif @completion_state == CompletionState::MENU_WITH_PERFECT_MATCH + is_menu = true + else + is_menu = false + end result = complete_internal_proc(list, is_menu) if @completion_state == CompletionState::MENU_WITH_PERFECT_MATCH @completion_state = CompletionState::PERFECT_MATCH @@ -621,7 +629,7 @@ class Reline::LineEditor else @completion_state = CompletionState::MENU end - if target < completed + if not just_show_list and target < completed @line = preposing + completed + completion_append_character.to_s + postposing line_to_pointer = preposing + completed + completion_append_character.to_s @cursor_max = calculate_width(@line) @@ -1567,7 +1575,7 @@ class Reline::LineEditor end end - private def em_delete_or_list(key) + private def em_delete(key) if (not @is_multiline and @line.empty?) or (@is_multiline and @line.empty? and @buffer_of_lines.size == 1) @line = nil if @buffer_of_lines.size > 1 @@ -1592,7 +1600,20 @@ class Reline::LineEditor @rest_height += 1 end end - alias_method :delete_char, :em_delete_or_list + alias_method :delete_char, :em_delete + + private def em_delete_or_list(key) + if @line.empty? or @byte_pointer < @line.bytesize + em_delete(key) + else # show completed list + result = call_completion_proc + if result.is_a?(Array) + completion_occurs = true + complete(result, true) + end + end + end + alias_method :delete_char_or_list, :em_delete_or_list private def em_yank(key) yanked = @kill_ring.yank diff --git a/test/reline/test_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb index 8854df56a2..97ff654506 100644 --- a/test/reline/test_key_actor_emacs.rb +++ b/test/reline/test_key_actor_emacs.rb @@ -372,7 +372,7 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase assert_line('abcd012ABCa') end - def test_em_delete_or_list + def test_em_delete input_keys('ab') assert_byte_pointer_size('ab') assert_cursor(2) @@ -388,7 +388,7 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase assert_line('b') end - def test_em_delete_or_list_for_mbchar + def test_em_delete_for_mbchar input_keys('かき') assert_byte_pointer_size('かき') assert_cursor(4) @@ -407,7 +407,7 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase assert_line('き') end - def test_em_delete_or_list_for_mbchar_by_plural_code_points + def test_em_delete_for_mbchar_by_plural_code_points input_keys("か\u3099き\u3099") assert_byte_pointer_size("か\u3099き\u3099") assert_cursor(4) @@ -1244,6 +1244,43 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase assert_line('{}#* AAA!!!CCC ') end + def test_em_delete_or_list + @line_editor.completion_proc = proc { |word| + %w{ + foo_foo + foo_bar + foo_baz + qux + }.map { |i| + i.encode(@encoding) + } + } + input_keys('fooo') + assert_byte_pointer_size('fooo') + assert_cursor(4) + assert_cursor_max(4) + assert_line('fooo') + assert_equal(nil, @line_editor.instance_variable_get(:@menu_info)) + input_keys("\C-b", false) + assert_byte_pointer_size('foo') + assert_cursor(3) + assert_cursor_max(4) + assert_line('fooo') + assert_equal(nil, @line_editor.instance_variable_get(:@menu_info)) + @line_editor.input_key(Reline::Key.new(:em_delete_or_list, :em_delete_or_list, false)) + assert_byte_pointer_size('foo') + assert_cursor(3) + assert_cursor_max(3) + assert_line('foo') + assert_equal(nil, @line_editor.instance_variable_get(:@menu_info)) + @line_editor.input_key(Reline::Key.new(:em_delete_or_list, :em_delete_or_list, false)) + assert_byte_pointer_size('foo') + assert_cursor(3) + assert_cursor_max(3) + assert_line('foo') + assert_equal(%w{foo_foo foo_bar foo_baz}, @line_editor.instance_variable_get(:@menu_info).list) + end + def test_completion @line_editor.completion_proc = proc { |word| %w{ -- cgit v1.2.3