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

ruby-changes:67618

From: aycabta <ko1@a...>
Date: Mon, 6 Sep 2021 05:23:42 +0900 (JST)
Subject: [ruby-changes:67618] 3773296bfc (master): [ruby/reline] Allow Reline::KeyStroke to compare raw and meta-key processed key sequences

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

From 3773296bfc45a60baf9e5cc025bfed2d6b493eaa Mon Sep 17 00:00:00 2001
From: aycabta <aycabta@g...>
Date: Mon, 6 Sep 2021 03:58:48 +0900
Subject: [ruby/reline] Allow Reline::KeyStroke to compare raw and meta-key
 processed key sequences

https://github.com/ruby/reline/commit/731103f9c9
---
 lib/reline.rb            | 12 ++++++++--
 lib/reline/key_stroke.rb | 58 +++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 65 insertions(+), 5 deletions(-)

diff --git a/lib/reline.rb b/lib/reline.rb
index 3569787..33aa6cd 100644
--- a/lib/reline.rb
+++ b/lib/reline.rb
@@ -390,15 +390,23 @@ module Reline https://github.com/ruby/ruby/blob/trunk/lib/reline.rb#L390
               block.([Reline::Key.new(c, c, false)])
               break
             else
-              if key_stroke.match_status(buffer.dup.push(succ_c)) == :unmatched
+              case key_stroke.match_status(buffer.dup.push(succ_c))
+              when :unmatched
                 if c == "\e".ord
                   block.([Reline::Key.new(succ_c, succ_c | 0b10000000, true)])
                 else
                   block.([Reline::Key.new(c, c, false), Reline::Key.new(succ_c, succ_c, false)])
                 end
                 break
-              else
+              when :matching
                 Reline::IOGate.ungetc(succ_c)
+              when :matched
+                buffer << succ_c
+                expanded = key_stroke.expand(buffer).map{ |expanded_c|
+                  Reline::Key.new(expanded_c, expanded_c, false)
+                }
+                block.(expanded)
+                break
               end
             end
           end
diff --git a/lib/reline/key_stroke.rb b/lib/reline/key_stroke.rb
index 017e3db..675b658f 100644
--- a/lib/reline/key_stroke.rb
+++ b/lib/reline/key_stroke.rb
@@ -1,8 +1,59 @@ https://github.com/ruby/ruby/blob/trunk/lib/reline/key_stroke.rb#L1
 class Reline::KeyStroke
   using Module.new {
+    refine Integer do
+      def ==(other)
+        if other.is_a?(Reline::Key)
+          if other.combined_char == "\e".ord
+            false
+          else
+            other.combined_char == self
+          end
+        else
+          super
+        end
+      end
+    end
+
     refine Array do
       def start_with?(other)
-        other.size <= size && other == self.take(other.size)
+        compressed_me = compress_meta_key
+        compressed_other = other.compress_meta_key
+        i = 0
+        loop do
+          my_c = compressed_me[i]
+          other_c = compressed_other[i]
+          other_is_last = (i + 1) == compressed_other.size
+          me_is_last = (i + 1) == compressed_me.size
+          if my_c != other_c
+            if other_c == "\e".ord and other_is_last and my_c.is_a?(Reline::Key) and my_c.with_meta
+              return true
+            else
+              return false
+            end
+          elsif other_is_last
+            return true
+          elsif me_is_last
+            return false
+          end
+          i += 1
+        end
+      end
+
+      def ==(other)
+        compressed_me = compress_meta_key
+        compressed_other = other.compress_meta_key
+        compressed_me.size == compressed_other.size and [compressed_me, compressed_other].transpose.all?{ |i| i[0] == i[1] }
+      end
+
+      def compress_meta_key
+        inject([]) { |result, key|
+          if result.size > 0 and result.last == "\e".ord
+            result[result.size - 1] = Reline::Key.new(key, key | 0b10000000, true)
+          else
+            result << key
+          end
+          result
+        }
       end
 
       def bytes
@@ -19,8 +70,8 @@ class Reline::KeyStroke https://github.com/ruby/ruby/blob/trunk/lib/reline/key_stroke.rb#L70
     key_mapping.keys.select { |lhs|
       lhs.start_with? input
     }.tap { |it|
-      return :matched  if it.size == 1 && (it.max_by(&:size)&.size&.== input.size)
-      return :matching if it.size == 1 && (it.max_by(&:size)&.size&.!= input.size)
+      return :matched  if it.size == 1 && (it.max_by(&:size)&.== input)
+      return :matching if it.size == 1 && (it.max_by(&:size)&.!= input)
       return :matched  if it.max_by(&:size)&.size&.< input.size
       return :matching if it.size > 1
     }
@@ -32,6 +83,7 @@ class Reline::KeyStroke https://github.com/ruby/ruby/blob/trunk/lib/reline/key_stroke.rb#L83
   end
 
   def expand(input)
+    input = input.compress_meta_key
     lhs = key_mapping.keys.select { |item| input.start_with? item }.sort_by(&:size).reverse.first
     return input unless lhs
     rhs = key_mapping[lhs]
-- 
cgit v1.1


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

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