aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authoraycabta <aycabta@gmail.com>2019-05-28 08:38:55 +0900
committeraycabta <aycabta@gmail.com>2019-05-28 08:38:55 +0900
commit57b4df07bc1e863c48a3b0f4c3185de431454695 (patch)
tree27c865a65c919936e7682c47d814a9c87d74daae /lib
parent74c88e7cda8640084077003ec00b004f9dd7ae73 (diff)
downloadruby-57b4df07bc1e863c48a3b0f4c3185de431454695.tar.gz
Use Reline.completer_quote_characters to complete
Diffstat (limited to 'lib')
-rw-r--r--lib/reline.rb16
-rw-r--r--lib/reline/line_editor.rb45
2 files changed, 36 insertions, 25 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