[ruby/reline] Support bracketed paste mode
https://github.com/ruby/reline/commit/d1a6869322
This commit is contained in:
parent
7624f52757
commit
c2bd5b84d0
@ -44,6 +44,7 @@ module Reline
|
||||
self.output = STDOUT
|
||||
yield self
|
||||
@completion_quote_character = nil
|
||||
@bracketed_paste_finished = false
|
||||
end
|
||||
|
||||
def encoding
|
||||
@ -243,6 +244,10 @@ module Reline
|
||||
line_editor.input_key(c)
|
||||
line_editor.rerender
|
||||
}
|
||||
if @bracketed_paste_finished
|
||||
line_editor.rerender_all
|
||||
@bracketed_paste_finished = false
|
||||
end
|
||||
}
|
||||
if prev_pasting_state == true and not Reline::IOGate.in_pasting? and not line_editor.finished?
|
||||
prev_pasting_state = false
|
||||
@ -275,8 +280,13 @@ module Reline
|
||||
buffer = []
|
||||
loop do
|
||||
c = Reline::IOGate.getc
|
||||
buffer << c
|
||||
result = key_stroke.match_status(buffer)
|
||||
if c == -1
|
||||
result = :unmatched
|
||||
@bracketed_paste_finished = true
|
||||
else
|
||||
buffer << c
|
||||
result = key_stroke.match_status(buffer)
|
||||
end
|
||||
case result
|
||||
when :matched
|
||||
expanded = key_stroke.expand(buffer).map{ |expanded_c|
|
||||
|
@ -1,4 +1,5 @@
|
||||
require 'io/console'
|
||||
require 'timeout'
|
||||
|
||||
class Reline::ANSI
|
||||
def self.encoding
|
||||
@ -67,7 +68,7 @@ class Reline::ANSI
|
||||
end
|
||||
|
||||
@@buf = []
|
||||
def self.getc
|
||||
def self.inner_getc
|
||||
unless @@buf.empty?
|
||||
return @@buf.shift
|
||||
end
|
||||
@ -80,8 +81,48 @@ class Reline::ANSI
|
||||
nil
|
||||
end
|
||||
|
||||
@@in_bracketed_paste_mode = false
|
||||
START_BRACKETED_PASTE = String.new("\e[200~,", encoding: Encoding::ASCII_8BIT)
|
||||
END_BRACKETED_PASTE = String.new("\e[200~.", encoding: Encoding::ASCII_8BIT)
|
||||
def self.getc_with_bracketed_paste
|
||||
buffer = String.new(encoding: Encoding::ASCII_8BIT)
|
||||
buffer << inner_getc
|
||||
while START_BRACKETED_PASTE.start_with?(buffer) or END_BRACKETED_PASTE.start_with?(buffer) do
|
||||
if START_BRACKETED_PASTE == buffer
|
||||
@@in_bracketed_paste_mode = true
|
||||
return inner_getc
|
||||
elsif END_BRACKETED_PASTE == buffer
|
||||
@@in_bracketed_paste_mode = false
|
||||
ungetc(-1)
|
||||
return inner_getc
|
||||
end
|
||||
begin
|
||||
succ_c = nil
|
||||
Timeout.timeout(Reline.core.config.keyseq_timeout * 100) {
|
||||
succ_c = inner_getc
|
||||
}
|
||||
rescue Timeout::Error
|
||||
break
|
||||
else
|
||||
buffer << succ_c
|
||||
end
|
||||
end
|
||||
buffer.bytes.reverse_each do |ch|
|
||||
ungetc ch
|
||||
end
|
||||
inner_getc
|
||||
end
|
||||
|
||||
def self.getc
|
||||
if Reline.core.config.enable_bracketed_paste
|
||||
getc_with_bracketed_paste
|
||||
else
|
||||
inner_getc
|
||||
end
|
||||
end
|
||||
|
||||
def self.in_pasting?
|
||||
not Reline::IOGate.empty_buffer?
|
||||
@@in_bracketed_paste_mode or (not Reline::IOGate.empty_buffer?)
|
||||
end
|
||||
|
||||
def self.empty_buffer?
|
||||
|
@ -37,6 +37,7 @@ class Reline::Config
|
||||
vi-cmd-mode-icon
|
||||
vi-ins-mode-icon
|
||||
emacs-mode-string
|
||||
enable-bracketed-paste
|
||||
}
|
||||
VARIABLE_NAME_SYMBOLS = VARIABLE_NAMES.map { |v| :"#{v.tr(?-, ?_)}" }
|
||||
VARIABLE_NAME_SYMBOLS.each do |v|
|
||||
|
@ -423,6 +423,24 @@ begin
|
||||
EOC
|
||||
end
|
||||
|
||||
def test_enable_bracketed_paste
|
||||
write_inputrc <<~LINES
|
||||
set enable-bracketed-paste on
|
||||
LINES
|
||||
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl}, startup_message: 'Multiline REPL.')
|
||||
write("\e[200~,")
|
||||
write("def hoge\n 3\nend\n")
|
||||
write("\e[200~.")
|
||||
close
|
||||
assert_screen(<<~EOC)
|
||||
prompt> def hoge
|
||||
prompt> 3
|
||||
prompt> end
|
||||
=> :hoge
|
||||
prompt>
|
||||
EOC
|
||||
end
|
||||
|
||||
private def write_inputrc(content)
|
||||
File.open(@inputrc_file, 'w') do |f|
|
||||
f.write content
|
||||
|
Loading…
x
Reference in New Issue
Block a user