Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add truncate-at-node for timestamp-based undo-list truncation #111

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ should pop up. To move around, type:
m to mark the current node for diff
u to unmark the marked node
d to show a diff between the marked (or parent) and current nodes
K to truncate the undo list prior to a selected time-stamped node

q to quit, you can also type C-g

Expand Down
65 changes: 65 additions & 0 deletions vundo.el
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
;; m to mark the current node for diff
;; u to unmark the marked node
;; d to show a diff between the marked (or parent) and current nodes
;; K to truncate the undo list prior to a selected time-stamped node
;;
;; q to quit, you can also type C-g
;;
Expand Down Expand Up @@ -161,6 +162,7 @@
(require 'cl-lib)
(require 'seq)
(require 'subr-x)
(require 'time-date)

;;; Customization

Expand Down Expand Up @@ -768,6 +770,7 @@ WINDOW is the window that was/is displaying the vundo buffer."
(define-key map (kbd "d") #'vundo-diff)
(define-key map (kbd "i") #'vundo--inspect)
(define-key map (kbd "D") #'vundo--debug)
(define-key map (kbd "K") #'vundo-truncate-undo-at-node)

(define-key map [remap save-buffer] #'vundo-save)
map)
Expand Down Expand Up @@ -941,6 +944,68 @@ Consults the alist of TIMESTAMPS. This moves the overlay
(move-overlay vundo--highlight-last-saved-overlay
(1- node-pt) node-pt))))

(defun vundo-truncate-undo-at-node (node &optional timestamp)
"Truncate the buffer's undo list, removing entries before NODE.
If TIMESTAMP is provided and NODE is nil, use the timestamp to
identify a saved node to trim to. Interactively, NODE is
selected based on its saved timestamp, if any saved nodes exist."
(interactive
(let* ((undo-cnt (length (buffer-local-value
'buffer-undo-list vundo--orig-buffer)))
(ts-list
(mapcar
(lambda (entry)
(cons (format-time-string "%FT%T%z" (cdr entry)) entry))
(reverse (seq-filter
(lambda (e) ; anything to remove?
(and (car e) (cdr (vundo-m-undo-list (car e)))))
vundo--timestamps))))
(annotation-function
(lambda (time-string)
(let* ((entry (alist-get time-string ts-list nil nil #'equal))
(age (seconds-to-string (float-time (time-since (cdr entry)))))
(trim-cnt (length (cdr (vundo-m-undo-list (car entry)))))
(percentage (* 100 (/ (float trim-cnt) undo-cnt)))
(str (format "(%d records, %0.1f%%)" trim-cnt percentage))
(l (length str)))
(concat " [" age "]"
(propertize " " 'display
`(space :align-to (- right ,l)))
str))))
(table (lambda (string pred action)
(if (eq action 'metadata) ; timestamps pre-sorted
`(metadata (display-sort-function . ,#'identity)
(annotation-function . ,annotation-function))
(complete-with-action action ts-list string pred)))))
(or (and ts-list
(let* ((key (completing-read "Trim undo records prior to timestamp: "
table nil t))
(entry (alist-get key ts-list nil nil #'equal)))
(list (car entry) (cdr entry))))
(progn (message "No timestamps found.")
(list nil nil)))))
(if (and (null node) timestamp)
(setq node (car (cl-find-if (lambda (x) (equal (cdr x) timestamp))
vundo--timestamps))))
(if (and node
(or (not (called-interactively-p 'interactive))
(yes-or-no-p
(format "Permanently remove all undo information prior to %s? "
(if timestamp (format-time-string "%FT%T%z" timestamp)
"this node")))))
(progn
(let* ((undo-list (vundo-m-undo-list node))
(len (length (cdr undo-list))))
(setcdr undo-list nil)
(when (called-interactively-p 'interactive)
(message "Trimmed %d undo-list records" len)))
(vundo--refresh-buffer vundo--orig-buffer (current-buffer))
(when vundo--roll-back-to-this
(setq vundo--roll-back-to-this
(vundo--current-node vundo--prev-mod-list))))
(when (called-interactively-p 'interactive)
(message "No undo-list records removed"))))

;;;###autoload
(defun vundo ()
"Display visual undo for the current buffer."
Expand Down