[前][次][番号順一覧][スレッド一覧]

ruby-changes:59172

From: aycabta <ko1@a...>
Date: Wed, 11 Dec 2019 11:13:34 +0900 (JST)
Subject: [ruby-changes:59172] ec54ac9381 (master): Support Readline.completion_quote_character by Reline

https://git.ruby-lang.org/ruby.git/commit/?id=ec54ac9381

From ec54ac938104517dd61887006ef8cc324b3b1b35 Mon Sep 17 00:00:00 2001
From: aycabta <aycabta@g...>
Date: Wed, 11 Dec 2019 11:12:54 +0900
Subject: Support Readline.completion_quote_character by Reline


diff --git a/lib/reline.rb b/lib/reline.rb
index 2036ec7..c4c6b97 100644
--- a/lib/reline.rb
+++ b/lib/reline.rb
@@ -42,6 +42,7 @@ module Reline https://github.com/ruby/ruby/blob/trunk/lib/reline.rb#L42
     def initialize
       self.output = STDOUT
       yield self
+      @completion_quote_character = nil
     end
 
     def completion_append_character=(val)
@@ -88,6 +89,10 @@ module Reline https://github.com/ruby/ruby/blob/trunk/lib/reline.rb#L89
       @config.completion_ignore_case
     end
 
+    def completion_quote_character
+      @completion_quote_character
+    end
+
     def completion_proc=(p)
       raise ArgumentError unless p.respond_to?(:call)
       @completion_proc = p
@@ -347,6 +352,7 @@ module Reline https://github.com/ruby/ruby/blob/trunk/lib/reline.rb#L352
   def_single_delegators :core, :vi_editing_mode, :emacs_editing_mode
   def_single_delegators :core, :readline
   def_single_delegators :core, :completion_case_fold, :completion_case_fold=
+  def_single_delegators :core, :completion_quote_character
   def_instance_delegators self, :readline
   private :readline
 
diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
index 74c5489..2abe659 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -789,9 +789,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L789
     completion_occurs = false
     if @config.editing_mode_is?(:emacs, :vi_insert) and key.char == "\C-i".ord
       unless @config.disable_completion
-        result = retrieve_completion_block
-        slice = result[1]
-        result = @completion_proc.(slice) if @completion_proc and slice
+        result = call_completion_proc
         if result.is_a?(Array)
           completion_occurs = true
           complete(result)
@@ -799,9 +797,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L797
       end
     elsif not @config.disable_completion and @config.editing_mode_is?(:vi_insert) and ["\C-p".ord, "\C-n".ord].include?(key.char)
       unless @config.disable_completion
-        result = retrieve_completion_block
-        slice = result[1]
-        result = @completion_proc.(slice) if @completion_proc and slice
+        result = call_completion_proc
         if result.is_a?(Array)
           completion_occurs = true
           move_completed_list(result, "\C-p".ord == key.char ? :up : :down)
@@ -820,6 +816,14 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L816
     end
   end
 
+  def call_completion_proc
+    result = retrieve_completion_block(true)
+    slice = result[1]
+    result = @completion_proc.(slice) if @completion_proc and slice
+    Reline.core.instance_variable_set(:@completion_quote_character, nil)
+    result
+  end
+
   private def process_auto_indent
     return if not @check_new_auto_indent and @previous_line_index # move cursor up or down
     if @check_new_auto_indent and @previous_line_index and @previous_line_index > 0 and @line_index > @previous_line_index
@@ -861,7 +865,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L865
     @check_new_auto_indent = false
   end
 
-  def retrieve_completion_block
+  def retrieve_completion_block(set_completion_quote_character = false)
     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)
@@ -880,14 +884,18 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L884
       if quote and slice.start_with?(closing_quote)
         quote = nil
         i += 1
+        rest = nil
+        break_pointer = nil
       elsif quote and slice.start_with?(escaped_quote)
         # skip
         i += 2
       elsif slice =~ quote_characters_regexp # find new "
+        rest = $'
         quote = $&
         closing_quote = /(?!\\)#{Regexp.escape(quote)}/
         escaped_quote = /\\#{Regexp.escape(quote)}/
         i += 1
+        break_pointer = i
       elsif not quote and slice =~ word_break_regexp
         rest = $'
         i += 1
@@ -896,14 +904,20 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L904
         i += 1
       end
     end
+    postposing = @line.byteslice(@byte_pointer, @line.bytesize - @byte_pointer)
     if rest
       preposing = @line.byteslice(0, break_pointer)
       target = rest
+      if set_completion_quote_character and quote
+        Reline.core.instance_variable_set(:@completion_quote_character, quote)
+        if postposing !~ /(?!\\)#{Regexp.escape(quote)}/ # closing quote
+          insert_text(quote)
+        end
+      end
     else
       preposing = ''
       target = before
     end
-    postposing = @line.byteslice(@byte_pointer, @line.bytesize - @byte_pointer)
     [preposing.encode(@encoding), target.encode(@encoding), postposing.encode(@encoding)]
   end
 
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]