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

ruby-changes:59043

From: aycabta <ko1@a...>
Date: Tue, 3 Dec 2019 01:41:25 +0900 (JST)
Subject: [ruby-changes:59043] a92560132b (master): Support incremental search by last determined word

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

From a92560132b1bff6a01782cfeacd62756b4b34d21 Mon Sep 17 00:00:00 2001
From: aycabta <aycabta@g...>
Date: Tue, 3 Dec 2019 01:17:07 +0900
Subject: Support incremental search by last determined word

In the incremental search by C-r, search word is saved when it's determined. In
the next incremental search by C-r, if a user presses C-r again with the empty
search word, the determined previous search word is used to search.

diff --git a/lib/reline.rb b/lib/reline.rb
index 7352d1a..229c41a 100644
--- a/lib/reline.rb
+++ b/lib/reline.rb
@@ -40,6 +40,7 @@ module Reline https://github.com/ruby/ruby/blob/trunk/lib/reline.rb#L40
     attr_accessor :key_stroke
     attr_accessor :line_editor
     attr_accessor :ambiguous_width
+    attr_accessor :last_incremental_search
     attr_reader :output
 
     def initialize
@@ -367,6 +368,8 @@ module Reline https://github.com/ruby/ruby/blob/trunk/lib/reline.rb#L368
   def_single_delegator :line_editor, :rerender, :redisplay
   def_single_delegators :core, :vi_editing_mode?, :emacs_editing_mode?
   def_single_delegators :core, :ambiguous_width
+  def_single_delegators :core, :last_incremental_search
+  def_single_delegators :core, :last_incremental_search=
 
   def_single_delegators :core, :readmultiline
   def_instance_delegators self, :readmultiline
diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
index fb0b47d..5d325bc 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -1160,6 +1160,9 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L1160
         key = Fiber.yield(search_word)
         search_again = false
         case key
+        when -1 # determined
+          Reline.last_incremental_search = search_word
+          break
         when "\C-h".ord, "\C-?".ord
           grapheme_clusters = search_word.grapheme_clusters
           if grapheme_clusters.size > 0
@@ -1176,13 +1179,18 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L1179
           end
         end
         hit = nil
-        if @line_backup_in_history&.include?(search_word)
+        if not search_word.empty? and @line_backup_in_history&.include?(search_word)
           @history_pointer = nil
           hit = @line_backup_in_history
         else
           if search_again
+            if search_word.empty? and Reline.last_incremental_search
+              search_word = Reline.last_incremental_search
+            end
             if @history_pointer
               history = Reline::HISTORY[0..(@history_pointer - 1)]
+            else
+              history = Reline::HISTORY
             end
           elsif @history_pointer
             history = Reline::HISTORY[0..@history_pointer]
@@ -1226,22 +1234,41 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L1234
       case k
       when "\C-j".ord
         if @history_pointer
-          @line = Reline::HISTORY[@history_pointer]
+          buffer = Reline::HISTORY[@history_pointer]
         else
-          @line = @line_backup_in_history
+          buffer = @line_backup_in_history
+        end
+        if @is_multiline
+          @buffer_of_lines = buffer.split("\n")
+          @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+          @line_index = @buffer_of_lines.size - 1
+          @line = @buffer_of_lines.last
+          @rerender_all = true
+        else
+          @line = buffer
         end
         @searching_prompt = nil
         @waiting_proc = nil
         @cursor_max = calculate_width(@line)
         @cursor = @byte_pointer = 0
+        searcher.resume(-1)
       when "\C-g".ord
-        @line = @line_backup_in_history
+        if @is_multiline
+          @buffer_of_lines = @line_backup_in_history.split("\n")
+          @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+          @line_index = @buffer_of_lines.size - 1
+          @line = @buffer_of_lines.last
+          @rerender_all = true
+        else
+          @line = @line_backup_in_history
+        end
         @history_pointer = nil
         @searching_prompt = nil
         @waiting_proc = nil
         @line_backup_in_history = nil
         @cursor_max = calculate_width(@line)
         @cursor = @byte_pointer = 0
+        @rerender_all = true
       else
         chr = k.is_a?(String) ? k : k.chr(Encoding::ASCII_8BIT)
         if chr.match?(/[[:print:]]/) or k == "\C-h".ord or k == "\C-?".ord or k == "\C-r".ord
@@ -1267,6 +1294,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L1294
           @waiting_proc = nil
           @cursor_max = calculate_width(@line)
           @cursor = @byte_pointer = 0
+          searcher.resume(-1)
         end
       end
     }
diff --git a/test/reline/test_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb
index 6ec583b..8a80bc8 100644
--- a/test/reline/test_key_actor_emacs.rb
+++ b/test/reline/test_key_actor_emacs.rb
@@ -1474,6 +1474,43 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase https://github.com/ruby/ruby/blob/trunk/test/reline/test_key_actor_emacs.rb#L1474
     assert_cursor_max(0)
   end
 
+  def test_search_history_by_last_determined
+    Reline::HISTORY.concat([
+      '1235', # old
+      '12aa',
+      '1234' # new
+    ])
+    assert_line('')
+    assert_byte_pointer_size('')
+    assert_cursor(0)
+    assert_cursor_max(0)
+    input_keys("\C-r123")
+    assert_line('1234')
+    assert_byte_pointer_size('')
+    assert_cursor(0)
+    assert_cursor_max(0) # doesn't determine yet
+    input_keys("\C-j")
+    assert_line('1234')
+    assert_byte_pointer_size('')
+    assert_cursor(0)
+    assert_cursor_max(4)
+    input_keys("\C-k") # delete
+    assert_line('')
+    assert_byte_pointer_size('')
+    assert_cursor(0)
+    assert_cursor_max(0)
+    input_keys("\C-r")
+    assert_line('')
+    assert_byte_pointer_size('')
+    assert_cursor(0)
+    assert_cursor_max(0)
+    input_keys("\C-r")
+    assert_line('1235')
+    assert_byte_pointer_size('')
+    assert_cursor(0)
+    assert_cursor_max(0)
+  end
+
   def test_em_set_mark_and_em_exchange_mark
     input_keys('aaa bbb ccc ddd')
     assert_byte_pointer_size('aaa bbb ccc ddd')
-- 
cgit v0.10.2


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

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