I am working on my own new feature request for undo-tree linear undo/redo: How to make undo-tree linear -- undo-tree-undo/redo

I have successfully added two additional gizmos (?) to cl-defstruct ... undo-tree-node at the bottom and very end of the definition -- connect-dots and linear-history. The new functions are called like this: (undo-tree-node-connect-dots (undo-tree-current buffer-undo-tree)) or (undo-tree-node-history (undo-tree-current buffer-undo-tree)).

I am adding a list of time-stamps to each node when they are imported from the buffer-undo-list with undo-list-transfer-to-tree, and also to the final current node when using undo-tree-undo and undo-tree-redo. The result should be that every node has a list of one or more time-stamps that never change -- i.e., I just keep pushing new time-stamps onto whichever node is current.

undo-tree creates the visualizer buffer by starting from the root and following the branch until a branch-point is reached, at which time it branches into 2 or more, etc. In a nutshell, the parent knows who it siblings are, and the siblings know who the parent is. I can create a function that does not use a visualizer buffer, which follows the above tree-structure until the very end, but that seems like an inefficient manner to map through all of the nodes. [I envision this linear undo/redo new feature as being usable irrespective of whether the visualizer buffer has been generated.]

Q:  Absent following the tree structure programmatically, is there a more efficient manner to map through each node of the buffer-undo-tree?  [E.g., (dolist (node buffer-undo-tree) (when node ...))

In case anyone was wondering about connect-dots, at this time it is just an interesting way of seeing each branch with a different letter and each node is consecutively numbered between root and branch-point, and between each branch-point and leaf. I may consolidate that feature with the linear visualization, but each node may have more than one time-stamp, so I'll need to think about how to visually represent that.

Thanks to the helpful answer by @Tobias below, I came up with the following function that generates a list of all nodes. undo-tree-mapc is designed to apply a function to each node, which is also useful.

(defun undo-tree-node-list (&optional transfer-to-tree)
"See also `undo-tree-mapc'."
  (when transfer-to-tree
  (let* ((beginning-node (undo-tree-root buffer-undo-tree))
         (stack (list beginning-node))
         n res)
    (while stack
      (setq n (pop stack))
      (push n res)
      (setq stack (append (undo-tree-node-next n) stack)))

1 Answer 1


Example (can be run in the *scratch* buffer):

  (undo-tree-mapc (lambda (node) (message "\n%s" node)) (undo-tree-root buffer-undo-tree)))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.