import 'package:xterm/core/input/keys.dart'; import 'package:xterm/core/input/keytab/keytab.dart'; import 'package:xterm/utils/platform.dart'; import 'package:xterm/core/state.dart'; class TerminalInputEvent { final TerminalKey key; final bool shift; final bool ctrl; final bool alt; final TerminalState state; final bool altBuffer; final TerminalTargetPlatform platform; TerminalInputEvent({ required this.key, required this.shift, required this.ctrl, required this.alt, required this.state, required this.altBuffer, required this.platform, }); } abstract class TerminalInputHandler { String? call(TerminalInputEvent event); } class CascadeInputHandler implements TerminalInputHandler { final List _handlers; const CascadeInputHandler(this._handlers); @override String? call(TerminalInputEvent event) { for (var handler in _handlers) { final result = handler(event); if (result != null) { return result; } } return null; } } const defaultInputHandler = CascadeInputHandler([ KeytabInputHandler(), CtrlInputHandler(), AltInputHandler(), ]); final _keytab = Keytab.defaultKeytab(); class KeytabInputHandler implements TerminalInputHandler { const KeytabInputHandler(); @override String? call(TerminalInputEvent event) { final action = _keytab.find( event.key, ctrl: event.ctrl, alt: event.alt, shift: event.shift, newLineMode: event.state.lineFeedMode, appCursorKeys: event.state.appKeypadMode, appKeyPad: event.state.appKeypadMode, appScreen: event.altBuffer, macos: event.platform == TerminalTargetPlatform.macos, ); if (action == null) { return null; } return action.action.unescapedValue(); } } class CtrlInputHandler implements TerminalInputHandler { const CtrlInputHandler(); @override String? call(TerminalInputEvent event) { if (!event.ctrl) { return null; } final key = event.key; if (key.index >= TerminalKey.keyA.index && key.index <= TerminalKey.keyZ.index) { final input = key.index - TerminalKey.keyA.index + 1; return String.fromCharCode(input); } return null; } } class AltInputHandler implements TerminalInputHandler { const AltInputHandler(); @override String? call(TerminalInputEvent event) { if (!event.alt) { return null; } if (event.platform == TerminalTargetPlatform.macos) { return null; } final key = event.key; if (key.index >= TerminalKey.keyA.index && key.index <= TerminalKey.keyZ.index) { final charCode = key.index - TerminalKey.keyA.index + 65; final input = [0x1b, charCode]; return String.fromCharCodes(input); } return null; } }