This post discusses a possible fix for
#1437: Leo-Bridge can be wrong about an outline read from a file.
This is a tricky topic, so I want to walk myself, Bob, and other interested parties through the problem and the fix.
In the first comment of #1437 Bob says:
"Before reading a file, Leo generates one or more nodes with GNX's for the file. Usually this is harmless because the GNX's generated do not match any of the GNX's in the outline being read. But when a generated GNX equals a GNX in the outline being read, Leo is misled about the outline contents."
Restating the problem
LeoFrame.createFirstTreeNode allocates a vnode, c.hiddenRootNode, before reading the file. That means that there is no way to ensure that c.hiddenRootNode.gnx won't conflict with the vnodes in the file that is about to be read.
This potential clash only happens when the bridge opens two or more .leo files within a second or so.
leoBridge.py typically opens .leo
files using g.openWithFileName. The call chain is long and complex, so
adding kwargs along the way is out of the question.
The fix
Rev 6269bab in the gnx branch follows Bob's third solution, more or less. Here are the details:
1. frame.createFirstTreeNode now sets c.hiddenRootNode.gnx to a dummy value, but only when g.app.inBridge is True:
def createFirstTreeNode(self):
"""Create a new vnode as the root of the to-be-created tree."""
c = self.c
# #1437: Use a dummy gnx in the bridge.
gnx = '**dummy-gnx**' if g.app.inBridge else None
v = leoNodes.VNode(context=c, gnx=gnx)
p = leoNodes.Position(v)
v.initHeadString("NewHeadline")
# p.moveToRoot would be wrong: the node hasn't been linked yet.
p._linkAsRoot(oldRoot=None)
The guard on g.app.inBridge ensures that only the bridge can ever be affected by the new code.
2. After reading the file, bridge.openLeoFile sets c.hiddenRootNode.gnx to a value that doesn't conflict with any gnx in the just-read file:
# Existing code: make sure all new gnx's are unique.
g.app.nodeIndices.compute_last_index(c)
# #1437: Set c.hiddenRootNode.gnx:
g.app.nodeIndices.getNewIndex(v=c.hiddenRootNode)
Giving c.hiddenRootNode a valid (unique!) gnx should ensure that no other part of Leo can be affected by the dummy gnx.
Summary
The new code is straightforward. Its effects should be isolated to only the bridge itself.
Please let me know if I have misunderstood the problem, or its solution.
Edward