Writing the cffm and cfam commands was snap using c.cloneFindByPredicate, a
powerful new addition to Leo. Here is the entire code for the new commands:
@cmd('clone-find-all-marked')
@cmd('cfam')
def cloneFindAllMarked(self, event=None):
'''The clone-find-all-marked command.'''
self.cloneFindMarkedHelper(flatten=False)
@cmd('clone-find-all-flattened-marked')
@cmd('cffm')
def cloneFindAllFlattenedMarked(self, event=None):
'''The clone-find-all-flattened-marked command.'''
self.cloneFindMarkedHelper(flatten=True)
def cloneFindMarkedHelper(self, flatten):
'''Helper for clone-find-marked commands.'''
def isMarked(p):
return p.isMarked()
self.cloneFindByPredicate(
generator = self.all_unique_positions,
predicate = isMarked,
flatten = flatten,
undoType = 'clone-find-marked',
)
It's hard to imagine anything simpler. *Important*: the predicate could
filter on an attribute or *combination *of attributes. For example, the
predicate could return p has attributes A and B but *not* attribute C.
Instantly we have full database query capabilities. If we then hoist the
resulting node we see *all and only* those nodes satisfying the query.
Here is c.findNodeByPredicate. *Important*: Rev c8a3581c9b corrects a
serious blunder in c.cloneFindByPredicate. Don't use previous versions!
def cloneFindByPredicate(self,
generator, # The generator used to traverse the tree.
predicate, # A function of one argument p, returning True
# if p should be included in the results.
flatten=False, # True: Put all matches at the top level.
undoType=None, # The undo name, shown in the Edit:Undo menu.
# The default is 'clone-find-predicate'
):
'''
Traverse the tree given using the generator, cloning all positions
for which predicate(p) is True. Undoably move all clones to a new
node, created as the last top-level node. Arguments:
generator, The generator used to traverse the tree.
predicate, A function of one argument p returning true if
p should be included.
flatten=False, True: Move all node to be parents of the root node.
undo_type=None, The undo/redo name shown in the Edit:Undo menu.
The default is 'clone-find-predicate'
'''
c = self
u, undoType = c.undoer, undoType or 'clone-find-predicate'
clones, seen = [], set(),
for p in generator():
if predicate(p) and p.v not in seen:
if flatten:
seen.add(p.v)
else:
for p2 in p.self_and_subtree():
seen.add(p2.v)
clones.append(p.copy())
if clones:
undoData = u.beforeInsertNode(c.p)
root = c.createCloneFindPredicateRoot(flatten, undoType)
# This was botched in previous versions.
# The result was low-level vnode failures.
for p in clones:
clone = p.clone()
clone.moveToLastChildOf(root)
u.afterInsertNode(root, undoType, undoData, dirtyVnodeList=[])
c.selectPosition(root)
c.setChanged(True)
c.redraw()
else:
g.es_print('not found:', undoType)
Imo, this is the dawn of a new era in Leo's database capabilities.
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.