ansi.dart 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import 'dart:collection';
  2. import 'package:xterm/terminal/csi.dart';
  3. import 'package:xterm/terminal/osc.dart';
  4. import 'package:xterm/terminal/terminal.dart';
  5. typedef AnsiHandler = void Function(Queue<int>, Terminal);
  6. void ansiHandler(Queue<int> queue, Terminal terminal) {
  7. final charAfterEsc = queue.removeFirst();
  8. final handler = _ansiHandlers[charAfterEsc];
  9. if (handler != null) {
  10. if (handler != csiHandler && handler != oscHandler) {
  11. terminal.debug.onEsc(charAfterEsc);
  12. }
  13. return handler(queue, terminal);
  14. }
  15. terminal.debug.onError('unsupported ansi sequence: $charAfterEsc');
  16. }
  17. final _ansiHandlers = <int, AnsiHandler>{
  18. '['.codeUnitAt(0): csiHandler,
  19. ']'.codeUnitAt(0): oscHandler,
  20. '7'.codeUnitAt(0): _ansiSaveCursorHandler,
  21. '8'.codeUnitAt(0): _ansiRestoreCursorHandler,
  22. 'D'.codeUnitAt(0): _ansiIndexHandler,
  23. 'E'.codeUnitAt(0): _ansiNextLineHandler,
  24. 'H'.codeUnitAt(0): _ansiTabSetHandler,
  25. 'M'.codeUnitAt(0): _ansiReverseIndexHandler,
  26. 'P'.codeUnitAt(0): _unsupportedHandler, // Sixel
  27. 'c'.codeUnitAt(0): _unsupportedHandler,
  28. '#'.codeUnitAt(0): _unsupportedHandler,
  29. '('.codeUnitAt(0): _scsHandler(0), // G0
  30. ')'.codeUnitAt(0): _scsHandler(1), // G1
  31. '*'.codeUnitAt(0): _voidHandler(1), // TODO: G2 (vt220)
  32. '+'.codeUnitAt(0): _voidHandler(1), // TODO: G3 (vt220)
  33. '>'.codeUnitAt(0): _voidHandler(0), // TODO: Normal Keypad
  34. '='.codeUnitAt(0): _voidHandler(0), // TODO: Application Keypad
  35. };
  36. AnsiHandler _voidHandler(int sequenceLength) {
  37. return (queue, terminal) {
  38. queue.take(sequenceLength);
  39. };
  40. }
  41. void _unsupportedHandler(Queue<int> queue, Terminal terminal) async {
  42. // print('unimplemented ansi sequence.');
  43. }
  44. void _ansiSaveCursorHandler(Queue<int> queue, Terminal terminal) {
  45. terminal.buffer.saveCursor();
  46. }
  47. void _ansiRestoreCursorHandler(Queue<int> queue, Terminal terminal) {
  48. terminal.buffer.restoreCursor();
  49. }
  50. /// https://vt100.net/docs/vt100-ug/chapter3.html#IND IND – Index
  51. ///
  52. /// ESC D
  53. ///
  54. /// This sequence causes the active position to move downward one line without
  55. /// changing the column position. If the active position is at the bottom
  56. /// margin, a scroll up is performed.
  57. void _ansiIndexHandler(Queue<int> queue, Terminal terminal) {
  58. terminal.buffer.index();
  59. }
  60. void _ansiReverseIndexHandler(Queue<int> queue, Terminal terminal) {
  61. terminal.buffer.reverseIndex();
  62. }
  63. AnsiHandler _scsHandler(int which) {
  64. return (Queue<int> queue, Terminal terminal) {
  65. final name = String.fromCharCode(queue.removeFirst());
  66. terminal.buffer.charset.designate(which, name);
  67. };
  68. }
  69. void _ansiNextLineHandler(Queue<int> queue, Terminal terminal) {
  70. terminal.buffer.newLine();
  71. terminal.buffer.setCursorX(0);
  72. }
  73. void _ansiTabSetHandler(Queue<int> queue, Terminal terminal) {
  74. terminal.tabSetAtCursor();
  75. }