diff options
-rw-r--r-- | lib/reline.rb | 16 | ||||
-rw-r--r-- | lib/reline/line_editor.rb | 45 | ||||
-rw-r--r-- | test/reline/test_key_actor_emacs.rb | 1 | ||||
-rw-r--r-- | test/reline/test_key_actor_vi.rb | 1 |
4 files changed, 36 insertions, 27 deletions
diff --git a/lib/reline.rb b/lib/reline.rb index 0b6eddf498..656fab2fea 100644 --- a/lib/reline.rb +++ b/lib/reline.rb @@ -239,21 +239,6 @@ module Reline Reline::IOGate.get_screen_size end - def retrieve_completion_block(line, byte_pointer) - break_regexp = /[#{Regexp.escape(@@basic_word_break_characters)}]/ - before_pointer = line.byteslice(0, byte_pointer) - break_point = before_pointer.rindex(break_regexp) - if break_point - preposing = before_pointer[0..(break_point)] - block = before_pointer[(break_point + 1)..-1] - else - preposing = '' - block = before_pointer - end - postposing = line.byteslice(byte_pointer, line.bytesize) - [preposing, block, postposing] - end - def eof? @@line_editor.eof? end @@ -313,7 +298,6 @@ module Reline @@line_editor.output_modifier_proc = @@output_modifier_proc @@line_editor.dig_perfect_match_proc = @@dig_perfect_match_proc @@line_editor.pre_input_hook = @@pre_input_hook - @@line_editor.retrieve_completion_block = method(:retrieve_completion_block) @@line_editor.rerender if IS_WINDOWS diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb index 44cb0577a2..baec338e74 100644 --- a/lib/reline/line_editor.rb +++ b/lib/reline/line_editor.rb @@ -13,7 +13,6 @@ class Reline::LineEditor attr_accessor :output_modifier_proc attr_accessor :pre_input_hook attr_accessor :dig_perfect_match_proc - attr_writer :retrieve_completion_block attr_writer :output ARGUMENTABLE = %i{ @@ -482,7 +481,7 @@ class Reline::LineEditor end private def complete_internal_proc(list, is_menu) - preposing, target, postposing = @retrieve_completion_block.(@line, @byte_pointer) + preposing, target, postposing = retrieve_completion_block list = list.select { |i| if i and i.encoding != Encoding::US_ASCII and i.encoding != @encoding raise Encoding::CompatibilityError @@ -547,7 +546,7 @@ class Reline::LineEditor case @completion_state when CompletionState::NORMAL, CompletionState::COMPLETION, CompletionState::MENU @completion_state = CompletionState::JOURNEY - result = @retrieve_completion_block.(@line, @byte_pointer) + result = retrieve_completion_block return if result.nil? preposing, target, postposing = result @completion_journey_data = CompletionJourneyData.new( @@ -697,14 +696,16 @@ class Reline::LineEditor @first_char = false completion_occurs = false if @config.editing_mode_is?(:emacs, :vi_insert) and key.char == "\C-i".ord - slice = retrieve_completion_slice + result = retrieve_completion_block + slice = result[1] result = @completion_proc.(slice) if @completion_proc and slice if result.is_a?(Array) completion_occurs = true complete(result) end elsif @config.editing_mode_is?(:vi_insert) and ["\C-p".ord, "\C-n".ord].include?(key.char) - slice = retrieve_completion_slice + result = retrieve_completion_block + slice = result[1] result = @completion_proc.(slice) if @completion_proc and slice if result.is_a?(Array) completion_occurs = true @@ -720,16 +721,42 @@ class Reline::LineEditor end end - def retrieve_completion_slice + def retrieve_completion_block word_break_regexp = /\A[#{Regexp.escape(Reline.completer_word_break_characters)}]/ + quote_characters_regexp = /\A[#{Regexp.escape(Reline.completer_quote_characters)}]/ before = @line.byteslice(0, @byte_pointer) rest = nil - (0..@byte_pointer).each do |i| - if @line.byteslice(i, @byte_pointer) =~ word_break_regexp + break_pointer = nil + quote = nil + i = 0 + while i < @byte_pointer do + slice = @line.byteslice(i, @byte_pointer - i) + if quote and slice =~ /\A(?<!\\)#{Regexp.escape(quote)}/ # closing " + quote = nil + i += 1 + elsif quote and slice =~ /\A\\#{Regexp.escape(quote)}/ # escaped \" + # skip + i += 2 + elsif slice =~ quote_characters_regexp # find new " + quote = $& + i += 1 + elsif not quote and slice =~ word_break_regexp rest = $' + i += 1 + break_pointer = i + else + i += 1 end end - rest ? rest : before + if rest + preposing = @line.byteslice(0, break_pointer) + target = rest + else + preposing = '' + target = before + end + postposing = @line.byteslice(@byte_pointer, @line.bytesize - @byte_pointer) + [preposing, target, postposing] end def confirm_multiline_termination diff --git a/test/reline/test_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb index 58e1a07c69..5778677ad8 100644 --- a/test/reline/test_key_actor_emacs.rb +++ b/test/reline/test_key_actor_emacs.rb @@ -8,7 +8,6 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase @encoding = (RELINE_TEST_ENCODING rescue Encoding.default_external) @line_editor = Reline::LineEditor.new(@config) @line_editor.reset(@prompt, @encoding) - @line_editor.retrieve_completion_block = Reline.method(:retrieve_completion_block) end def test_ed_insert_one diff --git a/test/reline/test_key_actor_vi.rb b/test/reline/test_key_actor_vi.rb index e6392cf166..f5ceda05a6 100644 --- a/test/reline/test_key_actor_vi.rb +++ b/test/reline/test_key_actor_vi.rb @@ -10,7 +10,6 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase LINES @line_editor = Reline::LineEditor.new(@config) @line_editor.reset(@prompt, (RELINE_TEST_ENCODING rescue Encoding.default_external)) - @line_editor.retrieve_completion_block = Reline.method(:retrieve_completion_block) end def test_vi_command_mode |