summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authoraycabta <aycabta@gmail.com>2019-12-03 01:17:07 +0900
committeraycabta <aycabta@gmail.com>2019-12-03 01:39:59 +0900
commita92560132b1bff6a01782cfeacd62756b4b34d21 (patch)
tree240caff6dba5dabc52823ab7cb13e7c707ef21ce /lib
parentbce38f706e9c434d8fd7c0e2e14bb4acdd085777 (diff)
downloadruby-a92560132b1bff6a01782cfeacd62756b4b34d21.tar.gz
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.
Diffstat (limited to 'lib')
-rw-r--r--lib/reline.rb3
-rw-r--r--lib/reline/line_editor.rb36
2 files changed, 35 insertions, 4 deletions
diff --git a/lib/reline.rb b/lib/reline.rb
index 7352d1a625..229c41a9a8 100644
--- a/lib/reline.rb
+++ b/lib/reline.rb
@@ -40,6 +40,7 @@ module Reline
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
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 fb0b47d7ee..5d325bc7c4 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -1160,6 +1160,9 @@ class Reline::LineEditor
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
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
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
@waiting_proc = nil
@cursor_max = calculate_width(@line)
@cursor = @byte_pointer = 0
+ searcher.resume(-1)
end
end
}