tom_undo 0.1.0
tom_undo: ^0.1.0 copied to clipboard
The undo/redo stack every undo history runs on: a bounded stack that applies an entry before moving it, so a failing undo stays undoable, and composite steps that put back what they applied when one p [...]
tom_undo #
Published on pub.dev as tom_undo 0.1.0.
One undo/redo stack, TomUndoStack<E>, that every undo history in the
workspace runs on — Tom Forge's DefaultUndoManager, the text, Markdown, YAML
and Dart editors, the file tabs' ForgeFileSession, and tom_flutter_ui's
TomUndoHistory. Plain Dart with no dependency, so it reaches no dart:io
and no Flutter.
dependencies:
tom_undo:
path: ../../tom_ai/basics/tom_undo
- Applied first, moved second.
undoandredoapply an entry and only then move it between the stacks, so an application that throws leaves the entry where it was and the error reaches the caller.undoAsyncandredoAsyncdo the same for an application that completes later. - Bounded. A push clears the redo stack and drops the oldest entries
beyond
maxEntries;popNewesttakes the newest entry back so a history can merge a burst of typing into one act. - Atomic composite steps.
tomApplyAll(andtomApplyAllAsync) apply a list of steps in order and, when one throws, put back the ones already applied, newest first, before rethrowing.
import 'package:tom_undo/tom_undo.dart';
void main() {
final history = TomUndoStack<String>(maxEntries: 50);
history.push('typed "hello"');
history.undo((entry) => print('undo $entry')); // applied, then moved to redo
history.redo((entry) => print('redo $entry'));
}
Forge's undo contract (ForgeUndoManager) and its default implementation stay
in tom_forge_core, built on this stack.
One stack, kept one #
_bin/check_undo_stacks.py at the workspace root finds an undo or redo
history written by hand anywhere else — a field or local named like _undo or
_redoStack that starts as an empty list or queue — and its fix is this
package, not a rename:
./_bin/check_undo_stacks.py --strict # exit 1 on a hand-rolled stack
python3 _bin/test_check_undo_stacks.py # the check's own tests
It is started by hand, like every check in the workspace.
License #
BSD-3-Clause — See LICENSE for details.