class Reline::KeyStroke

Constants

CSI_INTERMEDIATE_BYTES_RANGE
CSI_PARAMETER_BYTES_RANGE
ESC_BYTE
MATCHED

Input partially matches to a key sequence

MATCHING

Input exactly matches to a key sequence

MATCHING_MATCHED

Input matches to a key sequence and the key sequence is a prefix of another key sequence

UNMATCHED

Input does not match to any key sequence

Attributes

Public Class Methods

# File lib/reline/key_stroke.rb, line 8
def initialize(config, encoding)
  @config = config
  @encoding = encoding
end

Public Instance Methods

# File lib/reline/key_stroke.rb, line 44
def expand(input)
  matched_bytes = nil
  (1..input.size).each do |i|
    bytes = input.take(i)
    status = match_status(bytes)
    matched_bytes = bytes if status == MATCHED || status == MATCHING_MATCHED
    break if status == MATCHED || status == UNMATCHED
  end
  return [[], []] unless matched_bytes

  func = key_mapping.get(matched_bytes)
  s = matched_bytes.pack('c*').force_encoding(@encoding)
  if func.is_a?(Array)
    # 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(s, func, false)]
  else
    if s.valid_encoding? && s.size == 1
      keys = [Reline::Key.new(s, :ed_insert, false)]
    else
      keys = []
    end
  end

  [keys, input.drop(matched_bytes.size)]
end
# File lib/reline/key_stroke.rb, line 22
def match_status(input)
  matching = key_mapping.matching?(input)
  matched = key_mapping.get(input)
  if matching && matched
    MATCHING_MATCHED
  elsif matching
    MATCHING
  elsif matched
    MATCHED
  elsif input[0] == ESC_BYTE
    match_unknown_escape_sequence(input, vi_mode: @config.editing_mode_is?(:vi_insert, :vi_command))
  else
    s = input.pack('c*').force_encoding(@encoding)
    if s.valid_encoding?
      s.size == 1 ? MATCHED : UNMATCHED
    else
      # Invalid string is MATCHING (part of valid string) or MATCHED (invalid bytes to be ignored)
      MATCHING_MATCHED
    end
  end
end