1

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
    (undo-list-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)))
    res))
lawlist
  • 18,826
  • 5
  • 37
  • 118

1 Answers1

2

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

(progn
  (undo-list-transfer-to-tree)
  (undo-tree-mapc (lambda (node) (message "\n%s" node)) (undo-tree-root buffer-undo-tree)))
Tobias
  • 32,569
  • 1
  • 34
  • 75