diff options
author | aycabta <aycabta@gmail.com> | 2020-04-17 03:03:12 +0900 |
---|---|---|
committer | aycabta <aycabta@gmail.com> | 2020-04-18 23:12:52 +0900 |
commit | bea3e31e5f8b85f0665b94312418f97e71c14fc6 (patch) | |
tree | c68fd132f15af4875d0748b0a84f6e17badaa549 | |
parent | 1e4efbb6d3e1794222703c2df2b0bb69bc4956cc (diff) |
[ruby/reline] Add ed_search_prev_history
https://github.com/ruby/reline/commit/e9ae288825
-rw-r--r-- | lib/reline/line_editor.rb | 47 | ||||
-rw-r--r-- | test/reline/test_key_actor_emacs.rb | 69 |
2 files changed, 116 insertions, 0 deletions
diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb index 7097a3d878..6f7afea274 100644 --- a/lib/reline/line_editor.rb +++ b/lib/reline/line_editor.rb @@ -1421,6 +1421,53 @@ class Reline::LineEditor end alias_method :forward_search_history, :vi_search_next + private def ed_search_prev_history(key, arg: 1) + history = nil + h_pointer = nil + line_no = nil + substr = @line.slice(0, @byte_pointer) + if @history_pointer.nil? + return if not @line.empty? and substr.empty? + history = Reline::HISTORY + elsif @history_pointer.zero? + history = nil + h_pointer = nil + else + history = Reline::HISTORY.slice(0, @history_pointer) + end + return if history.nil? + if @is_multiline + h_pointer = history.rindex { |h| + h.split("\n").each_with_index { |l, i| + if l.start_with?(substr) + line_no = i + break + end + } + not line_no.nil? + } + else + h_pointer = history.rindex { |l| + l.start_with?(substr) + } + end + return if h_pointer.nil? + @history_pointer = h_pointer + if @is_multiline + @buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n") + @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty? + @line_index = line_no + @line = @buffer_of_lines.last + @rerender_all = true + else + @line = Reline::HISTORY[@history_pointer] + end + @cursor_max = calculate_width(@line) + arg -= 1 + ed_search_prev_history(key, arg: arg) if arg > 0 + end + alias_method :history_search_backward, :ed_search_prev_history + private def ed_prev_history(key, arg: 1) if @is_multiline and @line_index > 0 @previous_line_index = @line_index diff --git a/test/reline/test_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb index 5ab3032f4e..a5de605314 100644 --- a/test/reline/test_key_actor_emacs.rb +++ b/test/reline/test_key_actor_emacs.rb @@ -1912,6 +1912,75 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase $VERBOSE = verbose end + def test_ed_search_prev_history + Reline::HISTORY.concat([ + '12356', # old + '12aaa', + '12345' # new + ]) + input_keys('123') + # The ed_search_prev_history doesn't have default binding + @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) + assert_byte_pointer_size('123') + assert_cursor(3) + assert_cursor_max(5) + assert_line('12345') + @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) + assert_byte_pointer_size('123') + assert_cursor(3) + assert_cursor_max(5) + assert_line('12356') + @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) + assert_byte_pointer_size('123') + assert_cursor(3) + assert_cursor_max(5) + assert_line('12356') + end + + def test_ed_search_prev_history_with_empty + Reline::HISTORY.concat([ + '12356', # old + '12aaa', + '12345' # new + ]) + # The ed_search_prev_history doesn't have default binding + @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) + assert_byte_pointer_size('') + assert_cursor(0) + assert_cursor_max(5) + assert_line('12345') + @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) + assert_byte_pointer_size('') + assert_cursor(0) + assert_cursor_max(5) + assert_line('12aaa') + @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) + assert_byte_pointer_size('') + assert_cursor(0) + assert_cursor_max(5) + assert_line('12356') + @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) + assert_byte_pointer_size('') + assert_cursor(0) + assert_cursor_max(5) + assert_line('12356') + end + + def test_ed_search_prev_history_without_match + Reline::HISTORY.concat([ + '12356', # old + '12aaa', + '12345' # new + ]) + input_keys('ABC') + # The ed_search_prev_history doesn't have default binding + @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) + assert_byte_pointer_size('ABC') + assert_cursor(3) + assert_cursor_max(3) + assert_line('ABC') + end + =begin # TODO: move KeyStroke instance from Reline to LineEditor def test_key_delete input_keys('ab') |