зеркало из https://github.com/github/ruby.git
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.
This commit is contained in:
Родитель
bce38f706e
Коммит
a92560132b
|
@ -40,6 +40,7 @@ module Reline
|
||||||
attr_accessor :key_stroke
|
attr_accessor :key_stroke
|
||||||
attr_accessor :line_editor
|
attr_accessor :line_editor
|
||||||
attr_accessor :ambiguous_width
|
attr_accessor :ambiguous_width
|
||||||
|
attr_accessor :last_incremental_search
|
||||||
attr_reader :output
|
attr_reader :output
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
|
@ -367,6 +368,8 @@ module Reline
|
||||||
def_single_delegator :line_editor, :rerender, :redisplay
|
def_single_delegator :line_editor, :rerender, :redisplay
|
||||||
def_single_delegators :core, :vi_editing_mode?, :emacs_editing_mode?
|
def_single_delegators :core, :vi_editing_mode?, :emacs_editing_mode?
|
||||||
def_single_delegators :core, :ambiguous_width
|
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_single_delegators :core, :readmultiline
|
||||||
def_instance_delegators self, :readmultiline
|
def_instance_delegators self, :readmultiline
|
||||||
|
|
|
@ -1160,6 +1160,9 @@ class Reline::LineEditor
|
||||||
key = Fiber.yield(search_word)
|
key = Fiber.yield(search_word)
|
||||||
search_again = false
|
search_again = false
|
||||||
case key
|
case key
|
||||||
|
when -1 # determined
|
||||||
|
Reline.last_incremental_search = search_word
|
||||||
|
break
|
||||||
when "\C-h".ord, "\C-?".ord
|
when "\C-h".ord, "\C-?".ord
|
||||||
grapheme_clusters = search_word.grapheme_clusters
|
grapheme_clusters = search_word.grapheme_clusters
|
||||||
if grapheme_clusters.size > 0
|
if grapheme_clusters.size > 0
|
||||||
|
@ -1176,13 +1179,18 @@ class Reline::LineEditor
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
hit = nil
|
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
|
@history_pointer = nil
|
||||||
hit = @line_backup_in_history
|
hit = @line_backup_in_history
|
||||||
else
|
else
|
||||||
if search_again
|
if search_again
|
||||||
|
if search_word.empty? and Reline.last_incremental_search
|
||||||
|
search_word = Reline.last_incremental_search
|
||||||
|
end
|
||||||
if @history_pointer
|
if @history_pointer
|
||||||
history = Reline::HISTORY[0..(@history_pointer - 1)]
|
history = Reline::HISTORY[0..(@history_pointer - 1)]
|
||||||
|
else
|
||||||
|
history = Reline::HISTORY
|
||||||
end
|
end
|
||||||
elsif @history_pointer
|
elsif @history_pointer
|
||||||
history = Reline::HISTORY[0..@history_pointer]
|
history = Reline::HISTORY[0..@history_pointer]
|
||||||
|
@ -1226,22 +1234,41 @@ class Reline::LineEditor
|
||||||
case k
|
case k
|
||||||
when "\C-j".ord
|
when "\C-j".ord
|
||||||
if @history_pointer
|
if @history_pointer
|
||||||
@line = Reline::HISTORY[@history_pointer]
|
buffer = Reline::HISTORY[@history_pointer]
|
||||||
else
|
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
|
end
|
||||||
@searching_prompt = nil
|
@searching_prompt = nil
|
||||||
@waiting_proc = nil
|
@waiting_proc = nil
|
||||||
@cursor_max = calculate_width(@line)
|
@cursor_max = calculate_width(@line)
|
||||||
@cursor = @byte_pointer = 0
|
@cursor = @byte_pointer = 0
|
||||||
|
searcher.resume(-1)
|
||||||
when "\C-g".ord
|
when "\C-g".ord
|
||||||
|
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
|
@line = @line_backup_in_history
|
||||||
|
end
|
||||||
@history_pointer = nil
|
@history_pointer = nil
|
||||||
@searching_prompt = nil
|
@searching_prompt = nil
|
||||||
@waiting_proc = nil
|
@waiting_proc = nil
|
||||||
@line_backup_in_history = nil
|
@line_backup_in_history = nil
|
||||||
@cursor_max = calculate_width(@line)
|
@cursor_max = calculate_width(@line)
|
||||||
@cursor = @byte_pointer = 0
|
@cursor = @byte_pointer = 0
|
||||||
|
@rerender_all = true
|
||||||
else
|
else
|
||||||
chr = k.is_a?(String) ? k : k.chr(Encoding::ASCII_8BIT)
|
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
|
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
|
@waiting_proc = nil
|
||||||
@cursor_max = calculate_width(@line)
|
@cursor_max = calculate_width(@line)
|
||||||
@cursor = @byte_pointer = 0
|
@cursor = @byte_pointer = 0
|
||||||
|
searcher.resume(-1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
|
@ -1474,6 +1474,43 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
|
||||||
assert_cursor_max(0)
|
assert_cursor_max(0)
|
||||||
end
|
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
|
def test_em_set_mark_and_em_exchange_mark
|
||||||
input_keys('aaa bbb ccc ddd')
|
input_keys('aaa bbb ccc ddd')
|
||||||
assert_byte_pointer_size('aaa bbb ccc ddd')
|
assert_byte_pointer_size('aaa bbb ccc ddd')
|
||||||
|
|
Загрузка…
Ссылка в новой задаче