handler.dart 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import 'package:xterm/core/input/keys.dart';
  2. import 'package:xterm/core/input/keytab/keytab.dart';
  3. import 'package:xterm/utils/platform.dart';
  4. import 'package:xterm/core/state.dart';
  5. class TerminalInputEvent {
  6. final TerminalKey key;
  7. final bool shift;
  8. final bool ctrl;
  9. final bool alt;
  10. final TerminalState state;
  11. final bool altBuffer;
  12. final TerminalTargetPlatform platform;
  13. TerminalInputEvent({
  14. required this.key,
  15. required this.shift,
  16. required this.ctrl,
  17. required this.alt,
  18. required this.state,
  19. required this.altBuffer,
  20. required this.platform,
  21. });
  22. }
  23. abstract class TerminalInputHandler {
  24. String? call(TerminalInputEvent event);
  25. }
  26. class CascadeInputHandler implements TerminalInputHandler {
  27. final List<TerminalInputHandler> _handlers;
  28. const CascadeInputHandler(this._handlers);
  29. @override
  30. String? call(TerminalInputEvent event) {
  31. for (var handler in _handlers) {
  32. final result = handler(event);
  33. if (result != null) {
  34. return result;
  35. }
  36. }
  37. return null;
  38. }
  39. }
  40. const defaultInputHandler = CascadeInputHandler([
  41. KeytabInputHandler(),
  42. CtrlInputHandler(),
  43. AltInputHandler(),
  44. ]);
  45. final _keytab = Keytab.defaultKeytab();
  46. class KeytabInputHandler implements TerminalInputHandler {
  47. const KeytabInputHandler();
  48. @override
  49. String? call(TerminalInputEvent event) {
  50. final action = _keytab.find(
  51. event.key,
  52. ctrl: event.ctrl,
  53. alt: event.alt,
  54. shift: event.shift,
  55. newLineMode: event.state.lineFeedMode,
  56. appCursorKeys: event.state.appKeypadMode,
  57. appKeyPad: event.state.appKeypadMode,
  58. appScreen: event.altBuffer,
  59. macos: event.platform == TerminalTargetPlatform.macos,
  60. );
  61. if (action == null) {
  62. return null;
  63. }
  64. return action.action.unescapedValue();
  65. }
  66. }
  67. class CtrlInputHandler implements TerminalInputHandler {
  68. const CtrlInputHandler();
  69. @override
  70. String? call(TerminalInputEvent event) {
  71. if (!event.ctrl) {
  72. return null;
  73. }
  74. final key = event.key;
  75. if (key.index >= TerminalKey.keyA.index &&
  76. key.index <= TerminalKey.keyZ.index) {
  77. final input = key.index - TerminalKey.keyA.index + 1;
  78. return String.fromCharCode(input);
  79. }
  80. return null;
  81. }
  82. }
  83. class AltInputHandler implements TerminalInputHandler {
  84. const AltInputHandler();
  85. @override
  86. String? call(TerminalInputEvent event) {
  87. if (!event.alt) {
  88. return null;
  89. }
  90. if (event.platform == TerminalTargetPlatform.macos) {
  91. return null;
  92. }
  93. final key = event.key;
  94. if (key.index >= TerminalKey.keyA.index &&
  95. key.index <= TerminalKey.keyZ.index) {
  96. final charCode = key.index - TerminalKey.keyA.index + 65;
  97. final input = [0x1b, charCode];
  98. return String.fromCharCodes(input);
  99. }
  100. return null;
  101. }
  102. }