mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Support Readline.completion_quote_character by Reline
This commit is contained in:
parent
8e49ef5a69
commit
ec54ac9381
2 changed files with 28 additions and 8 deletions
|
@ -42,6 +42,7 @@ module Reline
|
||||||
def initialize
|
def initialize
|
||||||
self.output = STDOUT
|
self.output = STDOUT
|
||||||
yield self
|
yield self
|
||||||
|
@completion_quote_character = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def completion_append_character=(val)
|
def completion_append_character=(val)
|
||||||
|
@ -88,6 +89,10 @@ module Reline
|
||||||
@config.completion_ignore_case
|
@config.completion_ignore_case
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def completion_quote_character
|
||||||
|
@completion_quote_character
|
||||||
|
end
|
||||||
|
|
||||||
def completion_proc=(p)
|
def completion_proc=(p)
|
||||||
raise ArgumentError unless p.respond_to?(:call)
|
raise ArgumentError unless p.respond_to?(:call)
|
||||||
@completion_proc = p
|
@completion_proc = p
|
||||||
|
@ -347,6 +352,7 @@ module Reline
|
||||||
def_single_delegators :core, :vi_editing_mode, :emacs_editing_mode
|
def_single_delegators :core, :vi_editing_mode, :emacs_editing_mode
|
||||||
def_single_delegators :core, :readline
|
def_single_delegators :core, :readline
|
||||||
def_single_delegators :core, :completion_case_fold, :completion_case_fold=
|
def_single_delegators :core, :completion_case_fold, :completion_case_fold=
|
||||||
|
def_single_delegators :core, :completion_quote_character
|
||||||
def_instance_delegators self, :readline
|
def_instance_delegators self, :readline
|
||||||
private :readline
|
private :readline
|
||||||
|
|
||||||
|
|
|
@ -789,9 +789,7 @@ class Reline::LineEditor
|
||||||
completion_occurs = false
|
completion_occurs = false
|
||||||
if @config.editing_mode_is?(:emacs, :vi_insert) and key.char == "\C-i".ord
|
if @config.editing_mode_is?(:emacs, :vi_insert) and key.char == "\C-i".ord
|
||||||
unless @config.disable_completion
|
unless @config.disable_completion
|
||||||
result = retrieve_completion_block
|
result = call_completion_proc
|
||||||
slice = result[1]
|
|
||||||
result = @completion_proc.(slice) if @completion_proc and slice
|
|
||||||
if result.is_a?(Array)
|
if result.is_a?(Array)
|
||||||
completion_occurs = true
|
completion_occurs = true
|
||||||
complete(result)
|
complete(result)
|
||||||
|
@ -799,9 +797,7 @@ class Reline::LineEditor
|
||||||
end
|
end
|
||||||
elsif not @config.disable_completion and @config.editing_mode_is?(:vi_insert) and ["\C-p".ord, "\C-n".ord].include?(key.char)
|
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
|
unless @config.disable_completion
|
||||||
result = retrieve_completion_block
|
result = call_completion_proc
|
||||||
slice = result[1]
|
|
||||||
result = @completion_proc.(slice) if @completion_proc and slice
|
|
||||||
if result.is_a?(Array)
|
if result.is_a?(Array)
|
||||||
completion_occurs = true
|
completion_occurs = true
|
||||||
move_completed_list(result, "\C-p".ord == key.char ? :up : :down)
|
move_completed_list(result, "\C-p".ord == key.char ? :up : :down)
|
||||||
|
@ -820,6 +816,14 @@ class Reline::LineEditor
|
||||||
end
|
end
|
||||||
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
|
private def process_auto_indent
|
||||||
return if not @check_new_auto_indent and @previous_line_index # move cursor up or down
|
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
|
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
|
||||||
@check_new_auto_indent = false
|
@check_new_auto_indent = false
|
||||||
end
|
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)}]/
|
word_break_regexp = /\A[#{Regexp.escape(Reline.completer_word_break_characters)}]/
|
||||||
quote_characters_regexp = /\A[#{Regexp.escape(Reline.completer_quote_characters)}]/
|
quote_characters_regexp = /\A[#{Regexp.escape(Reline.completer_quote_characters)}]/
|
||||||
before = @line.byteslice(0, @byte_pointer)
|
before = @line.byteslice(0, @byte_pointer)
|
||||||
|
@ -880,14 +884,18 @@ class Reline::LineEditor
|
||||||
if quote and slice.start_with?(closing_quote)
|
if quote and slice.start_with?(closing_quote)
|
||||||
quote = nil
|
quote = nil
|
||||||
i += 1
|
i += 1
|
||||||
|
rest = nil
|
||||||
|
break_pointer = nil
|
||||||
elsif quote and slice.start_with?(escaped_quote)
|
elsif quote and slice.start_with?(escaped_quote)
|
||||||
# skip
|
# skip
|
||||||
i += 2
|
i += 2
|
||||||
elsif slice =~ quote_characters_regexp # find new "
|
elsif slice =~ quote_characters_regexp # find new "
|
||||||
|
rest = $'
|
||||||
quote = $&
|
quote = $&
|
||||||
closing_quote = /(?!\\)#{Regexp.escape(quote)}/
|
closing_quote = /(?!\\)#{Regexp.escape(quote)}/
|
||||||
escaped_quote = /\\#{Regexp.escape(quote)}/
|
escaped_quote = /\\#{Regexp.escape(quote)}/
|
||||||
i += 1
|
i += 1
|
||||||
|
break_pointer = i
|
||||||
elsif not quote and slice =~ word_break_regexp
|
elsif not quote and slice =~ word_break_regexp
|
||||||
rest = $'
|
rest = $'
|
||||||
i += 1
|
i += 1
|
||||||
|
@ -896,14 +904,20 @@ class Reline::LineEditor
|
||||||
i += 1
|
i += 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
postposing = @line.byteslice(@byte_pointer, @line.bytesize - @byte_pointer)
|
||||||
if rest
|
if rest
|
||||||
preposing = @line.byteslice(0, break_pointer)
|
preposing = @line.byteslice(0, break_pointer)
|
||||||
target = rest
|
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
|
else
|
||||||
preposing = ''
|
preposing = ''
|
||||||
target = before
|
target = before
|
||||||
end
|
end
|
||||||
postposing = @line.byteslice(@byte_pointer, @line.bytesize - @byte_pointer)
|
|
||||||
[preposing.encode(@encoding), target.encode(@encoding), postposing.encode(@encoding)]
|
[preposing.encode(@encoding), target.encode(@encoding), postposing.encode(@encoding)]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue