aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2016-07-18 21:04:39 -0400
committerStefan Monnier2016-07-18 21:04:39 -0400
commit99fe98d37a39d26f5dea424926d0e0a082655fe5 (patch)
tree636e1f79d4b85206ea7281f08ad053fb84902abe
parent73f0715df53c6a12a3d9039ac1a1664d30c293ff (diff)
downloademacs-99fe98d37a39d26f5dea424926d0e0a082655fe5.tar.gz
emacs-99fe98d37a39d26f5dea424926d0e0a082655fe5.zip
* lisp/simple.el (undo-amalgamate-change-group): New function
* lisp/emulation/viper-cmd.el (viper-adjust-undo): Use it. (viper-set-complex-command-for-undo): Save current state with prepare-change-group. * lisp/emulation/viper-init.el (viper-undo-needs-adjustment) (viper-buffer-undo-list-mark): Remove.
-rw-r--r--etc/NEWS3
-rw-r--r--lisp/emulation/viper-cmd.el42
-rw-r--r--lisp/emulation/viper-init.el9
-rw-r--r--lisp/simple.el35
4 files changed, 49 insertions, 40 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 403a6b7ee36..e01f180e711 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -458,6 +458,9 @@ function 'check-declare-errmsg' has been removed.
458 458
459* Lisp Changes in Emacs 25.2 459* Lisp Changes in Emacs 25.2
460 460
461** New function undo-amalgamate-change-group to get rid of undo-boundaries
462between two states.
463
461** New var `definition-prefixes' is a hashtable mapping prefixes to the 464** New var `definition-prefixes' is a hashtable mapping prefixes to the
462files where corresponding definitions can be found. This can be used 465files where corresponding definitions can be found. This can be used
463to fetch definitions that are not yet loaded, for example for `C-h f'. 466to fetch definitions that are not yet loaded, for example for `C-h f'.
diff --git a/lisp/emulation/viper-cmd.el b/lisp/emulation/viper-cmd.el
index 3d9d1cc59f2..3ce1b4d6a75 100644
--- a/lisp/emulation/viper-cmd.el
+++ b/lisp/emulation/viper-cmd.el
@@ -1709,40 +1709,20 @@ invokes the command before that, etc."
1709;; The following two functions are used to set up undo properly. 1709;; The following two functions are used to set up undo properly.
1710;; In VI, unlike Emacs, if you open a line, say, and add a bunch of lines, 1710;; In VI, unlike Emacs, if you open a line, say, and add a bunch of lines,
1711;; they are undone all at once. 1711;; they are undone all at once.
1712(defun viper-adjust-undo () 1712(viper-deflocalvar viper--undo-change-group-handle nil)
1713 (if viper-undo-needs-adjustment 1713(put 'viper--undo-change-group-handle 'permanent-local t)
1714 (let ((inhibit-quit t)
1715 tmp tmp2)
1716 (setq viper-undo-needs-adjustment nil)
1717 (when (listp buffer-undo-list)
1718 (let ((had-boundary (null (car buffer-undo-list))))
1719 (if (setq tmp (memq viper-buffer-undo-list-mark buffer-undo-list))
1720 (progn
1721 (setq tmp2 (cdr tmp)) ; the part after mark
1722
1723 ;; cut tail from buffer-undo-list temporarily by direct
1724 ;; manipulation with pointers in buffer-undo-list
1725 (setcdr tmp nil)
1726
1727 (setq buffer-undo-list (delq nil buffer-undo-list))
1728 (setq buffer-undo-list
1729 (delq viper-buffer-undo-list-mark buffer-undo-list))
1730 ;; restore tail of buffer-undo-list
1731 (setq buffer-undo-list (nconc buffer-undo-list tmp2)))
1732 (setq buffer-undo-list (delq nil buffer-undo-list)))
1733 ;; The top-level loop only adds boundaries if there has been
1734 ;; modifications in the buffer, so make sure we don't accidentally
1735 ;; drop the "final" boundary (bug#22295).
1736 (if had-boundary (undo-boundary)))))))
1737 1714
1715(defun viper-adjust-undo ()
1716 (when viper--undo-change-group-handle
1717 (undo-amalgamate-change-group
1718 (prog1 viper--undo-change-group-handle
1719 (setq viper--undo-change-group-handle nil)))))
1738 1720
1739(defun viper-set-complex-command-for-undo () 1721(defun viper-set-complex-command-for-undo ()
1740 (if (listp buffer-undo-list) 1722 (and (listp buffer-undo-list)
1741 (if (not viper-undo-needs-adjustment) 1723 (not viper--undo-change-group-handle)
1742 (let ((inhibit-quit t)) 1724 (setq viper--undo-change-group-handle
1743 (setq buffer-undo-list 1725 (prepare-change-group))))
1744 (cons viper-buffer-undo-list-mark buffer-undo-list))
1745 (setq viper-undo-needs-adjustment t)))))
1746 1726
1747 1727
1748;;; Viper's destructive Command ring utilities 1728;;; Viper's destructive Command ring utilities
diff --git a/lisp/emulation/viper-init.el b/lisp/emulation/viper-init.el
index cd71925590a..ee093906771 100644
--- a/lisp/emulation/viper-init.el
+++ b/lisp/emulation/viper-init.el
@@ -369,15 +369,6 @@ Use `\\[viper-set-expert-level]' to change this.")
369 369
370;; VI-style Undo 370;; VI-style Undo
371 371
372;; Used to 'undo' complex commands, such as replace and insert commands.
373(viper-deflocalvar viper-undo-needs-adjustment nil)
374(put 'viper-undo-needs-adjustment 'permanent-local t)
375
376;; A mark that Viper puts on buffer-undo-list. Marks the beginning of a
377;; complex command that must be undone atomically. If inserted, it is
378;; erased by viper-change-state-to-vi and viper-repeat.
379(defconst viper-buffer-undo-list-mark 'viper)
380
381(defcustom viper-keep-point-on-undo nil 372(defcustom viper-keep-point-on-undo nil
382 "Non-nil means not to move point while undoing commands. 373 "Non-nil means not to move point while undoing commands.
383This style is different from Emacs and Vi. Try it to see if 374This style is different from Emacs and Vi. Try it to see if
diff --git a/lisp/simple.el b/lisp/simple.el
index a757876328b..51c9100d2c2 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -2958,6 +2958,41 @@ behavior."
2958 (undo-auto--boundary-ensure-timer)) 2958 (undo-auto--boundary-ensure-timer))
2959;; End auto-boundary section 2959;; End auto-boundary section
2960 2960
2961(defun undo-amalgamate-change-group (handle)
2962 "Amalgamate changes in change-group since HANDLE.
2963Remove all undo boundaries between the state of HANDLE and now.
2964HANDLE is as returned by `prepare-change-group'."
2965 (dolist (elt handle)
2966 (with-current-buffer (car elt)
2967 (setq elt (cdr elt))
2968 (when (consp buffer-undo-list)
2969 (let ((old-car (car-safe elt))
2970 (old-cdr (cdr-safe elt)))
2971 (unwind-protect
2972 (progn
2973 ;; Temporarily truncate the undo log at ELT.
2974 (when (consp elt)
2975 (setcar elt t) (setcdr elt nil))
2976 (when
2977 (or (null elt) ;The undo-log was empty.
2978 ;; `elt' is still in the log: normal case.
2979 (eq elt (last buffer-undo-list))
2980 ;; `elt' is not in the log any more, but that's because
2981 ;; the log is "all new", so we should remove all
2982 ;; boundaries from it.
2983 (not (eq (last buffer-undo-list) (last old-cdr))))
2984 (cl-callf (lambda (x) (delq nil x))
2985 (if (car buffer-undo-list)
2986 buffer-undo-list
2987 ;; Preserve the undo-boundaries at either ends of the
2988 ;; change-groups.
2989 (cdr buffer-undo-list)))))
2990 ;; Reset the modified cons cell ELT to its original content.
2991 (when (consp elt)
2992 (setcar elt old-car)
2993 (setcdr elt old-cdr))))))))
2994
2995
2961(defcustom undo-ask-before-discard nil 2996(defcustom undo-ask-before-discard nil
2962 "If non-nil ask about discarding undo info for the current command. 2997 "If non-nil ask about discarding undo info for the current command.
2963Normally, Emacs discards the undo info for the current command if 2998Normally, Emacs discards the undo info for the current command if