Skip to content

Commit

Permalink
Merge pull request #161 from itzhoujun/fix/tabs
Browse files Browse the repository at this point in the history
Fix/tabs
  • Loading branch information
xtyxtyx authored Feb 16, 2023
2 parents cd6b675 + f68802f commit 7454fe0
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 5 deletions.
30 changes: 26 additions & 4 deletions lib/src/core/tabs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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();
}
}
2 changes: 1 addition & 1 deletion lib/src/terminal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
31 changes: 31 additions & 0 deletions test/src/core/tabs_test.dart
Original file line number Diff line number Diff line change
@@ -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);
});
});
}

0 comments on commit 7454fe0

Please sign in to comment.