call method
Implementation
@override
String? call(TerminalKeyboardEvent event) {
final mode = event.state.kittyKeyboardMode;
final kittySequenceEnabled = mode &
(_disambiguateEscapeCodes |
_reportEventTypes |
_reportAllKeysAsEscapeCodes) !=
0;
if (!kittySequenceEnabled) {
return null;
}
if (_isComposedTextEvent(event, mode)) {
return null;
}
// "Additionally, with this mode, events for pressing modifier keys are
// reported" — the modifier keys themselves are reported only under report
// all keys, never under disambiguate alone.
final specialCode = _specialKeyCode(event.key);
if (specialCode != null) {
if (_isModifierKey(event.key) &&
mode & _reportAllKeysAsEscapeCodes == 0) {
return null;
}
if (!_reportsRelease(event, mode)) {
return null;
}
return _sequence(specialCode, event);
}
// "Additionally, all non text keypad keys will be reported as separate
// keys" — a keypad key that types a character (a digit with Num Lock on,
// or any operator) follows the same rules as other text keys. The key
// decides this rather than the event text, which releases never carry.
final numpadCode = _numpadKeyCode(event.key);
if (numpadCode != null) {
// Keypad Enter keeps the legacy carriage return like the main Enter key.
// kitty and Ghostty send CSI 57414 u here, but clients that only push
// "disambiguate" (Cursor's agent CLI among them) do not decode it and
// insert U+E046 instead of submitting.
if (event.key == TerminalKey.numpadEnter &&
mode & _reportAllKeysAsEscapeCodes == 0 &&
!(event.ctrl || event.alt || event.shift || event.superKey)) {
return switch (event.type) {
TerminalKeyEventType.release => null,
_ => '\r',
};
}
if (event.key != TerminalKey.numpadEnter &&
!_shouldEncodeCharacter(event, mode)) {
return null;
}
if (!_reportsRelease(event, mode)) {
return null;
}
return _sequence(numpadCode, event);
}
final functionalSequence = _functionalSequence(event, mode);
if (functionalSequence != null) {
return functionalSequence;
}
final controlCode = _controlKeyCode(event.key);
if (controlCode != null && _shouldUseLegacyControlCode(event, mode)) {
return String.fromCharCode(controlCode);
}
if (_shouldEncodeControlKey(event, mode)) {
if (controlCode != null) {
return _sequence(controlCode, event);
}
}
final characterCode = _characterKeyCode(event);
if (characterCode == null) {
return null;
}
if (!_shouldEncodeCharacter(event, mode)) {
return null;
}
var payload = characterCode.toString();
final reportsAlternateKeys = mode & _reportAlternateKeys != 0;
final alternateCode = _alternateCharacterCode(event, characterCode);
if (reportsAlternateKeys && alternateCode != null) {
payload = '$payload:$alternateCode';
}
return _sequence(payload, event);
}