Created
April 11, 2018 03:56
-
-
Save lawlist/8bc2c575ff709aee52faa893a8521bda to your computer and use it in GitHub Desktop.
undo-tree-debug-structs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
https://emacs.stackexchange.com/q/34314/2287 | |
undo-tree: Create a separate copy of `buffer-undo-tree` in Emacs 26.0.50 | |
Q: Using Emacs 26.0.50, how to copy the buffer-undo-tree preserving the structure and create a completely separate copy -- including the hash-table (aka object-pool)? | |
When using Emacs 25.2.1, setting the hash-table of the copy of buffer-undo-tree to a nil value does not alter the original buffer-undo-tree. | |
When using Emacs 26.0.50 (master branch), setting the hash-table of the copy of buffer-undo-tree to a nil value alters the original buffer-undo-tree -- setting it to nil. | |
A wild guess is that setf or cl-defstruct may have undergone improvements [?] in the master branch that have lead to this new problem. | |
STEP 1: Download the latest version of undo-tree.el from the emacs mirror. | |
https://github.com/emacsmirror/undo-tree/archive/master.zip | |
STEP 2: Extract undo-tree.el from the zipped archive that was downloaded in the first step. | |
STEP 3: Launch Emacs without any user configuration; i.e., emacs -q. | |
STEP 4: Open undo-tree.el with Emacs and evaluate the buffer; e.g., M-x eval-buffer. | |
STEP 5: Switch to the *scratch* buffer, paste the structure preserving copy-tree*... functions written by @Tobias, and evaluate the buffer; e.g., M-x eval-buffer. | |
(require 'cl) | |
;;; Written by @Tobias: https://emacs.stackexchange.com/a/32230/2287 | |
(cl-defstruct (copy-tree* | |
(:constructor copy-tree*-mem | |
(&optional stack stack-new (hash (make-hash-table))))) | |
stack stack-new hash) | |
(defmacro copy-tree*--push (el el-new mem &optional hash) | |
"Written by @Tobias: https://emacs.stackexchange.com/a/32230/2287" | |
(let ((my-el (make-symbol "my-el")) | |
;; makes sure `el' is only evaluated once | |
(my-el-new (make-symbol "my-el-new"))) | |
(append `(let ((,my-el ,el) | |
(,my-el-new ,el-new)) | |
(push ,my-el (copy-tree*-stack ,mem)) | |
(push ,my-el-new (copy-tree*-stack-new ,mem))) | |
(and hash | |
`((puthash ,my-el ,my-el-new (copy-tree*-hash ,mem)))) | |
(list my-el-new)))) | |
(defmacro copy-tree*--pop (el el-new mem) | |
"Written by @Tobias: https://emacs.stackexchange.com/a/32230/2287" | |
`(setq ,el (pop (copy-tree*-stack ,mem)) | |
,el-new (pop (copy-tree*-stack-new mem)))) | |
(defun copy-tree*--copy-node (node mem vecp) | |
"Written by @Tobias: https://emacs.stackexchange.com/a/32230/2287" | |
(if (or (consp node) | |
(and vecp (vectorp node))) | |
(let ((existing-node (gethash node (copy-tree*-hash mem)))) | |
(if existing-node | |
existing-node | |
(copy-tree*--push node (if (consp node) | |
(cons nil nil) | |
(make-vector (length node) nil)) | |
mem t))) | |
node)) | |
(defun copy-tree* (tree &optional vecp) | |
"Written by @Tobias: https://emacs.stackexchange.com/a/32230/2287" | |
(if (or (consp tree) | |
(and vecp (vectorp tree))) | |
(let* ((tree-new (if (consp tree) (cons nil nil) | |
(make-vector (length tree) nil))) | |
(mem (copy-tree*-mem)) | |
next | |
next-new) | |
(copy-tree*--push tree tree-new mem t) | |
(while (copy-tree*--pop next next-new mem) | |
(cond | |
((consp next) | |
(setcar next-new (copy-tree*--copy-node (car next) mem vecp)) | |
(setcdr next-new (copy-tree*--copy-node (cdr next) mem vecp))) | |
((and vecp (vectorp next)) | |
(cl-loop for i from 0 below (length next) do | |
(aset next-new i | |
(copy-tree*--copy-node (aref next i) mem vecp)))))) | |
tree-new) | |
tree)) | |
STEP 6: Evaluate (undo-list-transfer-to-tree) | |
STEP 7: Evaluate (setq foo (copy-tree* buffer-undo-tree 'vecp)) | |
STEP 8: Evaluate (setf (undo-tree-object-pool foo) nil) | |
STEP 9: Evaluate (undo-tree-object-pool buffer-undo-tree) | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
Possibly relevant: structs are now records in Emacs 26, before they were just vectors | |
with a special symbol in the first element. – `npostavs` Jul 20 '17 at 21:08 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment