Skip to content

Commit

Permalink
Combine MAPPINGS(single byte input to symbol) with key_bindings(escap…
Browse files Browse the repository at this point in the history
…e sequence to symbol)
  • Loading branch information
tompng committed Nov 26, 2024
1 parent 5a8da85 commit 700e4ef
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 194 deletions.
8 changes: 5 additions & 3 deletions lib/reline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ module Reline

class ConfigEncodingConversionError < StandardError; end

Key = Struct.new(:char, :combined_char, :with_meta) do
# EOF key: { char: nil, method_symbol: nil }
# Other key: { char: String, method_symbol: Symbol }
Key = Struct.new(:char, :method_symbol, :unused_boolean) do
# For dialog_proc `key.match?(dialog.name)`
def match?(sym)
combined_char.is_a?(Symbol) && combined_char == sym
method_symbol && method_symbol == sym
end
end
CursorPos = Struct.new(:x, :y)
Expand Down Expand Up @@ -344,7 +346,7 @@ def readline(prompt = '', add_hist = false)
read_io(config.keyseq_timeout) { |inputs|
line_editor.set_pasting_state(io_gate.in_pasting?)
inputs.each do |key|
if key.char == :bracketed_paste_start
if key.method_symbol == :bracketed_paste_start
text = io_gate.read_bracketed_paste
line_editor.insert_multiline_text(text)
line_editor.scroll_into_view
Expand Down
14 changes: 10 additions & 4 deletions lib/reline/key_actor/base.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
class Reline::KeyActor::Base
def initialize(mapping = [])
@mapping = mapping
def initialize(mappings = nil)
@matching_bytes = {}
@key_bindings = {}
add_mappings(mappings) if mappings
end

def get_method(key)
@mapping[key]
def add_mappings(mappings)
add([27], :ed_ignore)
128.times do |key|
func = mappings[key]
meta_func = mappings[key | 0b10000000]
add([key], func) unless func == :ed_unassigned
add([27, key], meta_func) unless meta_func == :ed_unassigned
end
end

def add(key, func)
Expand Down
21 changes: 10 additions & 11 deletions lib/reline/key_stroke.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ def initialize(config, encoding)
def match_status(input)
matching = key_mapping.matching?(input)
matched = key_mapping.get(input)

# FIXME: Workaround for single byte. remove this after MAPPING is merged into KeyActor.
matched ||= input.size == 1 && input[0] < 0x80
matching ||= input == [ESC_BYTE]

if matching && matched
MATCHING_MATCHED
elsif matching
Expand Down Expand Up @@ -57,16 +52,20 @@ def expand(input)
return [[], []] unless matched_bytes

func = key_mapping.get(matched_bytes)
s = matched_bytes.pack('c*').force_encoding(@encoding)
if func.is_a?(Array)
keys = func.map { |c| Reline::Key.new(c, c, false) }
# Perform simple macro expansion for single byte key bindings.
# Multibyte key bindings and recursive macro expansion are not supported yet.
marco = func.pack('c*').force_encoding(@encoding)
keys = marco.chars.map do |c|
f = key_mapping.get(c.bytes)
Reline::Key.new(c, f.is_a?(Symbol) ? f : :ed_insert, false)
end
elsif func
keys = [Reline::Key.new(func, func, false)]
elsif matched_bytes.size == 2 && matched_bytes[0] == ESC_BYTE
keys = [Reline::Key.new(matched_bytes[1], matched_bytes[1] | 0b10000000, true)]
keys = [Reline::Key.new(s, func, false)]
else
s = matched_bytes.pack('c*').force_encoding(@encoding)
if s.valid_encoding? && s.size == 1
keys = [Reline::Key.new(s.ord, s.ord, false)]
keys = [Reline::Key.new(s, :ed_insert, false)]
else
keys = []
end
Expand Down
Loading

0 comments on commit 700e4ef

Please sign in to comment.