Browse Source

Add Terminal.reflowEnabled #104

xuty 3 years ago
parent
commit
7e01a69528
4 changed files with 52 additions and 6 deletions
  1. 8 6
      lib/src/core/buffer/buffer.dart
  2. 2 0
      lib/src/core/state.dart
  3. 6 0
      lib/src/terminal.dart
  4. 36 0
      test/src/terminal_test.dart

+ 8 - 6
lib/src/core/buffer/buffer.dart

@@ -433,14 +433,16 @@ class Buffer {
     _cursorX = _cursorX.clamp(0, newWidth - 1);
     _cursorY = _cursorY.clamp(0, newHeight - 1);
 
-    if (!isAltBuffer && newWidth != oldWidth) {
-      final reflowResult = reflow(lines, oldWidth, newWidth);
+    if (terminal.reflowEnabled) {
+      if (!isAltBuffer && newWidth != oldWidth) {
+        final reflowResult = reflow(lines, oldWidth, newWidth);
 
-      while (reflowResult.length < newHeight) {
-        reflowResult.add(_newEmptyLine(newWidth));
-      }
+        while (reflowResult.length < newHeight) {
+          reflowResult.add(_newEmptyLine(newWidth));
+        }
 
-      lines.replaceWith(reflowResult);
+        lines.replaceWith(reflowResult);
+      }
     }
   }
 

+ 2 - 0
lib/src/core/state.dart

@@ -8,6 +8,8 @@ abstract class TerminalState {
 
   CursorStyle get cursor;
 
+  bool get reflowEnabled;
+
   /* Modes */
 
   bool get insertMode;

+ 6 - 0
lib/src/terminal.dart

@@ -49,6 +49,7 @@ class Terminal with Observable implements TerminalState, EscapeHandler {
     this.platform = TerminalTargetPlatform.unknown,
     this.inputHandler = defaultInputHandler,
     this.mouseHandler = defaultMouseHandler,
+    this.reflowEnabled = true,
   });
 
   TerminalMouseHandler? mouseHandler;
@@ -166,6 +167,11 @@ class Terminal with Observable implements TerminalState, EscapeHandler {
 
   CircularList<BufferLine> get lines => _buffer.lines;
 
+  /// Whether the terminal performs reflow when the viewport size changes or
+  /// simply truncates lines. true by default.
+  @override
+  bool reflowEnabled;
+
   void write(String data) {
     _parser.write(data);
     notifyListeners();

+ 36 - 0
test/src/terminal_test.dart

@@ -49,6 +49,42 @@ void main() {
       expect(output, ['\x1B[M +,']);
     });
   });
+
+  group('Terminal.reflowEnabled', () {
+    test('prevents reflow when set to false', () {
+      final terminal = Terminal(reflowEnabled: false);
+
+      terminal.write('Hello World');
+      terminal.resize(5, 5);
+
+      expect(terminal.buffer.lines[0].toString(), 'Hello');
+      expect(terminal.buffer.lines[1].toString(), isEmpty);
+    });
+
+    test('preserves hidden cells when reflow is disabled', () {
+      final terminal = Terminal(reflowEnabled: false);
+
+      terminal.write('Hello World');
+      terminal.resize(5, 5);
+      terminal.resize(20, 5);
+
+      expect(terminal.buffer.lines[0].toString(), 'Hello World');
+      expect(terminal.buffer.lines[1].toString(), isEmpty);
+    });
+
+    test('can be set at runtime', () {
+      final terminal = Terminal(reflowEnabled: true);
+
+      terminal.resize(5, 5);
+      terminal.write('Hello World');
+      terminal.reflowEnabled = false;
+      terminal.resize(20, 5);
+
+      expect(terminal.buffer.lines[0].toString(), 'Hello');
+      expect(terminal.buffer.lines[1].toString(), ' Worl');
+      expect(terminal.buffer.lines[2].toString(), 'd');
+    });
+  });
 }
 
 class _TestInputHandler implements TerminalInputHandler {