keyMatches function

bool keyMatches(
  1. Key key,
  2. List<KeyBinding> bindings
)

Checks if a key message matches any of the given bindings.

This is the primary way to check if user input matches a key binding.

Example

final keyMap = MyKeyMap();

(Model, Cmd?) update(Msg msg) {
  return switch (msg) {
    KeyMsg(:final key) when keyMatches(key, keyMap.up) =>
      (moveUp(), null),
    KeyMsg(:final key) when keyMatches(key, keyMap.down) =>
      (moveDown(), null),
    KeyMsg(:final key) when keyMatches(key, keyMap.quit) =>
      (this, Cmd.quit()),
    _ => (this, null),
  };
}

Implementation

bool keyMatches(Key key, List<KeyBinding> bindings) {
  final keyStr = key.toString();
  // Extract the key name from Key(...) format
  final keyName = keyStr.startsWith('Key(') && keyStr.endsWith(')')
      ? keyStr.substring(4, keyStr.length - 1)
      : keyStr;
  final caseSensitiveRunes =
      key.type == KeyType.runes &&
      !key.ctrl &&
      !key.alt &&
      !key.meta &&
      !key.hyper &&
      !key.superKey;
  final keyNameCmp = caseSensitiveRunes ? keyName : keyName.toLowerCase();
  final keyStrCmp = caseSensitiveRunes ? keyStr : keyStr.toLowerCase();

  for (final binding in bindings) {
    if (!binding.enabled) continue;
    for (final k in binding.keys) {
      // For character keys (runes), match case-sensitively
      // For other keys, match case-insensitively
      final kCmp = caseSensitiveRunes ? k : k.toLowerCase();
      final matches = caseSensitiveRunes
          ? (keyNameCmp == kCmp || keyStrCmp == kCmp)
          : (keyNameCmp == kCmp || keyStrCmp == kCmp);
      if (matches) return true;

      // Handle special key type aliases (e.g., ' ' for space, '\t' for tab)
      if (_keyTypeMatchesAlias(key.type, k)) return true;
    }
  }
  return false;
}