summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraycabta <aycabta@gmail.com>2019-05-24 23:38:40 +0900
committeraycabta <aycabta@gmail.com>2019-05-24 23:38:40 +0900
commiteb4e774711b17b8a25a7b16c4f0b6044da3dc261 (patch)
treed33f0bfb2087ee0169422d08b8553678fd189f75
parent2d34087a38ac680c5576a56fbf4104c3561b0204 (diff)
Support Meta key in Reline
-rw-r--r--lib/reline.rb6
-rw-r--r--lib/reline/ansi.rb8
-rw-r--r--lib/reline/config.rb4
-rw-r--r--lib/reline/general_io.rb7
-rw-r--r--lib/reline/key_actor/emacs.rb4
-rw-r--r--lib/reline/key_actor/vi_insert.rb256
-rw-r--r--lib/reline/key_stroke.rb89
-rw-r--r--lib/reline/line_editor.rb67
-rw-r--r--lib/reline/windows.rb4
-rw-r--r--test/reline/helper.rb8
-rw-r--r--test/reline/test_key_stroke.rb46
11 files changed, 282 insertions, 217 deletions
diff --git a/lib/reline.rb b/lib/reline.rb
index ac279b43f0..41f492d50c 100644
--- a/lib/reline.rb
+++ b/lib/reline.rb
@@ -1,4 +1,5 @@
require 'io/console'
+require 'timeout'
require 'reline/version'
require 'reline/config'
require 'reline/key_actor'
@@ -6,6 +7,8 @@ require 'reline/key_stroke'
require 'reline/line_editor'
module Reline
+ Key = Struct.new('Key', :char, :combined_char, :with_meta)
+
extend self
FILENAME_COMPLETION_PROC = nil
USERNAME_COMPLETION_PROC = nil
@@ -321,8 +324,7 @@ module Reline
key_stroke = Reline::KeyStroke.new(config)
begin
loop do
- c = Reline::IOGate.getc
- key_stroke.input_to!(c)&.then { |inputs|
+ key_stroke.read_io(@@config.keyseq_timeout) { |inputs|
inputs.each { |c|
@@line_editor.input_key(c)
@@line_editor.rerender
diff --git a/lib/reline/ansi.rb b/lib/reline/ansi.rb
index 34720d352c..1ead89b8ff 100644
--- a/lib/reline/ansi.rb
+++ b/lib/reline/ansi.rb
@@ -9,7 +9,11 @@ class Reline::ANSI
@@output = val
end
+ @@buf = []
def self.getc
+ unless @@buf.empty?
+ return @@buf.shift
+ end
c = nil
loop do
result = select([@@input], [], [], 0.1)
@@ -20,6 +24,10 @@ class Reline::ANSI
c&.ord
end
+ def self.ungetc(c)
+ @@buf.unshift(c)
+ end
+
def self.get_screen_size
@@input.winsize
rescue Errno::ENOTTY
diff --git a/lib/reline/config.rb b/lib/reline/config.rb
index cf46eda5ea..120a95a6fa 100644
--- a/lib/reline/config.rb
+++ b/lib/reline/config.rb
@@ -16,6 +16,7 @@ class Reline::Config
history-size
horizontal-scroll-mode
input-meta
+ keyseq-timeout
mark-directories
mark-modified-lines
mark-symlinked-directories
@@ -44,6 +45,7 @@ class Reline::Config
@key_actors[:vi_insert] = Reline::KeyActor::ViInsert.new
@key_actors[:vi_command] = Reline::KeyActor::ViCommand.new
@history_size = 500
+ @keyseq_timeout = 500
end
def reset
@@ -178,6 +180,8 @@ class Reline::Config
when 'vi-insert'
@keymap_label = :vi_insert
end
+ when 'keyseq-timeout'
+ @keyseq_timeout = value.to_i
end
end
diff --git a/lib/reline/general_io.rb b/lib/reline/general_io.rb
index 0ea31b972b..526c780084 100644
--- a/lib/reline/general_io.rb
+++ b/lib/reline/general_io.rb
@@ -8,6 +8,9 @@ class Reline::GeneralIO
end
def self.getc
+ unless @@buf.empty?
+ return @@buf.shift
+ end
c = nil
loop do
result = select([@@input], [], [], 0.1)
@@ -18,6 +21,10 @@ class Reline::GeneralIO
c&.ord
end
+ def self.ungetc(c)
+ @@buf.unshift(c)
+ end
+
def self.get_screen_size
[1, 1]
end
diff --git a/lib/reline/key_actor/emacs.rb b/lib/reline/key_actor/emacs.rb
index 5dac1ab12b..5a847169c4 100644
--- a/lib/reline/key_actor/emacs.rb
+++ b/lib/reline/key_actor/emacs.rb
@@ -277,13 +277,13 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
# 137 M-^I
:ed_unassigned,
# 138 M-^J
- :ed_unassigned,
+ :key_newline,
# 139 M-^K
:ed_unassigned,
# 140 M-^L
:ed_clear_screen,
# 141 M-^M
- :ed_unassigned,
+ :key_newline,
# 142 M-^N
:ed_unassigned,
# 143 M-^O
diff --git a/lib/reline/key_actor/vi_insert.rb b/lib/reline/key_actor/vi_insert.rb
index 8585a642ab..0301e5d20d 100644
--- a/lib/reline/key_actor/vi_insert.rb
+++ b/lib/reline/key_actor/vi_insert.rb
@@ -257,261 +257,261 @@ class Reline::KeyActor::ViInsert < Reline::KeyActor::Base
# 127 ^?
:vi_delete_prev_char,
# 128 M-^@
- :ed_insert,
+ :ed_unassigned,
# 129 M-^A
- :ed_insert,
+ :ed_unassigned,
# 130 M-^B
- :ed_insert,
+ :ed_unassigned,
# 131 M-^C
- :ed_insert,
+ :ed_unassigned,
# 132 M-^D
- :ed_insert,
+ :ed_unassigned,
# 133 M-^E
- :ed_insert,
+ :ed_unassigned,
# 134 M-^F
- :ed_insert,
+ :ed_unassigned,
# 135 M-^G
- :ed_insert,
+ :ed_unassigned,
# 136 M-^H
- :ed_insert,
+ :ed_unassigned,
# 137 M-^I
- :ed_insert,
+ :ed_unassigned,
# 138 M-^J
- :ed_insert,
+ :key_newline,
# 139 M-^K
- :ed_insert,
+ :ed_unassigned,
# 140 M-^L
- :ed_insert,
+ :ed_unassigned,
# 141 M-^M
- :ed_insert,
+ :key_newline,
# 142 M-^N
- :ed_insert,
+ :ed_unassigned,
# 143 M-^O
- :ed_insert,
+ :ed_unassigned,
# 144 M-^P
- :ed_insert,
+ :ed_unassigned,
# 145 M-^Q
- :ed_insert,
+ :ed_unassigned,
# 146 M-^R
- :ed_insert,
+ :ed_unassigned,
# 147 M-^S
- :ed_insert,
+ :ed_unassigned,
# 148 M-^T
- :ed_insert,
+ :ed_unassigned,
# 149 M-^U
- :ed_insert,
+ :ed_unassigned,
# 150 M-^V
- :ed_insert,
+ :ed_unassigned,
# 151 M-^W
- :ed_insert,
+ :ed_unassigned,
# 152 M-^X
- :ed_insert,
+ :ed_unassigned,
# 153 M-^Y
- :ed_insert,
+ :ed_unassigned,
# 154 M-^Z
- :ed_insert,
+ :ed_unassigned,
# 155 M-^[
- :ed_insert,
+ :ed_unassigned,
# 156 M-^\
- :ed_insert,
+ :ed_unassigned,
# 157 M-^]
- :ed_insert,
+ :ed_unassigned,
# 158 M-^^
- :ed_insert,
+ :ed_unassigned,
# 159 M-^_
- :ed_insert,
+ :ed_unassigned,
# 160 M-SPACE
- :ed_insert,
+ :ed_unassigned,
# 161 M-!
- :ed_insert,
+ :ed_unassigned,
# 162 M-"
- :ed_insert,
+ :ed_unassigned,
# 163 M-#
- :ed_insert,
+ :ed_unassigned,
# 164 M-$
- :ed_insert,
+ :ed_unassigned,
# 165 M-%
- :ed_insert,
+ :ed_unassigned,
# 166 M-&
- :ed_insert,
+ :ed_unassigned,
# 167 M-'
- :ed_insert,
+ :ed_unassigned,
# 168 M-(
- :ed_insert,
+ :ed_unassigned,
# 169 M-)
- :ed_insert,
+ :ed_unassigned,
# 170 M-*
- :ed_insert,
+ :ed_unassigned,
# 171 M-+
- :ed_insert,
+ :ed_unassigned,
# 172 M-,
- :ed_insert,
+ :ed_unassigned,
# 173 M--
- :ed_insert,
+ :ed_unassigned,
# 174 M-.
- :ed_insert,
+ :ed_unassigned,
# 175 M-/
- :ed_insert,
+ :ed_unassigned,
# 176 M-0
- :ed_insert,
+ :ed_unassigned,
# 177 M-1
- :ed_insert,
+ :ed_unassigned,
# 178 M-2
- :ed_insert,
+ :ed_unassigned,
# 179 M-3
- :ed_insert,
+ :ed_unassigned,
# 180 M-4
- :ed_insert,
+ :ed_unassigned,
# 181 M-5
- :ed_insert,
+ :ed_unassigned,
# 182 M-6
- :ed_insert,
+ :ed_unassigned,
# 183 M-7
- :ed_insert,
+ :ed_unassigned,
# 184 M-8
- :ed_insert,
+ :ed_unassigned,
# 185 M-9
- :ed_insert,
+ :ed_unassigned,
# 186 M-:
- :ed_insert,
+ :ed_unassigned,
# 187 M-;
- :ed_insert,
+ :ed_unassigned,
# 188 M-<
- :ed_insert,
+ :ed_unassigned,
# 189 M-=
- :ed_insert,
+ :ed_unassigned,
# 190 M->
- :ed_insert,
+ :ed_unassigned,
# 191 M-?
- :ed_insert,
+ :ed_unassigned,
# 192 M-@
- :ed_insert,
+ :ed_unassigned,
# 193 M-A
- :ed_insert,
+ :ed_unassigned,
# 194 M-B
- :ed_insert,
+ :ed_unassigned,
# 195 M-C
- :ed_insert,
+ :ed_unassigned,
# 196 M-D
- :ed_insert,
+ :ed_unassigned,
# 197 M-E
- :ed_insert,
+ :ed_unassigned,
# 198 M-F
- :ed_insert,
+ :ed_unassigned,
# 199 M-G
- :ed_insert,
+ :ed_unassigned,
# 200 M-H
- :ed_insert,
+ :ed_unassigned,
# 201 M-I
- :ed_insert,
+ :ed_unassigned,
# 202 M-J
- :ed_insert,
+ :ed_unassigned,
# 203 M-K
- :ed_insert,
+ :ed_unassigned,
# 204 M-L
- :ed_insert,
+ :ed_unassigned,
# 205 M-M
- :ed_insert,
+ :ed_unassigned,
# 206 M-N
- :ed_insert,
+ :ed_unassigned,
# 207 M-O
- :ed_insert,
+ :ed_unassigned,
# 208 M-P
- :ed_insert,
+ :ed_unassigned,
# 209 M-Q
- :ed_insert,
+ :ed_unassigned,
# 210 M-R
- :ed_insert,
+ :ed_unassigned,
# 211 M-S
- :ed_insert,
+ :ed_unassigned,
# 212 M-T
- :ed_insert,
+ :ed_unassigned,
# 213 M-U
- :ed_insert,
+ :ed_unassigned,
# 214 M-V
- :ed_insert,
+ :ed_unassigned,
# 215 M-W
- :ed_insert,
+ :ed_unassigned,
# 216 M-X
- :ed_insert,
+ :ed_unassigned,
# 217 M-Y
- :ed_insert,
+ :ed_unassigned,
# 218 M-Z
- :ed_insert,
+ :ed_unassigned,
# 219 M-[
- :ed_insert,
+ :ed_unassigned,
# 220 M-\
- :ed_insert,
+ :ed_unassigned,
# 221 M-]
- :ed_insert,
+ :ed_unassigned,
# 222 M-^
- :ed_insert,
+ :ed_unassigned,
# 223 M-_
- :ed_insert,
+ :ed_unassigned,
# 223 M-`
- :ed_insert,
+ :ed_unassigned,
# 224 M-a
- :ed_insert,
+ :ed_unassigned,
# 225 M-b
- :ed_insert,
+ :ed_unassigned,
# 226 M-c
- :ed_insert,
+ :ed_unassigned,
# 227 M-d
- :ed_insert,
+ :ed_unassigned,
# 228 M-e
- :ed_insert,
+ :ed_unassigned,
# 229 M-f
- :ed_insert,
+ :ed_unassigned,
# 230 M-g
- :ed_insert,
+ :ed_unassigned,
# 231 M-h
- :ed_insert,
+ :ed_unassigned,
# 232 M-i
- :ed_insert,
+ :ed_unassigned,
# 233 M-j
- :ed_insert,
+ :ed_unassigned,
# 234 M-k
- :ed_insert,
+ :ed_unassigned,
# 235 M-l
- :ed_insert,
+ :ed_unassigned,
# 236 M-m
- :ed_insert,
+ :ed_unassigned,
# 237 M-n
- :ed_insert,
+ :ed_unassigned,
# 238 M-o
- :ed_insert,
+ :ed_unassigned,
# 239 M-p
- :ed_insert,
+ :ed_unassigned,
# 240 M-q
- :ed_insert,
+ :ed_unassigned,
# 241 M-r
- :ed_insert,
+ :ed_unassigned,
# 242 M-s
- :ed_insert,
+ :ed_unassigned,
# 243 M-t
- :ed_insert,
+ :ed_unassigned,
# 244 M-u
- :ed_insert,
+ :ed_unassigned,
# 245 M-v
- :ed_insert,
+ :ed_unassigned,
# 246 M-w
- :ed_insert,
+ :ed_unassigned,
# 247 M-x
- :ed_insert,
+ :ed_unassigned,
# 248 M-y
- :ed_insert,
+ :ed_unassigned,
# 249 M-z
- :ed_insert,
+ :ed_unassigned,
# 250 M-{
- :ed_insert,
+ :ed_unassigned,
# 251 M-|
- :ed_insert,
+ :ed_unassigned,
# 252 M-}
- :ed_insert,
+ :ed_unassigned,
# 253 M-~
- :ed_insert,
+ :ed_unassigned,
# 254 M-^?
- :ed_insert
+ :ed_unassigned
# 255
# EOF
]
diff --git a/lib/reline/key_stroke.rb b/lib/reline/key_stroke.rb
index fdfe74a6ee..d09abd9058 100644
--- a/lib/reline/key_stroke.rb
+++ b/lib/reline/key_stroke.rb
@@ -13,30 +13,81 @@ class Reline::KeyStroke
def initialize(config)
@config = config
- @buffer = []
end
- def input_to(bytes)
- case match_status(bytes)
- when :matching
- nil
- when :matched
- expand(bytes)
- when :unmatched
- bytes
+ # 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(bytes).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(buffer, block)
+ else
+ block.(buffer.map{ |c| Reline::Key.new(c, c, false) })
+ end
+ break
+ end
end
end
- def input_to!(bytes)
- if bytes.nil?
- return @buffer.push(nil)&.tap { clear }
+ def read_escaped_key(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
- @buffer.concat Array(bytes)
- input_to(@buffer)&.tap { clear }
end
- private
-
def match_status(input)
key_mapping.keys.select { |lhs|
lhs.start_with? input
@@ -53,6 +104,8 @@ 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
@@ -70,8 +123,4 @@ class Reline::KeyStroke
def key_mapping
@config[:key_mapping].transform_keys(&:bytes)
end
-
- def clear
- @buffer = []
- end
end
diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
index 92f75c7b88..764176c167 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -104,7 +104,6 @@ class Reline::LineEditor
@kill_ring = Reline::KillRing.new
@vi_clipboard = ''
@vi_arg = nil
- @meta_prefix = false
@waiting_proc = nil
@waiting_operator_proc = nil
@completion_journey_data = nil
@@ -625,31 +624,38 @@ class Reline::LineEditor
private def normal_char(key)
method_symbol = method_obj = nil
- @multibyte_buffer << key
+ @multibyte_buffer << key.combined_char
if @multibyte_buffer.size > 1
if @multibyte_buffer.dup.force_encoding(@encoding).valid_encoding?
- key = @multibyte_buffer.dup.force_encoding(@encoding)
+ process_key(@multibyte_buffer.dup.force_encoding(@encoding), nil, nil)
@multibyte_buffer.clear
else
# invalid
return
end
else # single byte
- return if key >= 128 # maybe, first byte of multi byte
- if @meta_prefix
- key |= 0b10000000 if key.nobits?(0b10000000)
- @meta_prefix = false
- end
- method_symbol = @config.editing_mode.get_method(key)
- if key.allbits?(0b10000000) and method_symbol == :ed_unassigned
- return # This is unknown input
- end
- if method_symbol and respond_to?(method_symbol, true)
- method_obj = method(method_symbol)
+ return if key.char >= 128 # maybe, first byte of multi byte
+ method_symbol = @config.editing_mode.get_method(key.combined_char)
+ if key.with_meta and method_symbol == :ed_unassigned
+ # split ESC + key
+ method_symbol = @config.editing_mode.get_method("\e".ord)
+ if method_symbol and respond_to?(method_symbol, true)
+ method_obj = method(method_symbol)
+ end
+ process_key("\e".ord, method_symbol, method_obj)
+ method_symbol = @config.editing_mode.get_method(key.char)
+ if method_symbol and respond_to?(method_symbol, true)
+ method_obj = method(method_symbol)
+ end
+ process_key(key.char, method_symbol, method_obj)
+ else
+ if method_symbol and respond_to?(method_symbol, true)
+ method_obj = method(method_symbol)
+ end
+ process_key(key.combined_char, method_symbol, method_obj)
end
@multibyte_buffer.clear
end
- process_key(key, method_symbol, method_obj)
if @config.editing_mode_is?(:vi_command) and @cursor > 0 and @cursor == @cursor_max
byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
@byte_pointer -= byte_size
@@ -660,7 +666,7 @@ class Reline::LineEditor
end
def input_key(key)
- if key.nil?
+ if key.nil? or key.char.nil?
if @first_char
@line = nil
end
@@ -669,30 +675,20 @@ class Reline::LineEditor
end
@first_char = false
completion_occurs = false
- if @config.editing_mode_is?(:emacs, :vi_insert) and key == "\C-i".ord
+ if @config.editing_mode_is?(:emacs, :vi_insert) and key.char == "\C-i".ord
result = @completion_proc&.(@line)
if result.is_a?(Array)
completion_occurs = true
complete(result)
end
- elsif @config.editing_mode_is?(:vi_insert) and ["\C-p".ord, "\C-n".ord].include?(key)
+ elsif @config.editing_mode_is?(:vi_insert) and ["\C-p".ord, "\C-n".ord].include?(key.char)
result = @completion_proc&.(@line)
if result.is_a?(Array)
completion_occurs = true
- move_completed_list(result, "\C-p".ord == key ? :up : :down)
- end
- elsif @config.editing_mode_is?(:emacs) and key == "\e".ord # meta key
- if @meta_prefix
- # escape twice
- @meta_prefix = false
- @kill_ring.process
- else
- @meta_prefix = true
+ move_completed_list(result, "\C-p".ord == key.char ? :up : :down)
end
- elsif @config.editing_mode_is?(:vi_command) and key == "\e".ord
- # suppress ^[ when command_mode
- elsif Symbol === key and respond_to?(key, true)
- process_key(key, key, method(key))
+ elsif Symbol === key.char and respond_to?(key.char, true)
+ process_key(key.char, key.char, method(key.char))
else
normal_char(key)
end
@@ -823,6 +819,15 @@ class Reline::LineEditor
end
end
+ private def key_newline(key)
+ if @is_multiline
+ next_line = @line.byteslice(@byte_pointer, @line.bytesize - @byte_pointer)
+ cursor_line = @line.byteslice(0, @byte_pointer)
+ insert_new_line(cursor_line, next_line)
+ @cursor = 0
+ end
+ end
+
private def ed_insert(key)
if key.instance_of?(String)
width = Reline::Unicode.get_mbchar_width(key)
diff --git a/lib/reline/windows.rb b/lib/reline/windows.rb
index 2e7ed89ff9..842760e5bd 100644
--- a/lib/reline/windows.rb
+++ b/lib/reline/windows.rb
@@ -101,6 +101,10 @@ class Reline::Windows
end
end
+ def self.ungetc(c)
+ @@buf.unshift(c)
+ end
+
def self.get_screen_size
csbi = 0.chr * 24
@@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi)
diff --git a/test/reline/helper.rb b/test/reline/helper.rb
index 227fc0689a..e6587b30f6 100644
--- a/test/reline/helper.rb
+++ b/test/reline/helper.rb
@@ -40,13 +40,13 @@ class Reline::TestCase < Test::Unit::TestCase
eighth_bit = 0b10000000
byte = c.bytes.first
if byte.allbits?(eighth_bit)
- @line_editor.input_key("\e".ord)
- byte ^= eighth_bit
+ @line_editor.input_key(Reline::Key.new(byte ^ eighth_bit, byte, true))
+ else
+ @line_editor.input_key(Reline::Key.new(byte, byte, false))
end
- @line_editor.input_key(byte)
else
c.bytes.each do |b|
- @line_editor.input_key(b)
+ @line_editor.input_key(Reline::Key.new(b, b, false))
end
end
end
diff --git a/test/reline/test_key_stroke.rb b/test/reline/test_key_stroke.rb
index b6d5ce4150..e76129d04b 100644
--- a/test/reline/test_key_stroke.rb
+++ b/test/reline/test_key_stroke.rb
@@ -4,30 +4,16 @@ class Reline::KeyStroke::Test < Reline::TestCase
using Module.new {
refine Array do
def as_s
- map(&:chr).join
+ join
+ end
+
+ def to_keys
+ map{ |b| Reline::Key.new(b, b, false) }
end
end
}
- def test_input_to!
- config = {
- key_mapping: {
- "a" => "xx",
- "ab" => "y",
- "abc" => "z",
- "x" => "rr"
- }
- }
- stroke = Reline::KeyStroke.new(config)
- result = ("abzwabk".bytes).map { |char|
- stroke.input_to!(char)&.then { |result|
- "#{result.as_s}"
- }
- }
- assert_equal(result, [nil, nil, "yz", "w", nil, nil, "yk"])
- end
-
- def test_input_to
+ def test_match_status
config = {
key_mapping: {
"a" => "xx",
@@ -37,15 +23,15 @@ class Reline::KeyStroke::Test < Reline::TestCase
}
}
stroke = Reline::KeyStroke.new(config)
- assert_equal(stroke.input_to("a".bytes)&.as_s, nil)
- assert_equal(stroke.input_to("ab".bytes)&.as_s, nil)
- assert_equal(stroke.input_to("abc".bytes)&.as_s, "z")
- assert_equal(stroke.input_to("abz".bytes)&.as_s, "yz")
- assert_equal(stroke.input_to("abx".bytes)&.as_s, "yrr")
- assert_equal(stroke.input_to("ac".bytes)&.as_s, "rrrrc")
- assert_equal(stroke.input_to("aa".bytes)&.as_s, "rrrrrrrr")
- assert_equal(stroke.input_to("x".bytes)&.as_s, "rr")
- assert_equal(stroke.input_to("m".bytes)&.as_s, "m")
- assert_equal(stroke.input_to("abzwabk".bytes)&.as_s, "yzwabk")
+ assert_equal(:matching, stroke.match_status("a".bytes))
+ assert_equal(:matching, stroke.match_status("ab".bytes))
+ assert_equal(:matched, stroke.match_status("abc".bytes))
+ assert_equal(:matched, stroke.match_status("abz".bytes))
+ assert_equal(:matched, stroke.match_status("abx".bytes))
+ assert_equal(:matched, stroke.match_status("ac".bytes))
+ assert_equal(:matched, stroke.match_status("aa".bytes))
+ assert_equal(:matched, stroke.match_status("x".bytes))
+ assert_equal(:unmatched, stroke.match_status("m".bytes))
+ assert_equal(:matched, stroke.match_status("abzwabk".bytes))
end
end