| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595 |
- import 'package:xterm/src/core/escape/handler.dart';
- import 'package:xterm/src/core/escape/parser.dart';
- import 'package:xterm/src/core/mouse/mode.dart';
- import 'package:xterm/src/utils/observable.dart';
- class TerminalCommand {
- TerminalCommand(
- this.start,
- this.end,
- this.chars,
- this.escapedChars,
- this.explanation,
- this.error,
- );
- final int start;
- final int end;
- final String chars;
- final String escapedChars;
- final List<String> explanation;
- final bool error;
- }
- class TerminalDebugger with Observable {
- late final _parser = EscapeParser(_handler);
- late final _handler = _TerminalDebuggerHandler(recordCommand);
- final recorded = <int>[];
- final commands = <TerminalCommand>[];
- void write(String chunk) {
- recorded.addAll(chunk.runes);
- _parser.write(chunk);
- notifyListeners();
- }
- void recordCommand(String explanation, {bool error = false}) {
- final start = _parser.tokenBegin;
- final end = _parser.tokenEnd;
- if (commands.isNotEmpty && commands.last.end == end) {
- commands.last.explanation.add(explanation);
- } else {
- final charCodes = recorded.sublist(start, end);
- final chars = String.fromCharCodes(charCodes);
- final escapedChars = _escape(chars);
- commands.add(
- TerminalCommand(start, end, chars, escapedChars, [explanation], error),
- );
- }
- }
- String getRecord(TerminalCommand command) {
- final charCodes = recorded.sublist(0, command.end);
- return String.fromCharCodes(charCodes);
- }
- static String _escape(String chars) {
- final escaped = StringBuffer();
- for (final char in chars.runes) {
- if (char == 0x1b) {
- escaped.write('ESC');
- } else if (char < 32) {
- escaped.write('^0x${char.toRadixString(16)}');
- } else if (char == 127) {
- escaped.write('^?');
- } else {
- escaped.writeCharCode(char);
- }
- }
- return escaped.toString();
- }
- }
- class _TerminalDebuggerHandler implements EscapeHandler {
- _TerminalDebuggerHandler(this.onCommand);
- final void Function(String explanation, {bool error}) onCommand;
- @override
- void writeChar(int char) {
- onCommand('writeChar(${String.fromCharCode(char)})');
- }
- /* SBC */
- @override
- void bell() {
- onCommand('bell');
- }
- @override
- void backspaceReturn() {
- onCommand('backspaceReturn');
- }
- @override
- void tab() {
- onCommand('tab');
- }
- @override
- void lineFeed() {
- onCommand('lineFeed');
- }
- @override
- void carriageReturn() {
- onCommand('carriageReturn');
- }
- @override
- void shiftOut() {
- onCommand('shiftOut');
- }
- @override
- void shiftIn() {
- onCommand('shiftIn');
- }
- @override
- void unknownSBC(int char) {
- onCommand('unkownSBC(${String.fromCharCode(char)})', error: true);
- }
- /* ANSI sequence */
- @override
- void saveCursor() {
- onCommand('saveCursor');
- }
- @override
- void restoreCursor() {
- onCommand('restoreCursor');
- }
- @override
- void index() {
- onCommand('index');
- }
- @override
- void nextLine() {
- onCommand('nextLine');
- }
- @override
- void setTapStop() {
- onCommand('setTapStop');
- }
- @override
- void reverseIndex() {
- onCommand('reverseIndex');
- }
- @override
- void designateCharset(int charset) {
- onCommand('designateCharset($charset)');
- }
- @override
- void unkownEscape(int char) {
- onCommand('unkownEscape(${String.fromCharCode(char)})', error: true);
- }
- /* CSI */
- @override
- void repeatPreviousCharacter(int count) {
- onCommand('repeatPreviousCharacter($count)');
- }
- @override
- void unknownCSI(int finalByte) {
- onCommand('unkownCSI(${String.fromCharCode(finalByte)})', error: true);
- }
- @override
- void setCursor(int x, int y) {
- onCommand('setCursor($x, $y)');
- }
- @override
- void setCursorX(int x) {
- onCommand('setCursorX($x)');
- }
- @override
- void setCursorY(int y) {
- onCommand('setCursorY($y)');
- }
- @override
- void sendPrimaryDeviceAttributes() {
- onCommand('sendPrimaryDeviceAttributes');
- }
- @override
- void clearTabStopUnderCursor() {
- onCommand('clearTabStopUnderCursor');
- }
- @override
- void clearAllTabStops() {
- onCommand('clearAllTabStops');
- }
- @override
- void moveCursorX(int offset) {
- onCommand('moveCursorX($offset)');
- }
- @override
- void moveCursorY(int n) {
- onCommand('moveCursorY($n)');
- }
- @override
- void sendSecondaryDeviceAttributes() {
- onCommand('sendSecondaryDeviceAttributes');
- }
- @override
- void sendTertiaryDeviceAttributes() {
- onCommand('sendTertiaryDeviceAttributes');
- }
- @override
- void sendOperatingStatus() {
- onCommand('sendOperatingStatus');
- }
- @override
- void sendCursorPosition() {
- onCommand('sendCursorPosition');
- }
- @override
- void setMargins(int i, [int? bottom]) {
- onCommand('setMargins($i, $bottom)');
- }
- @override
- void cursorNextLine(int amount) {
- onCommand('cursorNextLine($amount)');
- }
- @override
- void cursorPrecedingLine(int amount) {
- onCommand('cursorPrecedingLine($amount)');
- }
- @override
- void eraseDisplayBelow() {
- onCommand('eraseDisplayBelow');
- }
- @override
- void eraseDisplayAbove() {
- onCommand('eraseDisplayAbove');
- }
- @override
- void eraseDisplay() {
- onCommand('eraseDisplay');
- }
- @override
- void eraseScrollbackOnly() {
- onCommand('eraseScrollbackOnly');
- }
- @override
- void eraseLineRight() {
- onCommand('eraseLineRight');
- }
- @override
- void eraseLineLeft() {
- onCommand('eraseLineLeft');
- }
- @override
- void eraseLine() {
- onCommand('eraseLine');
- }
- @override
- void insertLines(int amount) {
- onCommand('insertLines($amount)');
- }
- @override
- void deleteLines(int amount) {
- onCommand('deleteLines($amount)');
- }
- @override
- void deleteChars(int amount) {
- onCommand('deleteChars($amount)');
- }
- @override
- void scrollUp(int amount) {
- onCommand('scrollUp($amount)');
- }
- @override
- void scrollDown(int amount) {
- onCommand('scrollDown($amount)');
- }
- @override
- void eraseChars(int amount) {
- onCommand('eraseChars($amount)');
- }
- @override
- void insertBlankChars(int amount) {
- onCommand('insertBlankChars($amount)');
- }
- @override
- void resize(int cols, int rows) {
- onCommand('resize($cols, $rows)');
- }
- @override
- void sendSize() {
- onCommand('sendSize');
- }
- /* Modes */
- @override
- void setInsertMode(bool enabled) {
- onCommand('setInsertMode($enabled)');
- }
- @override
- void setLineFeedMode(bool enabled) {
- onCommand('setLineFeedMode($enabled)');
- }
- @override
- void setUnknownMode(int mode, bool enabled) {
- onCommand('setUnknownMode($mode, $enabled)', error: true);
- }
- /* DEC Private modes */
- @override
- void setCursorKeysMode(bool enabled) {
- onCommand('setCursorKeysMode($enabled)');
- }
- @override
- void setReverseDisplayMode(bool enabled) {
- onCommand('setReverseDisplayMode($enabled)');
- }
- @override
- void setOriginMode(bool enabled) {
- onCommand('setOriginMode($enabled)');
- }
- @override
- void setColumnMode(bool enabled) {
- onCommand('setColumnMode($enabled)');
- }
- @override
- void setAutoWrapMode(bool enabled) {
- onCommand('setAutoWrapMode($enabled)');
- }
- @override
- void setMouseMode(MouseMode mode) {
- onCommand('setMouseMode($mode)');
- }
- @override
- void setCursorBlinkMode(bool enabled) {
- onCommand('setCursorBlinkMode($enabled)');
- }
- @override
- void setCursorVisibleMode(bool enabled) {
- onCommand('setCursorVisibleMode($enabled)');
- }
- @override
- void useAltBuffer() {
- onCommand('useAltBuffer');
- }
- @override
- void useMainBuffer() {
- onCommand('useMainBuffer');
- }
- @override
- void clearAltBuffer() {
- onCommand('clearAltBuffer');
- }
- @override
- void setAppKeypadMode(bool enabled) {
- onCommand('setAppKeypadMode($enabled)');
- }
- @override
- void setReportFocusMode(bool enabled) {
- onCommand('setReportFocusMode($enabled)');
- }
- @override
- void setMouseReportMode(MouseReportMode mode) {
- onCommand('setMouseReportMode($mode)');
- }
- @override
- void setAltBufferMouseScrollMode(bool enabled) {
- onCommand('setAltBufferMouseScrollMode($enabled)');
- }
- @override
- void setBracketedPasteMode(bool enabled) {
- onCommand('setBracketedPasteMode($enabled)');
- }
- @override
- void setUnknownDecMode(int mode, bool enabled) {
- onCommand('setUnknownDecMode($mode, $enabled)', error: true);
- }
- /* Select Graphic Rendition (SGR) */
- @override
- void resetCursorStyle() {
- onCommand('resetCursorStyle');
- }
- @override
- void setCursorBold() {
- onCommand('setCursorBold');
- }
- @override
- void setCursorFaint() {
- onCommand('setCursorFaint');
- }
- @override
- void setCursorItalic() {
- onCommand('setCursorItalic');
- }
- @override
- void setCursorUnderline() {
- onCommand('setCursorUnderline');
- }
- @override
- void setCursorBlink() {
- onCommand('setCursorBlink');
- }
- @override
- void setCursorInverse() {
- onCommand('setCursorInverse');
- }
- @override
- void setCursorInvisible() {
- onCommand('setCursorInvisible');
- }
- @override
- void setCursorStrikethrough() {
- onCommand('setCursorStrikethrough');
- }
- @override
- void unsetCursorBold() {
- onCommand('unsetCursorBold');
- }
- @override
- void unsetCursorFaint() {
- onCommand('unsetCursorFaint');
- }
- @override
- void unsetCursorItalic() {
- onCommand('unsetCursorItalic');
- }
- @override
- void unsetCursorUnderline() {
- onCommand('unsetCursorUnderline');
- }
- @override
- void unsetCursorBlink() {
- onCommand('unsetCursorBlink');
- }
- @override
- void unsetCursorInverse() {
- onCommand('unsetCursorInverse');
- }
- @override
- void unsetCursorInvisible() {
- onCommand('unsetCursorInvisible');
- }
- @override
- void unsetCursorStrikethrough() {
- onCommand('unsetCursorStrikethrough');
- }
- @override
- void setForegroundColor16(int color) {
- onCommand('setForegroundColor16($color)');
- }
- @override
- void setForegroundColor256(int index) {
- onCommand('setForegroundColor256($index)');
- }
- @override
- void setForegroundColorRgb(int r, int g, int b) {
- onCommand('setForegroundColorRgb($r, $g, $b)');
- }
- @override
- void resetForeground() {
- onCommand('resetForeground');
- }
- @override
- void setBackgroundColor16(int color) {
- onCommand('setBackgroundColor16($color)');
- }
- @override
- void setBackgroundColor256(int index) {
- onCommand('setBackgroundColor256($index)');
- }
- @override
- void setBackgroundColorRgb(int r, int g, int b) {
- onCommand('setBackgroundColorRgb($r, $g, $b)');
- }
- @override
- void resetBackground() {
- onCommand('resetBackground');
- }
- @override
- void unsupportedStyle(int param) {
- onCommand('unsupportedStyle($param)', error: true);
- }
- /* OSC */
- @override
- void setTitle(String name) {
- onCommand('setTitle($name)');
- }
- @override
- void setIconName(String name) {
- onCommand('setIconName($name)');
- }
- @override
- void unknownOSC(String ps) {
- onCommand('unknownOSC($ps)', error: true);
- }
- }
|