While working on issue #3435, I see that u.saveTree can't possibly work! About a dozen commands and methods call u.saveTree indirectly. Undo and redo for these may be dangerous!
This Engineering Notebook post discusses what to do about this situation.
tl;dr: See the summary.
The problem
A cff shows that about a dozen commands and script helpers call u.beforeChangeTree and u.afterChangeTree. Both these methods call u.saveTree(p).
Alas, u.saveTree has no chance of working. As a result, Leo's undo logic is dangerously flawed in about a dozen places.
The section << about u.saveTree >> discusses u.createVnodeUndoInfo, u.saveTree's helper. These comments do not describe u.createVnodeUndoInfo correctly. Worse, u.createVnodeUndoInfo itself has no chance of solving the original problem! Details omitted.
Solutions
Imo, the following commands should not be undoable: refresh-from-disk, read-at-auto-nodes, read-at-file-nodes, and read-at-shadow-nodes. These commands are "one-way" updates. Rewriting their undo code would be fraught. Bugs in the undo/redo logic could be devastating.
Various commands and methods create a single new node. Their undo logic can mimic that of undo/redo insert-node. Undoing these commands would delete the newly-created node. Redo would undo the delete.
The abbrev.expand_tree method might be a unique case. I'm not yet sure what to do.
Summary
- We must retire u.saveTree, u.beforeChangeTree, and u.afterChangeTree.
- Several commands should not be undoable.
- Commands that insert a single node can use the undo/redo logic of insert-node.
All of your comments are welcome.
Edward
Various commands and methods create a single new node. Their undo logic can mimic that of undo/redo insert-node. Undoing these commands would delete the newly-created node. Redo would undo the delete.
On Thu, Jul 13, 2023 at 7:49 AM Edward K. Ream <edre...@gmail.com> wrote:> On second thought, none of [the git-diff commands] need to be undoable.
There's no shame in having big data-changing commands not be undoable! Big software packages often have such commands!On the other hand, it should be somewhat indicated when an action is not undoable. (perhaps add "This action is not undoable" in the string where the user is asked about refreshing from disk when an external file change is detected. idem for when an opened .leo file changes, and other non-undoable actions, when possible.)But the most important thing is to wipe clear the undo stack when such an action occurs