[前][次][番号順一覧][スレッド一覧]

ruby-changes:59226

From: aycabta <ko1@a...>
Date: Fri, 13 Dec 2019 08:54:58 +0900 (JST)
Subject: [ruby-changes:59226] c2dfc6d869 (master): Show a menu before a document

https://git.ruby-lang.org/ruby.git/commit/?id=c2dfc6d869

From c2dfc6d869979124a46fb0c5404956891c27575f Mon Sep 17 00:00:00 2001
From: aycabta <aycabta@g...>
Date: Fri, 13 Dec 2019 03:57:32 +0900
Subject: Show a menu before a document

IRB should show a menu first if a completed list has plural items. But just
shows document without menu if a completed list with plural items includes a
perfect matched item. The behavior is a bug. This commit fixes it.

diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
index 5d23c82..20d966f 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -43,6 +43,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L43
     COMPLETION = :completion
     MENU = :menu
     JOURNEY = :journey
+    MENU_WITH_PERFECT_MATCH = :menu_with_perfect_match
     PERFECT_MATCH = :perfect_match
   end
 
@@ -599,16 +600,24 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L600
     when CompletionState::PERFECT_MATCH
       @dig_perfect_match_proc&.(@perfect_matched)
     end
-    is_menu = (@completion_state == CompletionState::MENU)
+    is_menu = (@completion_state == CompletionState::MENU or @completion_state == CompletionState::MENU_WITH_PERFECT_MATCH)
     result = complete_internal_proc(list, is_menu)
+    if @completion_state == CompletionState::MENU_WITH_PERFECT_MATCH
+      @completion_state = CompletionState::PERFECT_MATCH
+    end
     return if result.nil?
     target, preposing, completed, postposing = result
     return if completed.nil?
-    if target <= completed and (@completion_state == CompletionState::COMPLETION or @completion_state == CompletionState::PERFECT_MATCH)
-      @completion_state = CompletionState::MENU
+    if target <= completed and (@completion_state == CompletionState::COMPLETION)
       if list.include?(completed)
-        @completion_state = CompletionState::PERFECT_MATCH
+        if list.one?
+          @completion_state = CompletionState::PERFECT_MATCH
+        else
+          @completion_state = CompletionState::MENU_WITH_PERFECT_MATCH
+        end
         @perfect_matched = completed
+      else
+        @completion_state = CompletionState::MENU
       end
       if target < completed
         @line = preposing + completed + postposing
@@ -622,7 +631,8 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L631
 
   private def move_completed_list(list, direction)
     case @completion_state
-    when CompletionState::NORMAL, CompletionState::COMPLETION, CompletionState::MENU
+    when CompletionState::NORMAL, CompletionState::COMPLETION,
+         CompletionState::MENU, CompletionState::MENU_WITH_PERFECT_MATCH
       @completion_state = CompletionState::JOURNEY
       result = retrieve_completion_block
       return if result.nil?
diff --git a/test/reline/test_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb
index 4e3184b..7ffa28e 100644
--- a/test/reline/test_key_actor_emacs.rb
+++ b/test/reline/test_key_actor_emacs.rb
@@ -1287,6 +1287,72 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase https://github.com/ruby/ruby/blob/trunk/test/reline/test_key_actor_emacs.rb#L1287
     assert_line('foo_ba')
   end
 
+  def test_completion_with_perfect_match
+    @line_editor.completion_proc = proc { |word|
+      %w{
+        foo
+        foo_bar
+      }.map { |i|
+        i.encode(@encoding)
+      }
+    }
+    matched = nil
+    @line_editor.dig_perfect_match_proc = proc { |m|
+      matched = m
+    }
+    input_keys('fo')
+    assert_byte_pointer_size('fo')
+    assert_cursor(2)
+    assert_cursor_max(2)
+    assert_line('fo')
+    assert_equal(Reline::LineEditor::CompletionState::NORMAL, @line_editor.instance_variable_get(:@completion_state))
+    assert_equal(nil, matched)
+    input_keys("\C-i", false)
+    assert_byte_pointer_size('foo')
+    assert_cursor(3)
+    assert_cursor_max(3)
+    assert_line('foo')
+    assert_equal(Reline::LineEditor::CompletionState::MENU_WITH_PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state))
+    assert_equal(nil, matched)
+    input_keys("\C-i", false)
+    assert_byte_pointer_size('foo')
+    assert_cursor(3)
+    assert_cursor_max(3)
+    assert_line('foo')
+    assert_equal(Reline::LineEditor::CompletionState::PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state))
+    assert_equal(nil, matched)
+    input_keys("\C-i", false)
+    assert_byte_pointer_size('foo')
+    assert_cursor(3)
+    assert_cursor_max(3)
+    assert_line('foo')
+    assert_equal(Reline::LineEditor::CompletionState::PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state))
+    assert_equal('foo', matched)
+    matched = nil
+    input_keys('_')
+    input_keys("\C-i", false)
+    assert_byte_pointer_size('foo_bar')
+    assert_cursor(7)
+    assert_cursor_max(7)
+    assert_line('foo_bar')
+    assert_equal(Reline::LineEditor::CompletionState::MENU_WITH_PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state))
+    assert_equal(nil, matched)
+    input_keys("\C-i", false)
+    assert_byte_pointer_size('foo_bar')
+    assert_cursor(7)
+    assert_cursor_max(7)
+    assert_line('foo_bar')
+    assert_equal(Reline::LineEditor::CompletionState::PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state))
+    assert_equal(nil, matched)
+    input_keys("\C-i", false)
+    assert_byte_pointer_size('foo_bar')
+    assert_cursor(7)
+    assert_cursor_max(7)
+    assert_line('foo_bar')
+    assert_equal(Reline::LineEditor::CompletionState::PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state))
+    assert_equal('foo_bar', matched)
+  end
+
   def test_completion_with_completion_ignore_case
     @line_editor.completion_proc = proc { |word|
       %w{
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]