Don't panic.  I have no plans to write code :-)

Recently Vitalije made a remark that got me thinking about how to simplify 
Leo's clumsy undo code.  The late great Bernhard Mulder also wanted to do 
this. 

Vitalije suggested that we could modify Leo's execute-script code to 
support undo.  We probably must go further, and support undo in 
k.masterCommand, and in other places. k.masterCommand handles the details 
surrounding setup/teardown of commands.  c.doCommand is also involved, but 
it might suffice only to change k.masterCommand.

*Overview*

The general idea is to create a per-commander *undo data structure*, 
c.undoer.undo_data. This will have a list of changes, 
undo_data.undo_changes that describe the nodes to be changed. undo_data 
will also have a undo_type value, with default being "Undo Typing".

We want Leo data classes to update undo_data.undo_changes automatically:

1. When headlines change,
2. When body text change,
3. When outline structure change.
4. (Maybe) when uA's change.

1, 2 and 4 should be straightforward, because of the p.b, p.h and p.u 
properties.  Straightforward, but not trivial, because Leo's core probably 
sets p.b, p.h and p.u *without* using the properties.

Recording changes to outline structure would require more work.  The 
position methods that modify outline structure actually just call 
corresponding vnode methods.  These methods could update c.undo_data, *provided 
*that they had access to c.

*Simplicity*

k.masterCommand (and all other methods that execute code) would call 
c.undoer.setup() and c.undoer.teardown().

Leo's commands would need to do *nothing* except possibly setting 
undo_data.undo_type.

Leo's actual undo code, in leoUndo.py, would change drastically.  u.setup 
replaces all the "before" methods.  u.teardown replaces all "after" 
methods. u.setup simply inits c.undo_data.  u.teardown pushes it on the 
undo stack.

Only one undo method and one redo method would exist, both driven by 
undo_changes. This method will not be trivial, but it should be simpler, 
and less error prone, than the existing code.

*Summary*

1. All methods that execute code (including @command and @button) will call 
c.undoer.setup()/teardown().

2. All the present undo/redo code in Leo's core (and in Leo scripts) could 
be eliminated.  Commands and scripts could optionally set 
c.undoer.undo_data.undo_type. The default would be "Undo Typing".

3. Leo's low-level setters will add items to c.undoer.undo_data.

4. Leo's undo/redo code, in leoUndo.py, would be driven by u.undo_data. 
Rewriting leoUndo.py would have no effect on the rest of Leo.

5. No significant changes to Leo's existing vnode or position classes would 
be required. A new data model is not required ;-)

Edward

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/leo-editor.
For more options, visit https://groups.google.com/d/optout.

Reply via email to