debugger.dart 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'package:dartssh2/dartssh2.dart';
  4. import 'package:example/src/virtual_keyboard.dart';
  5. import 'package:flutter/cupertino.dart';
  6. import 'package:xterm/utils.dart';
  7. import 'package:xterm/xterm.dart';
  8. const host = 'localhost';
  9. const port = 22;
  10. const username = '<your username>';
  11. const password = '<your password>';
  12. void main() {
  13. runApp(MyApp());
  14. }
  15. class MyApp extends StatelessWidget {
  16. @override
  17. Widget build(BuildContext context) {
  18. return CupertinoApp(
  19. title: 'xterm.dart debugger',
  20. home: MyHomePage(),
  21. );
  22. }
  23. }
  24. class MyHomePage extends StatefulWidget {
  25. MyHomePage({super.key});
  26. @override
  27. // ignore: library_private_types_in_public_api
  28. _MyHomePageState createState() => _MyHomePageState();
  29. }
  30. class _MyHomePageState extends State<MyHomePage> {
  31. /// The main terminal that user interacts with
  32. late final terminal = Terminal(inputHandler: keyboard);
  33. final keyboard = VirtualKeyboard(defaultInputHandler);
  34. /// The debugger used to record and parse terminal data
  35. final debugger = TerminalDebugger();
  36. /// A temporary terminal to display playback data. null if not in playback
  37. /// mode.
  38. Terminal? debuggerTerminal;
  39. var title = host;
  40. @override
  41. void initState() {
  42. super.initState();
  43. initTerminal();
  44. }
  45. /// Write data to both the main terminal and the debugger
  46. void write(String data) {
  47. terminal.write(data);
  48. debugger.write(data);
  49. }
  50. Future<void> initTerminal() async {
  51. write('Connecting...\r\n');
  52. final client = SSHClient(
  53. await SSHSocket.connect(host, port),
  54. username: username,
  55. onPasswordRequest: () => password,
  56. );
  57. write('Connected\r\n');
  58. final session = await client.shell(
  59. pty: SSHPtyConfig(
  60. width: terminal.viewWidth,
  61. height: terminal.viewHeight,
  62. ),
  63. );
  64. terminal.buffer.clear();
  65. terminal.buffer.setCursor(0, 0);
  66. terminal.onTitleChange = (title) {
  67. setState(() => this.title = title);
  68. };
  69. terminal.onResize = (width, height, pixelWidth, pixelHeight) {
  70. session.resizeTerminal(width, height, pixelWidth, pixelHeight);
  71. };
  72. terminal.onOutput = (data) {
  73. session.write(utf8.encode(data));
  74. };
  75. session.stdout.cast<List<int>>().transform(Utf8Decoder()).listen(write);
  76. session.stderr.cast<List<int>>().transform(Utf8Decoder()).listen(write);
  77. }
  78. @override
  79. Widget build(BuildContext context) {
  80. return CupertinoPageScaffold(
  81. navigationBar: CupertinoNavigationBar(
  82. middle: Text(title),
  83. backgroundColor:
  84. CupertinoTheme.of(context).barBackgroundColor.withOpacity(0.5),
  85. ),
  86. child: Column(
  87. children: [
  88. Expanded(
  89. child: Row(
  90. children: [
  91. Expanded(
  92. child: TerminalView(debuggerTerminal ?? terminal),
  93. ),
  94. SizedBox(
  95. width: 600,
  96. child: TerminalDebuggerView(
  97. debugger,
  98. onSeek: (commandIndex) {
  99. if (commandIndex == null) {
  100. setState(() => this.debuggerTerminal = null);
  101. return;
  102. }
  103. // Get all data rangin from beginning to the command
  104. // selected and write it to the temporary terminal
  105. final command = debugger.commands[commandIndex];
  106. final data = debugger.getRecord(command);
  107. final debuggerTerminal = Terminal();
  108. debuggerTerminal.write(data);
  109. setState(() => this.debuggerTerminal = debuggerTerminal);
  110. },
  111. ),
  112. ),
  113. ],
  114. ),
  115. ),
  116. VirtualKeyboardView(keyboard),
  117. ],
  118. ),
  119. );
  120. }
  121. }