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

ruby-changes:59143

From: aycabta <ko1@a...>
Date: Tue, 10 Dec 2019 07:08:20 +0900 (JST)
Subject: [ruby-changes:59143] 6a22b2a091 (master): Support completion with case-insensitive fashion

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

From 6a22b2a091eda81a473eb1b0cc69fe0792560e27 Mon Sep 17 00:00:00 2001
From: aycabta <aycabta@g...>
Date: Tue, 10 Dec 2019 07:01:26 +0900
Subject: Support completion with case-insensitive fashion

Reline performs completion in a case-insensitive fashon if
Readline.completion_case_fold or completion-ignore-case of .inputrc are set
"on".

diff --git a/lib/reline.rb b/lib/reline.rb
index 229c41a..2036ec7 100644
--- a/lib/reline.rb
+++ b/lib/reline.rb
@@ -32,10 +32,6 @@ module Reline https://github.com/ruby/ruby/blob/trunk/lib/reline.rb#L32
       dig_perfect_match_proc
     ).each(&method(:attr_reader))
 
-    ATTR_ACCESSOR_NAMES = %i(
-      completion_case_fold
-    ).each(&method(:attr_accessor))
-
     attr_accessor :config
     attr_accessor :key_stroke
     attr_accessor :line_editor
@@ -84,6 +80,14 @@ module Reline https://github.com/ruby/ruby/blob/trunk/lib/reline.rb#L80
       @special_prefixes = v.encode(Encoding::default_external)
     end
 
+    def completion_case_fold=(v)
+      @config.completion_ignore_case = v
+    end
+
+    def completion_case_fold
+      @config.completion_ignore_case
+    end
+
     def completion_proc=(p)
       raise ArgumentError unless p.respond_to?(:call)
       @completion_proc = p
@@ -336,12 +340,13 @@ module Reline https://github.com/ruby/ruby/blob/trunk/lib/reline.rb#L340
   # Documented API
   #--------------------------------------------------------
 
-  (Core::ATTR_READER_NAMES + Core::ATTR_ACCESSOR_NAMES).each { |name|
+  (Core::ATTR_READER_NAMES).each { |name|
     def_single_delegators :core, "#{name}", "#{name}="
   }
   def_single_delegators :core, :input=, :output=
   def_single_delegators :core, :vi_editing_mode, :emacs_editing_mode
   def_single_delegators :core, :readline
+  def_single_delegators :core, :completion_case_fold, :completion_case_fold=
   def_instance_delegators self, :readline
   private :readline
 
diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
index e352f88..2986bdd 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -552,7 +552,11 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L552
       if i and not Encoding.compatible?(target.encoding, i.encoding)
         raise Encoding::CompatibilityError
       end
-      i&.start_with?(target)
+      if @config.completion_ignore_case
+        i&.downcase.start_with?(target.downcase)
+      else
+        i&.start_with?(target)
+      end
     }
     if is_menu
       menu(target, list)
@@ -569,10 +573,18 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L573
       size = [memo_mbchars.size, item_mbchars.size].min
       result = ''
       size.times do |i|
-        if memo_mbchars[i] == item_mbchars[i]
-          result << memo_mbchars[i]
+        if @config.completion_ignore_case
+          if memo_mbchars[i].casecmp?(item_mbchars[i])
+            result << memo_mbchars[i]
+          else
+            break
+          end
         else
-          break
+          if memo_mbchars[i] == item_mbchars[i]
+            result << memo_mbchars[i]
+          else
+            break
+          end
         end
       end
       result
diff --git a/test/reline/test_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb
index 8a80bc8..cd5b926 100644
--- a/test/reline/test_key_actor_emacs.rb
+++ b/test/reline/test_key_actor_emacs.rb
@@ -1287,6 +1287,57 @@ 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_completion_ignore_case
+    @line_editor.completion_proc = proc { |word|
+      %w{
+        foo_foo
+        foo_bar
+        Foo_baz
+        qux
+      }.map { |i|
+        i.encode(@encoding)
+      }
+    }
+    input_keys('fo')
+    assert_byte_pointer_size('fo')
+    assert_cursor(2)
+    assert_cursor_max(2)
+    assert_line('fo')
+    assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
+    input_keys("\C-i", false)
+    assert_byte_pointer_size('foo_')
+    assert_cursor(4)
+    assert_cursor_max(4)
+    assert_line('foo_')
+    assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
+    input_keys("\C-i", false)
+    assert_byte_pointer_size('foo_')
+    assert_cursor(4)
+    assert_cursor_max(4)
+    assert_line('foo_')
+    assert_equal(%w{foo_foo foo_bar}, @line_editor.instance_variable_get(:@menu_info).list)
+    @config.completion_ignore_case = true
+    input_keys("\C-i", false)
+    assert_byte_pointer_size('foo_')
+    assert_cursor(4)
+    assert_cursor_max(4)
+    assert_line('foo_')
+    assert_equal(%w{foo_foo foo_bar Foo_baz}, @line_editor.instance_variable_get(:@menu_info).list)
+    input_keys('a')
+    input_keys("\C-i", false)
+    assert_byte_pointer_size('foo_a')
+    assert_cursor(5)
+    assert_cursor_max(5)
+    assert_line('foo_a')
+    input_keys("\C-h", false)
+    input_keys('b')
+    input_keys("\C-i", false)
+    assert_byte_pointer_size('foo_ba')
+    assert_cursor(6)
+    assert_cursor_max(6)
+    assert_line('foo_ba')
+  end
+
   def test_completion_in_middle_of_line
     @line_editor.completion_proc = proc { |word|
       %w{
-- 
cgit v0.10.2


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

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