[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#23906: 25.0.95; Undo boundary after process output is not consistent
From: |
Stefan Monnier |
Subject: |
bug#23906: 25.0.95; Undo boundary after process output is not consistent |
Date: |
Mon, 18 Jul 2016 00:18:36 -0400 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/25.1.50 (gnu/linux) |
> Please let us use this opportunity to fix the more general case
> too. Stefan agreed that the following primitives would work:
> -) undo-begin-transaction
> Starts a new transaction.
> -) undo-end-transaction
> Ends the most recently started undo transaction.
> The effects of all commands between would be undone as a single unit.
How 'bout the patch below (see the viper part to get an idea about how
to use it in ediprolog)?
Stefan
diff --git a/lisp/simple.el b/lisp/simple.el
index f114235..e54d4f2 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -3054,6 +3054,41 @@ undo-auto--undoable-change
(undo-auto--boundary-ensure-timer))
;; End auto-boundary section
+(defun undo-amalgamate-change-group (handle)
+ "Amalgamate changes in change-group since HANDLE.
+Remove all undo boundaries between the state of HANDLE and now.
+HANDLE is as returned by `prepare-change-group'."
+ (dolist (elt handle)
+ (with-current-buffer (car elt)
+ (setq elt (cdr elt))
+ (when (consp buffer-undo-list)
+ (let ((old-car (car-safe elt))
+ (old-cdr (cdr-safe elt)))
+ (unwind-protect
+ (progn
+ ;; Temporarily truncate the undo log at ELT.
+ (when (consp elt)
+ (setcar elt t) (setcdr elt nil))
+ (when
+ (or (null elt) ;The undo-log was empty.
+ ;; `elt' is still in the log: normal case.
+ (eq elt (last buffer-undo-list))
+ ;; `elt' is not in the log any more, but that's because
+ ;; the log is "all new", so we should remove all
+ ;; boundaries from it.
+ (not (eq (last buffer-undo-list) (last old-cdr))))
+ (cl-callf (lambda (x) (delq nil x))
+ (if (car buffer-undo-list)
+ buffer-undo-list
+ ;; Preserve the undo-boundaries at either ends of the
+ ;; change-groups.
+ (cdr buffer-undo-list)))))
+ ;; Reset the modified cons cell ELT to its original content.
+ (when (consp elt)
+ (setcar elt old-car)
+ (setcdr elt old-cdr))))))))
+
+
(defcustom undo-ask-before-discard nil
"If non-nil ask about discarding undo info for the current command.
Normally, Emacs discards the undo info for the current command if
diff --git a/lisp/emulation/viper-cmd.el b/lisp/emulation/viper-cmd.el
index 3d9d1cc..3ce1b4d 100644
--- a/lisp/emulation/viper-cmd.el
+++ b/lisp/emulation/viper-cmd.el
@@ -1709,40 +1709,20 @@ viper-undo-more
;; The following two functions are used to set up undo properly.
;; In VI, unlike Emacs, if you open a line, say, and add a bunch of lines,
;; they are undone all at once.
-(defun viper-adjust-undo ()
- (if viper-undo-needs-adjustment
- (let ((inhibit-quit t)
- tmp tmp2)
- (setq viper-undo-needs-adjustment nil)
- (when (listp buffer-undo-list)
- (let ((had-boundary (null (car buffer-undo-list))))
- (if (setq tmp (memq viper-buffer-undo-list-mark buffer-undo-list))
- (progn
- (setq tmp2 (cdr tmp)) ; the part after mark
-
- ;; cut tail from buffer-undo-list temporarily by direct
- ;; manipulation with pointers in buffer-undo-list
- (setcdr tmp nil)
-
- (setq buffer-undo-list (delq nil buffer-undo-list))
- (setq buffer-undo-list
- (delq viper-buffer-undo-list-mark buffer-undo-list))
- ;; restore tail of buffer-undo-list
- (setq buffer-undo-list (nconc buffer-undo-list tmp2)))
- (setq buffer-undo-list (delq nil buffer-undo-list)))
- ;; The top-level loop only adds boundaries if there has been
- ;; modifications in the buffer, so make sure we don't accidentally
- ;; drop the "final" boundary (bug#22295).
- (if had-boundary (undo-boundary)))))))
+(viper-deflocalvar viper--undo-change-group-handle nil)
+(put 'viper--undo-change-group-handle 'permanent-local t)
+(defun viper-adjust-undo ()
+ (when viper--undo-change-group-handle
+ (undo-amalgamate-change-group
+ (prog1 viper--undo-change-group-handle
+ (setq viper--undo-change-group-handle nil)))))
(defun viper-set-complex-command-for-undo ()
- (if (listp buffer-undo-list)
- (if (not viper-undo-needs-adjustment)
- (let ((inhibit-quit t))
- (setq buffer-undo-list
- (cons viper-buffer-undo-list-mark buffer-undo-list))
- (setq viper-undo-needs-adjustment t)))))
+ (and (listp buffer-undo-list)
+ (not viper--undo-change-group-handle)
+ (setq viper--undo-change-group-handle
+ (prepare-change-group))))
;;; Viper's destructive Command ring utilities
diff --git a/lisp/emulation/viper-init.el b/lisp/emulation/viper-init.el
index 086daf2..838d846 100644
--- a/lisp/emulation/viper-init.el
+++ b/lisp/emulation/viper-init.el
@@ -369,15 +369,6 @@ viper-set-input-method
;; VI-style Undo
-;; Used to 'undo' complex commands, such as replace and insert commands.
-(viper-deflocalvar viper-undo-needs-adjustment nil)
-(put 'viper-undo-needs-adjustment 'permanent-local t)
-
-;; A mark that Viper puts on buffer-undo-list. Marks the beginning of a
-;; complex command that must be undone atomically. If inserted, it is
-;; erased by viper-change-state-to-vi and viper-repeat.
-(defconst viper-buffer-undo-list-mark 'viper)
-
(defcustom viper-keep-point-on-undo nil
"Non-nil means not to move point while undoing commands.
This style is different from Emacs and Vi. Try it to see if
- bug#23906: 25.0.95; Undo boundary after process output is not consistent, (continued)
- bug#23906: 25.0.95; Undo boundary after process output is not consistent, Markus Triska, 2016/07/12
- bug#23906: 25.0.95; Undo boundary after process output is not consistent, Phillip Lord, 2016/07/13
- bug#23906: 25.0.95; Undo boundary after process output is not consistent, Markus Triska, 2016/07/14
- bug#23906: 25.0.95; Undo boundary after process output is not consistent, Phillip Lord, 2016/07/14
- bug#23906: 25.0.95; Undo boundary after process output is not consistent, Markus Triska, 2016/07/14
- bug#23906: 25.0.95; Undo boundary after process output is not consistent, Phillip Lord, 2016/07/14
- bug#23906: 25.0.95; Undo boundary after process output is not consistent, Stefan Monnier, 2016/07/14
- bug#23906: 25.0.95; Undo boundary after process output is not consistent,
Stefan Monnier <=
- bug#23906: 25.0.95; Undo boundary after process output is not consistent, Markus Triska, 2016/07/18
- bug#23906: 25.0.95; Undo boundary after process output is not consistent, Stefan Monnier, 2016/07/18
- bug#23906: 25.0.95; Undo boundary after process output is not consistent, Stefan Monnier, 2016/07/18
- bug#23906: 25.0.95; Undo boundary after process output is not consistent, Phillip Lord, 2016/07/24
- bug#23906: 25.0.95; Undo boundary after process output is not consistent, Stefan Monnier, 2016/07/24
- bug#23906: 25.0.95; Undo boundary after process output is not consistent, Phillip Lord, 2016/07/13
- bug#23906: 25.0.95; Undo boundary after process output is not consistent, Markus Triska, 2016/07/13
- bug#23906: 25.0.95; Undo boundary after process output is not consistent, Phillip Lord, 2016/07/13