Implement fold undo

This commit is contained in:
Greg Sexton 2014-08-16 18:23:04 +01:00
parent ac970fb8ea
commit f9d284cf3d

View File

@ -151,6 +151,8 @@
(defun origami-fold-data (node) (when node (aref node 5))) (defun origami-fold-data (node) (when node (aref node 5)))
;;; fold structure utils
(defun origami-fold-range-equal (a b) (defun origami-fold-range-equal (a b)
(and (equal (origami-fold-beg a) (origami-fold-beg b)) (and (equal (origami-fold-beg a) (origami-fold-beg b))
(equal (origami-fold-end a) (origami-fold-end b)))) (equal (origami-fold-end a) (origami-fold-end b))))
@ -273,6 +275,7 @@ with the current state and the current node at each iteration."
(defun origami-setup-local-vars (buffer) (defun origami-setup-local-vars (buffer)
(with-current-buffer buffer (with-current-buffer buffer
(set (make-local-variable 'origami-stack) nil)
(set (make-local-variable 'origami-tree) (origami-fold-root-node)) (set (make-local-variable 'origami-tree) (origami-fold-root-node))
(set (make-local-variable 'origami-tree-tick) 0))) (set (make-local-variable 'origami-tree-tick) 0)))
@ -281,12 +284,35 @@ with the current state and the current node at each iteration."
(error "Necessary local variables were not available")) (error "Necessary local variables were not available"))
(buffer-local-value 'origami-tree buffer)) (buffer-local-value 'origami-tree buffer))
(defun origami-get-tree-stack (buffer)
(or (local-variable-p 'origami-stack buffer)
(error "Necessary local variables were not available"))
(buffer-local-value 'origami-stack buffer))
(defun origami-set-tree-stack (buffer stack)
(or (local-variable-p 'origami-stack buffer)
(error "Necessary local variables were not available"))
(with-current-buffer buffer
(setq origami-stack stack)))
(defun origami-push-cached-tree (buffer tree)
;; TODO: size-limit the stack
(let ((stack (origami-get-tree-stack buffer)))
(when (not (eq tree (car stack)))
(origami-set-tree-stack buffer (cons tree stack)))))
(defun origami-pop-cached-tree (buffer)
(-when-let (stack (origami-get-tree-stack buffer))
(origami-set-tree-stack buffer (cdr stack))
(car stack)))
(defun origami-store-cached-tree (buffer tree) (defun origami-store-cached-tree (buffer tree)
(or (local-variable-p 'origami-tree buffer) (or (local-variable-p 'origami-tree buffer)
(local-variable-p 'origami-tree-tick buffer) (local-variable-p 'origami-tree-tick buffer)
(error "Necessary local variables were not available")) (error "Necessary local variables were not available"))
(with-current-buffer buffer (with-current-buffer buffer
(setq origami-tree-tick (buffer-modified-tick)) (setq origami-tree-tick (buffer-modified-tick))
(origami-push-cached-tree buffer tree)
(setq origami-tree tree))) (setq origami-tree tree)))
(defun origami-rebuild-tree? (buffer) (defun origami-rebuild-tree? (buffer)
@ -452,6 +478,8 @@ as to ensure seeing where POINT is."
(defun origami-show-only-node (buffer point) (defun origami-show-only-node (buffer point)
(interactive (list (current-buffer) (point))) (interactive (list (current-buffer) (point)))
(origami-close-all-nodes buffer) (origami-close-all-nodes buffer)
;; pop this intermediate tree state, making this an atomic operation
(origami-pop-cached-tree buffer)
(origami-show-node buffer point)) (origami-show-node buffer point))
(defun origami-previous-fold (buffer point) (defun origami-previous-fold (buffer point)
@ -478,6 +506,12 @@ a fold, move to the end of the fold that point is in."
(->> (-last (lambda (pos) (> pos point)))) (->> (-last (lambda (pos) (> pos point))))
goto-char))) goto-char)))
(defun origami-undo (buffer)
(interactive (list (current-buffer)))
(let ((current-tree (origami-pop-cached-tree buffer))
(old-tree (origami-pop-cached-tree buffer)))
(origami-apply-new-tree buffer current-tree old-tree)))
(defun origami-reset (buffer) (defun origami-reset (buffer)
(interactive (list (current-buffer))) (interactive (list (current-buffer)))
(origami-setup-local-vars buffer) (origami-setup-local-vars buffer)