> > s = g.app.gui.getTextFromClipboard() > undoType = 'Paste As Clone' > c.endEditing() > if not s or not c.canPasteOutline(s): > return # This should never happen. > isLeo = g.match(s, 0, g.app.prolog_prefix_string) > vnodeInfoDict = computeVnodeInfoDict(c) > # create a *position* to be pasted. > if isLeo: > pasted = c.fileCommands.getLeoOutlineFromClipboard(s, > reassignIndices)
This part of code is present in almost all three kinds of paste functions as you have refactored them. However, if you look into c.canPasteOutline you will see that it repeats almost all of the above. It checks to see if s is None and if so it takes value from clipboard, then it checks if it starts with g.app_prolog_prefix_string and if everything is checked returns True. In order to avoid code duplication some other duplication have been made. And it is not easy to spot the duplication and unnecessary code unless you really dive into this code. Proposing three different methods for three kinds of paste commands, I haven't imagined them to be like those. This is just first layer of decomposing code. For example in all three implementations you are using c.fileCommands.getOutlineFromClipboard passing kw flag again. And also same switch is passed to undo methods. Instead, I would recommend further decomposition down the road. By the way, getOutlineFromClipboard ends with call to c.selectPosition(p) where p is newly pasted node. In the above implementations there is also call to select the same position. Also, getOutlineFromClipboard creates at first v node, and then creates a position to hold this v node, then in the above implementations, calls methods of the position class moveToNthChildOf or linkAsNthChildOf which are delegating their jobs to p.v methods. It would be much simpler if getOutlineFromClipboard returns v instance, and then just make link with parent_v. A variable named undoType is introduced in first two methods, just to be used once in the end. It would suffice to use constant string instead. This variable is necessary if pasteOutline performs both kinds of operation. By separating functions this variable can be eliminated and code complexity further reduced. For undoing paste-retaining-clones it would be enough to just cut the link between parent_v and the pasted v node. By definition all nodes inside the pasted outline are exactly the same after paste command. The only difference is one more parent element in v.parents and just in top level pasted node. That is why I strongly suspect that computing a copied bunch is unnecessary too. copiedBunchList = computeCopiedBunchList(c, pasted, vnodeInfoDict) undoData = c.undoer.beforeInsertNode(c.p, pasteAsClone=True, copiedBunchList=copiedBunchList) And there again is a method c.undoer.beforeInsertNode which needs kw flags pasteAsClone to be passed. I would recommend also to have c.undoer.beforePasteClone and c.undoer.afterPasteClone. which should be extremely simply. After all if there are common parts of these three kinds of paste methods then we can extract them and have: def pasteOutlineRetainingClones(self, p): (childIndex, undodata, txt,...) = prePasteNodeCommon(p, c.undoer.beforePasteRetainingClone) ... # specific to retaining clones variant v = getVnodeFromString(txt) # somehow see our discussion on #862 if v: postPasteNodeCommon(p, v, undodata, c.undoer.afterPasteRetainingClone) def pasteOutline(self, p): (childIndex, undodata, txt, ...) = prePasteNodeCommon(p, c.undoer.beforePasteNoClone) ... # specific to paste no clones v = getVnodeFromStringWithNewIndices(txt) if v: postPasteNodeCommon(p, v, c.undoer.afterPasteNoClone) def pasteFromString(self, p, txt): (childIndex, undodata, dummy, ...) = prePasteNodeCommon(p, lambda *args: None, txt) ... # specific to paste from string v = getVnodeFromStringWithNewIndices(txt) # no undo def prePasteNodeCommon(p, undoMethod): c.endEditing() ... # decide where to paste: parent_v and childIndex # based on expanded/collapsed state of current position ... txt = g.app.gui.getTextFromClipboard() undodata = undoMethod(c.undoer, ...) return childIndex, undodata, txt, ... def postPasteNodeCommon(p, v, undodata, undoMethod): # make link v.parents.append(p.v) p.v.children.insert(childIndex, v) undoMethod(c.undoer, undodata) This is not complete code just a blueprint. But implemented this way would look much better and point out in more contrast the difference from the current implementation. Vitalije -- 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 post to this group, send email to leo-editor@googlegroups.com. Visit this group at https://groups.google.com/group/leo-editor. For more options, visit https://groups.google.com/d/optout.