mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Move I/O access from Reline::KeyStroke to Reline
This commit is contained in:
parent
7c776038ec
commit
c75a3356b3
2 changed files with 77 additions and 77 deletions
|
@ -22,6 +22,7 @@ module Reline
|
|||
CursorPos = Struct.new(:x, :y)
|
||||
|
||||
@@config = Reline::Config.new
|
||||
@@key_stroke = Reline::KeyStroke.new(@@config)
|
||||
@@line_editor = Reline::LineEditor.new(@@config)
|
||||
@@ambiguous_width = nil
|
||||
|
||||
|
@ -331,10 +332,9 @@ module Reline
|
|||
end
|
||||
end
|
||||
|
||||
key_stroke = Reline::KeyStroke.new(@@config)
|
||||
begin
|
||||
loop do
|
||||
key_stroke.read_io(@@config.keyseq_timeout) { |inputs|
|
||||
read_io(@@config.keyseq_timeout) { |inputs|
|
||||
inputs.each { |c|
|
||||
@@line_editor.input_key(c)
|
||||
@@line_editor.rerender
|
||||
|
@ -353,6 +353,79 @@ module Reline
|
|||
Reline::IOGate.deprep(otio)
|
||||
end
|
||||
|
||||
# Keystrokes of GNU Readline will timeout it with the specification of
|
||||
# "keyseq-timeout" when waiting for the 2nd character after the 1st one.
|
||||
# If the 2nd character comes after 1st ESC without timeout it has a
|
||||
# meta-property of meta-key to discriminate modified key with meta-key
|
||||
# from multibyte characters that come with 8th bit on.
|
||||
#
|
||||
# GNU Readline will wait for the 2nd character with "keyseq-timeout"
|
||||
# milli-seconds but wait forever after 3rd characters.
|
||||
def read_io(keyseq_timeout, &block)
|
||||
buffer = []
|
||||
loop do
|
||||
c = Reline::IOGate.getc
|
||||
buffer << c
|
||||
result = @@key_stroke.match_status(buffer)
|
||||
case result
|
||||
when :matched
|
||||
block.(@@key_stroke.expand(buffer).map{ |c| Reline::Key.new(c, c, false) })
|
||||
break
|
||||
when :matching
|
||||
if buffer.size == 1
|
||||
begin
|
||||
succ_c = nil
|
||||
Timeout.timeout(keyseq_timeout / 1000.0) {
|
||||
succ_c = Reline::IOGate.getc
|
||||
}
|
||||
rescue Timeout::Error # cancel matching only when first byte
|
||||
block.([Reline::Key.new(c, c, false)])
|
||||
break
|
||||
else
|
||||
if @@key_stroke.match_status(buffer.dup.push(succ_c)) == :unmatched
|
||||
if c == "\e".ord
|
||||
block.([Reline::Key.new(succ_c, succ_c | 0b10000000, true)])
|
||||
else
|
||||
block.([Reline::Key.new(c, c, false), Reline::Key.new(succ_c, succ_c, false)])
|
||||
end
|
||||
break
|
||||
else
|
||||
Reline::IOGate.ungetc(succ_c)
|
||||
end
|
||||
end
|
||||
end
|
||||
when :unmatched
|
||||
if buffer.size == 1 and c == "\e".ord
|
||||
read_escaped_key(keyseq_timeout, buffer, block)
|
||||
else
|
||||
block.(buffer.map{ |c| Reline::Key.new(c, c, false) })
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def read_escaped_key(keyseq_timeout, buffer, block)
|
||||
begin
|
||||
escaped_c = nil
|
||||
Timeout.timeout(keyseq_timeout / 1000.0) {
|
||||
escaped_c = Reline::IOGate.getc
|
||||
}
|
||||
rescue Timeout::Error # independent ESC
|
||||
block.([Reline::Key.new(c, c, false)])
|
||||
else
|
||||
if escaped_c.nil?
|
||||
block.([Reline::Key.new(c, c, false)])
|
||||
elsif escaped_c >= 128 # maybe, first byte of multi byte
|
||||
block.([Reline::Key.new(c, c, false), Reline::Key.new(escaped_c, escaped_c, false)])
|
||||
elsif escaped_c == "\e".ord # escape twice
|
||||
block.([Reline::Key.new(c, c, false), Reline::Key.new(c, c, false)])
|
||||
else
|
||||
block.([Reline::Key.new(escaped_c, escaped_c | 0b10000000, true)])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def may_req_ambiguous_char_width
|
||||
@@ambiguous_width = 2 if Reline::IOGate == Reline::GeneralIO or STDOUT.is_a?(File)
|
||||
return if @@ambiguous_width
|
||||
|
|
|
@ -15,79 +15,6 @@ class Reline::KeyStroke
|
|||
@config = config
|
||||
end
|
||||
|
||||
# Keystrokes of GNU Readline will timeout it with the specification of
|
||||
# "keyseq-timeout" when waiting for the 2nd character after the 1st one.
|
||||
# If the 2nd character comes after 1st ESC without timeout it has a
|
||||
# meta-property of meta-key to discriminate modified key with meta-key
|
||||
# from multibyte characters that come with 8th bit on.
|
||||
#
|
||||
# GNU Readline will wait for the 2nd character with "keyseq-timeout"
|
||||
# milli-seconds but wait forever after 3rd characters.
|
||||
def read_io(keyseq_timeout, &block)
|
||||
buffer = []
|
||||
loop do
|
||||
c = Reline::IOGate.getc
|
||||
buffer << c
|
||||
result = match_status(buffer)
|
||||
case result
|
||||
when :matched
|
||||
block.(expand(buffer).map{ |c| Reline::Key.new(c, c, false) })
|
||||
break
|
||||
when :matching
|
||||
if buffer.size == 1
|
||||
begin
|
||||
succ_c = nil
|
||||
Timeout.timeout(keyseq_timeout / 1000.0) {
|
||||
succ_c = Reline::IOGate.getc
|
||||
}
|
||||
rescue Timeout::Error # cancel matching only when first byte
|
||||
block.([Reline::Key.new(c, c, false)])
|
||||
break
|
||||
else
|
||||
if match_status(buffer.dup.push(succ_c)) == :unmatched
|
||||
if c == "\e".ord
|
||||
block.([Reline::Key.new(succ_c, succ_c | 0b10000000, true)])
|
||||
else
|
||||
block.([Reline::Key.new(c, c, false), Reline::Key.new(succ_c, succ_c, false)])
|
||||
end
|
||||
break
|
||||
else
|
||||
Reline::IOGate.ungetc(succ_c)
|
||||
end
|
||||
end
|
||||
end
|
||||
when :unmatched
|
||||
if buffer.size == 1 and c == "\e".ord
|
||||
read_escaped_key(keyseq_timeout, buffer, block)
|
||||
else
|
||||
block.(buffer.map{ |c| Reline::Key.new(c, c, false) })
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def read_escaped_key(keyseq_timeout, buffer, block)
|
||||
begin
|
||||
escaped_c = nil
|
||||
Timeout.timeout(keyseq_timeout / 1000.0) {
|
||||
escaped_c = Reline::IOGate.getc
|
||||
}
|
||||
rescue Timeout::Error # independent ESC
|
||||
block.([Reline::Key.new(c, c, false)])
|
||||
else
|
||||
if escaped_c.nil?
|
||||
block.([Reline::Key.new(c, c, false)])
|
||||
elsif escaped_c >= 128 # maybe, first byte of multi byte
|
||||
block.([Reline::Key.new(c, c, false), Reline::Key.new(escaped_c, escaped_c, false)])
|
||||
elsif escaped_c == "\e".ord # escape twice
|
||||
block.([Reline::Key.new(c, c, false), Reline::Key.new(c, c, false)])
|
||||
else
|
||||
block.([Reline::Key.new(escaped_c, escaped_c | 0b10000000, true)])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def match_status(input)
|
||||
key_mapping.keys.select { |lhs|
|
||||
lhs.start_with? input
|
||||
|
@ -104,8 +31,6 @@ class Reline::KeyStroke
|
|||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def expand(input)
|
||||
lhs = key_mapping.keys.select { |lhs| input.start_with? lhs }.sort_by(&:size).reverse.first
|
||||
return input unless lhs
|
||||
|
@ -120,6 +45,8 @@ class Reline::KeyStroke
|
|||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def key_mapping
|
||||
@config.key_bindings
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue