summaryrefslogtreecommitdiff
path: root/lib/reline/key_stroke.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/reline/key_stroke.rb')
-rw-r--r--lib/reline/key_stroke.rb77
1 files changed, 2 insertions, 75 deletions
diff --git a/lib/reline/key_stroke.rb b/lib/reline/key_stroke.rb
index 08c00625ba..2f5415ef7e 100644
--- a/lib/reline/key_stroke.rb
+++ b/lib/reline/key_stroke.rb
@@ -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