This Engineering Notebook post discusses subtle problems with Leo's paste-outline commands: paste-node, paste-retaining-clones, and paste-as-template. A new unit test (in PR #3473 <https://github.com/leo-editor/leo-editor/pull/3473>) revealed these problems. They may be ancient.
This post will be of interest only to hard-core Leo devs. Feel free to ignore it. *Note:* Remember that I'll be discussing code in the *new *(6.7.5) codebase. *A subtle bug* Dumps in a new unit test reveal that *c.recompute_all_parents* fails: def recompute_all_parents(self) -> None: """ Recompute all v.parents arrays using neither positions nor v.parents ivars. """ c = self root_v = c.hiddenRootNode # Clear all v.parents arrays. root_v.parents = [] for v in c.alt_all_unique_nodes(): v.parents = [] # Loop invariant: Visit each *parent* vnode *once*. # Child vnodes may be visited more than once. # Visit the hidden root. for child in root_v.children: child.parents.append(root_v) # Visit all other parents. for parent in c.alt_all_unique_nodes(): for child in parent.children: child.parents.append(parent) How can this "obviously correct" code fail? What's going on?? Aha! c.alt_all_unique_nodes() can yield nodes with different ids than those in root_v.children. In other words, *two distinct VNodes may share the same gnx*. Big oops. *The cause of the bug* Leo calls *c.reassignNonClonedIndices* after calling *c.unarchive_to_vnode*. But unarchive_to_vnode *itself* creates (or patches) parent/child links. In short: unarchive_to_vnode must reallocate gnxs. *fc.gnxDict* Lurking behind all this code is the infamous *fc.gnxDict* dictionary. Keys are gnxs; values are the corresponding VNodes. *c.recreateGnxDict* *supposedly* recreates this dict. Various read/write/paste helpers save and restore this dict for impossible-to-remember reasons. I would love to remove this dict, but doing so probably won't work. Because of undo, *Leo never deallocates VNodes!* Instead, I am leaning towards replacing fc.gnxDict with, say, *c.all_gnxs_dict*. Leo will: - only *add* keys to this dict. - never *delete keys.* *- *never save/restore this dict. Only a detailed examination of Leo's entire codebase will show whether this plan is feasible. *Summary* Let this post be a warning for anyone foolish enough to assert that some code is "obviously correct." It's impossible to say whether the bugs discussed here exist in Leo's existing codebase without adding new unit tests to devel. I'm not going to do that. It's too late to change Leo 6.7.4. All calls to *c.recreateGnxDict* seem dubious. PR #3473 <https://github.com/leo-editor/leo-editor/pull/3473> is an opportunity to re-engineer how Leo remembers existing VNodes. All three paste-outline commands *and* their undo/redo helpers must likely confront these issues explicitly. "Clever" solutions will likely fail. 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 leo-editor+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/leo-editor/d821bd90-2c59-4482-a242-1d9e8f5fab59n%40googlegroups.com.