[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/undo-tree d7c1b2c 118/195: "De-circle" undo-tree when s
From: |
Stefan Monnier |
Subject: |
[elpa] externals/undo-tree d7c1b2c 118/195: "De-circle" undo-tree when saving to file, restore when loading. |
Date: |
Sat, 28 Nov 2020 13:41:34 -0500 (EST) |
branch: externals/undo-tree
commit d7c1b2c3cbe53c87dcc55710ed96aedd7fbc15ad
Author: Toby S. Cubitt <toby-undo-tree@dr-qubit.org>
Commit: Toby S. Cubitt <toby-undo-tree@dr-qubit.org>
"De-circle" undo-tree when saving to file, restore when loading.
Loading large undo-trees is too slow to be usable. Removing back-links from
the tree before saving, and restoring them when loading, speeds things up.
Note that this makes the written data almost but not quite non-circular; the
pointer to the current node is still written as a circular reference "#1".
---
undo-tree.el | 69 +++++++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 54 insertions(+), 15 deletions(-)
diff --git a/undo-tree.el b/undo-tree.el
index ee23e3e..48a1208 100644
--- a/undo-tree.el
+++ b/undo-tree.el
@@ -730,6 +730,10 @@
;; * install history auto-save hooks globally, otherwise
;; `undo-tree-load-history-hook' doesn't run because file has already been
;; loaded before `undo-tree-mode' has installed the hook function
+;; * add `undo-tree-decircle' and `undo-tree-recircle' functions to,
+;; respecrively, nullify and restore `previous' links in undo-tree nodes
+;; * speed up history saving and (especially) loading by "de-circling"
+;; undo-tree data before writing to file and "re-circling" it on load
;;
;; Version 0.5.3
;; * modified `undo-list-transfer-to-tree' and `undo-list-pop-changeset' to
@@ -1676,6 +1680,26 @@ Comparison is done with `eq'."
(make-symbol (format "undo-tree-id%d" num))))
+(defun undo-tree-decircle (tree)
+ ;; Nullify PREVIOUS links of undo-tree-nodes, to make undo-tree data
+ ;; structure non-circular.
+ (undo-tree-mapc
+ (lambda (node)
+ (dolist (n (undo-tree-node-next node))
+ (setf (undo-tree-node-previous n) nil)))
+ tree))
+
+
+(defun undo-tree-recircle (tree)
+ ;; Recreate PREVIOUS links of undo-tree-nodes, to restore circular undo-tree
+ ;; data structure.
+ (undo-tree-mapc
+ (lambda (node)
+ (dolist (n (undo-tree-node-next node))
+ (setf (undo-tree-node-previous n) node)))
+ tree))
+
+
;;; =====================================================================
@@ -3051,6 +3075,10 @@ Argument is a character, naming the register."
+
+;;; =====================================================================
+;;; Persistent storage
+
(defun undo-tree-make-history-save-file-name (file)
"Create the undo history file name for FILE.
Normally this is the file's name with `.' prepended and
@@ -3081,7 +3109,7 @@ without asking for confirmation."
(undo-tree-kill-visualizer)
(error (undo-tree-clear-visualizer-data buffer-undo-tree)))
(let ((buff (current-buffer))
- (tree (copy-undo-tree buffer-undo-tree)))
+ tree)
;; get filename
(unless filename
(setq filename
@@ -3091,20 +3119,29 @@ without asking for confirmation."
(when (or (not (file-exists-p filename))
overwrite
(yes-or-no-p (format "Overwrite \"%s\"? " filename)))
- ;; discard undo-tree object pool before saving
- (setf (undo-tree-object-pool tree) nil)
- ;; print undo-tree to file
- ;; NOTE: We use `with-temp-buffer' instead of `with-temp-file' to
- ;; allow `auto-compression-mode' to take effect, in case user
- ;; has overridden or advised the default
- ;; `undo-tree-make-history-save-file-name' to add a compressed
- ;; file extension.
- (with-auto-compression-mode
- (with-temp-buffer
- (prin1 (sha1 buff) (current-buffer))
- (terpri (current-buffer))
- (let ((print-circle t)) (prin1 tree (current-buffer)))
- (write-region nil nil filename)))))))
+ (unwind-protect
+ (progn
+ ;; transform undo-tree into non-circular structure, and make
+ ;; temporary copy
+ (undo-tree-decircle buffer-undo-tree)
+ (setq tree (copy-undo-tree buffer-undo-tree))
+ ;; discard undo-tree object pool before saving
+ (setf (undo-tree-object-pool tree) nil)
+ ;; print undo-tree to file
+ ;; NOTE: We use `with-temp-buffer' instead of `with-temp-file'
+ ;; to allow `auto-compression-mode' to take effect, in
+ ;; case user has overridden or advised the default
+ ;; `undo-tree-make-history-save-file-name' to add a
+ ;; compressed file extension.
+ (with-auto-compression-mode
+ (with-temp-buffer
+ (prin1 (sha1 buff) (current-buffer))
+ (terpri (current-buffer))
+ (let ((print-circle t)) (prin1 tree (current-buffer)))
+ (write-region nil nil filename))))
+ ;; restore circular undo-tree data structure
+ (undo-tree-recircle buffer-undo-tree))
+ ))))
@@ -3161,6 +3198,8 @@ signaling an error if file is not found."
;; initialise empty undo-tree object pool
(setf (undo-tree-object-pool tree)
(make-hash-table :test 'eq :weakness 'value))
+ ;; restore circular undo-tree data structure
+ (undo-tree-recircle tree)
(setq buffer-undo-tree tree))))
- [elpa] externals/undo-tree d6fa2e7 152/195: Reinstate accidentally deleted file header., (continued)
- [elpa] externals/undo-tree d6fa2e7 152/195: Reinstate accidentally deleted file header., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree 8afead1 162/195: Add Maintainer line to package headers., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree e9a9102 164/195: Throw error if interactive commands called outside undo-tree-mode., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree ffd18cd 175/195: Refactor undo-list-transfer-to-tree again in attempt to mitigate GC races., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree 941bfe5 190/195: Don't attempt to save undo history if history file is unwritable., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree 5a1ba84 017/195: Added standard Elisp package headers, including an extensive Commentary., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree 62e6097 044/195: Added undo-tree-save/restore-state-to/from-register commands and keybindings, Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree c638cbd 051/195: General code tidying and reorganisation., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree caa3bd0 082/195: Added new customization option to allow undo-in-region to be disabled., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree 8972e4d 069/195: Use get-buffer-create when creating the visualizer buffer in undo-tree-visualize., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree d7c1b2c 118/195: "De-circle" undo-tree when saving to file, restore when loading.,
Stefan Monnier <=
- [elpa] externals/undo-tree 121cab9 136/195: Trivial typo fixes in comments., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree 18754c1 114/195: Use with-temp-buffer instead of with-temp-file when saving undo history., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree c9f78c3 137/195: Use new user-error instead of error for expected undo errors., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree 1114679 135/195: Fix bugs in binding of undo-tree-insert-face., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree 5d19d4e 155/195: Bump version number and copyright year., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree ffb346a 157/195: Install undo-tree undo/redo Edit menu bar items., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree 19baf49 158/195: Fix undo/redo-in-region tree diagrams in Commentary., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree 22d6c01 153/195: Fix bug that cleared tree when enabling undo-tree-mode., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree 46639dd 154/195: Tweak undo history file names to match Emacs backup file names., Stefan Monnier, 2020/11/28
- [elpa] externals/undo-tree fba51e6 146/195: Add undo-tree-visualizer[-mouse]-select functions to select node at pos or click., Stefan Monnier, 2020/11/28