diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb index c74db5286d..9d8185ff00 100644 --- a/lib/reline/line_editor.rb +++ b/lib/reline/line_editor.rb @@ -1196,6 +1196,7 @@ class Reline::LineEditor loop do key = Fiber.yield(search_word) search_again = false + change_direction = false case key when -1 # determined Reline.last_incremental_search = search_word @@ -1207,7 +1208,11 @@ class Reline::LineEditor search_word = grapheme_clusters.join end when "\C-r".ord, "\C-s".ord - search_again = true if prev_search_key == key + if prev_search_key == key + search_again = true + else + change_direction = true + end prev_search_key = key else multibyte_buf << key @@ -1229,10 +1234,19 @@ class Reline::LineEditor case prev_search_key when "\C-r".ord history_pointer_base = 0 - history = Reline::HISTORY[0..(@history_pointer - 1)] + if change_direction + history = Reline::HISTORY[0..@history_pointer] + else + history = Reline::HISTORY[0..(@history_pointer - 1)] + end when "\C-s".ord - history_pointer_base = @history_pointer + 1 - history = Reline::HISTORY[(@history_pointer + 1)..-1] + if change_direction + history_pointer_base = @history_pointer + history = Reline::HISTORY[(@history_pointer)..-1] + else + history_pointer_base = @history_pointer + 1 + history = Reline::HISTORY[(@history_pointer + 1)..-1] + end end else history_pointer_base = 0 @@ -1242,10 +1256,19 @@ class Reline::LineEditor case prev_search_key when "\C-r".ord history_pointer_base = 0 - history = Reline::HISTORY[0..@history_pointer] + if change_direction + history = Reline::HISTORY[0..@history_pointer] + else + history = Reline::HISTORY[0..@history_pointer] + end when "\C-s".ord - history_pointer_base = @history_pointer - history = Reline::HISTORY[@history_pointer..-1] + if change_direction + history_pointer_base = @history_pointer + history = Reline::HISTORY[(@history_pointer - 1)..-1] + else + history_pointer_base = @history_pointer + history = Reline::HISTORY[@history_pointer..-1] + end end else history_pointer_base = 0 diff --git a/test/reline/test_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb index 5e5be0c15c..8854df56a2 100644 --- a/test/reline/test_key_actor_emacs.rb +++ b/test/reline/test_key_actor_emacs.rb @@ -1620,6 +1620,70 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase assert_cursor_max(0) end + def test_search_history_front_and_back + Reline::HISTORY.concat([ + '1235', # old + '12aa', + '1234' # new + ]) + assert_line('') + assert_byte_pointer_size('') + assert_cursor(0) + assert_cursor_max(0) + input_keys("\C-s12") + assert_line('1235') + assert_byte_pointer_size('') + assert_cursor(0) + assert_cursor_max(0) # doesn't determine yet + input_keys("\C-s") + assert_line('12aa') + assert_byte_pointer_size('') + assert_cursor(0) + assert_cursor_max(0) + input_keys("\C-r") + assert_line('12aa') + 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_search_history_back_and_front + Reline::HISTORY.concat([ + '1235', # old + '12aa', + '1234' # new + ]) + assert_line('') + assert_byte_pointer_size('') + assert_cursor(0) + assert_cursor_max(0) + input_keys("\C-r12") + assert_line('1234') + assert_byte_pointer_size('') + assert_cursor(0) + assert_cursor_max(0) # doesn't determine yet + input_keys("\C-r") + assert_line('12aa') + assert_byte_pointer_size('') + assert_cursor(0) + assert_cursor_max(0) + input_keys("\C-s") + assert_line('12aa') + assert_byte_pointer_size('') + assert_cursor(0) + assert_cursor_max(0) + input_keys("\C-s") + assert_line('1234') + assert_byte_pointer_size('') + assert_cursor(0) + assert_cursor_max(0) + end + def test_search_history_to_back_in_the_middle_of_histories Reline::HISTORY.concat([ '1235', # old