浏览代码

Merge pull request #161 from itzhoujun/fix/tabs

Fix/tabs
xuty 2 年之前
父节点
当前提交
7454fe0a7c
共有 3 个文件被更改,包括 58 次插入5 次删除
  1. 26 4
      lib/src/core/tabs.dart
  2. 1 1
      lib/src/terminal.dart
  3. 31 0
      test/src/core/tabs_test.dart

+ 26 - 4
lib/src/core/tabs.dart

@@ -2,9 +2,23 @@ import 'dart:math' show min;
 
 const _kMaxColumns = 1024;
 
+/// Manages the tab stop state for a terminal.
 class TabStops {
   final _stops = List<bool>.filled(_kMaxColumns, false);
 
+  TabStops() {
+    _initialize();
+  }
+
+  /// Initializes the tab stops to the default 8 column intervals.
+  void _initialize() {
+    const interval = 8;
+    for (var i = 0; i < _kMaxColumns; i += interval) {
+      _stops[i] = true;
+    }
+  }
+
+  /// Finds the next tab stop index, which satisfies [start] <= index < [end].
   int? find(int start, int end) {
     if (start >= end) {
       return null;
@@ -18,29 +32,37 @@ class TabStops {
     return null;
   }
 
+  /// Sets the tab stop at [index]. If there is already a tab stop at [index],
+  /// this method does nothing.
+  ///
+  /// See also:
+  /// * [clearAt] which does the opposite.
   void setAt(int index) {
     assert(index >= 0 && index < _kMaxColumns);
     _stops[index] = true;
   }
 
+  /// Clears the tab stop at [index]. If there is no tab stop at [index], this
+  /// method does nothing.
   void clearAt(int index) {
     assert(index >= 0 && index < _kMaxColumns);
     _stops[index] = false;
   }
 
+  /// Clears all tab stops without resetting them to the default 8 column
+  /// intervals.
   void clearAll() {
     _stops.fillRange(0, _kMaxColumns, false);
   }
 
+  /// Returns true if there is a tab stop at [index].
   bool isSetAt(int index) {
     return _stops[index];
   }
 
+  /// Resets the tab stops to the default 8 column intervals.
   void reset() {
     clearAll();
-    const interval = 8;
-    for (var i = 0; i < _kMaxColumns; i += interval) {
-      _stops[i] = true;
-    }
+    _initialize();
   }
 }

+ 1 - 1
lib/src/terminal.dart

@@ -398,7 +398,7 @@ class Terminal with Observable implements TerminalState, EscapeHandler {
 
   @override
   void tab() {
-    final nextStop = _tabStops.find(_buffer.cursorX, _viewWidth);
+    final nextStop = _tabStops.find(_buffer.cursorX + 1, _viewWidth);
 
     if (nextStop != null) {
       _buffer.setCursorX(nextStop);

+ 31 - 0
test/src/core/tabs_test.dart

@@ -0,0 +1,31 @@
+import 'package:flutter_test/flutter_test.dart';
+import 'package:xterm/src/core/tabs.dart';
+
+void main() {
+  group('TabStops', () {
+    test('has default tab stops after created', () {
+      final tabStops = TabStops();
+
+      expect(tabStops.isSetAt(0), true);
+      expect(tabStops.isSetAt(1), false);
+      expect(tabStops.isSetAt(7), false);
+      expect(tabStops.isSetAt(8), true);
+      expect(tabStops.isSetAt(9), false);
+      expect(tabStops.isSetAt(15), false);
+      expect(tabStops.isSetAt(16), true);
+    });
+  });
+
+  group('TabStops.find()', () {
+    test('includes start', () {
+      final tabStops = TabStops();
+      expect(tabStops.find(0, 10), 0);
+    });
+
+    test('excludes end', () {
+      final tabStops = TabStops();
+      expect(tabStops.find(0, 8), 0);
+      expect(tabStops.find(1, 9), 8);
+    });
+  });
+}