emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] fix/no-undo-boundary-on-secondary-buffer-change fa9c238 1/


From: Phillip Lord
Subject: [Emacs-diffs] fix/no-undo-boundary-on-secondary-buffer-change fa9c238 1/4: Cosmetic changes and introduction of some more state!
Date: Wed, 21 Oct 2015 07:09:57 +0000

branch: fix/no-undo-boundary-on-secondary-buffer-change
commit fa9c23877c05d9f397c8a0141e59bff66da2cb03
Author: Phillip Lord <address@hidden>
Commit: Phillip Lord <address@hidden>

    Cosmetic changes and introduction of some more state!
    
    This now handles amalgamation for both self-insert-command
    and delete-char (and can be extended freely for any command).
---
 lisp/simple.el |  146 +++++++++++++++++++++++++++++--------------------------
 src/cmds.c     |   15 +++---
 src/keyboard.c |    4 ++
 src/undo.c     |   21 +++-----
 4 files changed, 95 insertions(+), 91 deletions(-)

diff --git a/lisp/simple.el b/lisp/simple.el
index a2421df..e090f8f 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -27,6 +27,7 @@
 ;; major mode or to file-handling.
 
 ;;; Code:
+
 (eval-when-compile (require 'cl-lib))
 
 (declare-function widget-convert "wid-edit" (type &rest args))
@@ -2244,10 +2245,6 @@ as an argument limits undo to changes within the current 
region."
     ;; the next command should not be a "consecutive undo".
     ;; So set `this-command' to something other than `undo'.
     (setq this-command 'undo-start)
-    ;; We need to set `undo-last-boundary' to nil as we are about to
-    ;; delete the last boundary, so we want to not assume anything about
-    ;; the boundary before this one
-    (setq undo-last-boundary nil)
     (unless (and (eq last-command 'undo)
                 (or (eq pending-undo-list t)
                     ;; If something (a timer or filter?) changed the buffer
@@ -2758,18 +2755,9 @@ with < or <= based on USE-<."
 
 ;; Default undo-boundary addition
 ;;
-;; This section helps to prevent undo-lists from getting too large. It
-;; achieves by checking that no buffer has an undo-list which is large
-;; and has no `undo-boundary', a condition that will block garbage
-;; collection of that list. This happens silently and in most cases
-;; not at all, as generally, buffers add their own undo-boundary.
-;;
-;; It will still fail if a large amount of material is added or
-;; removed from a buffer with any rapidity and no undo-boundary. In
-;; this case, the `undo-outer-limit' machinary will operate; this is
-;; considered to be exceptional the user is warned.
-
-
+;; This section adds a new undo-boundary at either after a command is
+;; called or in some cases on a timer called after a change is made in
+;; any buffer.
 (defmacro undo-auto-message (&rest args)
   `(let ((msg
           (format ,@args)))
@@ -2785,52 +2773,67 @@ with < or <= based on USE-<."
   (setq buffer-undo-list t))
 (undo-auto-message "initialized")
 
+(defvar-local undo-last-boundary nil
+  "Describe the cause of the last undo-boundary.
+
+If nil, the last boundary was caused by an explicit call to
+`undo-boundary', that is one not called by the code in this
+section.
+
+If it is equal to 'timer, then the last boundary was inserted
+by `undo-auto-boundary-timer'.
+
+If it is equal to 'command, then the last boundary was inserted
+automatically after a command, that is by the code defined in
+this section.
+
+If it is equal to a number, then the last boundary was inserted
+by an amalgamating command.")
+
+(defvar undo--last-command-amalgamating nil)
+
+(defvar undo--amalgamating-commands '(self-insert-command delete-char))
+
 (defun undo-needs-boundary-p ()
-  "Returns non-nil if `buffer-undo-list' needs a boundary at the start."
-  (and
-   ;; `buffer-undo-list' can be t.
-   (listp buffer-undo-list)
-   ;; The first element of buffer-undo-list is not nil.
-   (car buffer-undo-list)))
-
-(defun undo-last-boundary-sic-p (last-boundary)
-  "Returns non-nil if the last boundary was from self-insert-command.
-Returns the actual number of times a self-insert-command has been
-run."
-  (and
-   (eq 'command
-       (car-safe last-boundary))
-   (eq 'self-insert-command
-       (nth 1 last-boundary))
-   (or (nth 2 last-boundary)
-       0)))
+  "Return non-nil if `buffer-undo-list' needs a boundary at the start."
+  (car-safe buffer-undo-list))
+
+(defun undo-last-boundary-amalgamating-p ()
+  "Return non-nil if the last boundary was from an amalgamating command.
+Amalgamating commands are either `self-insert-command' and
+`delete-char'.  The return value is actual number of times one of
+these commands have been run if non-nil."
+  (and (integerp undo-last-boundary)
+       undo-last-boundary))
 
 (defun undo-ensure-boundary (reason)
-  ""
+  "Add an `undo-boundary' to the current buffer if needed.
+REASON describes the reason that the boundary is being added; see
+`undo-last-boundary' for more information. "
   (when (and
          buffer-undo-list
          (undo-needs-boundary-p))
-    (let ((last-sic
-           (undo-last-boundary-sic-p undo-last-boundary)))
-      (when last-sic
-        (setq reason
-              `(command self-insert-command
-                        ,(1+ last-sic))))
+    (let ((last-amalgamating
+           (undo-last-boundary-amalgamating-p)))
+      (when (and last-amalgamating
+                 (eq 'amalgamate reason))
+        (setq reason (1+ last-amalgamating)))
       (undo-boundary)
-      (setq undo-last-boundary reason))
+      (setq undo-last-boundary
+            (if (eq 'amalgamate reason)
+                0
+              reason)))
+    (undo-auto-message "last-boundary now %s" undo-last-boundary)
     t))
 
 (defun undo-auto-boundary (reason)
   "Checks recently change buffers and adds a boundary if necessary.
 
 See also `undo-ensure-boundary'."
-  (mapc
-   (lambda (b)
-     (when (buffer-live-p b)
-       (with-current-buffer b
-         (when (undo-ensure-boundary reason)
-           (undo-auto-message "undo-auto-boundary boundary added %s" b)))))
-   undo-undoably-changed-buffers)
+  (dolist (b undo-undoably-changed-buffers)
+          (when (buffer-live-p b)
+            (with-current-buffer b
+              (undo-ensure-boundary reason))))
   (setq undo-undoably-changed-buffers nil))
 
 (defvar undo-auto-current-boundary-timer nil
@@ -2838,12 +2841,12 @@ See also `undo-ensure-boundary'."
 
 (defun undo-auto-boundary-timer ()
   "Timer which will run `undo-auto-boundary-timer'."
-  (undo-auto-message "running timer")
+  ;;(undo-auto-message "running timer")
   (undo-auto-boundary 'timer)
   (setq undo-auto-current-boundary-timer nil))
 
 (defun undo-auto-boundary-ensure-timer ()
-  "Ensure that the `undo-auto-boundary-timer is set."
+  "Ensure that the `undo-auto-boundary-timer' is set."
   (unless undo-auto-current-boundary-timer
     (setq undo-auto-current-boundary-timer
           (run-at-time 10 nil 'undo-auto-boundary-timer))))
@@ -2851,49 +2854,54 @@ See also `undo-ensure-boundary'."
 (defvar undo-undoably-changed-buffers nil
   "List of buffers that have changed recently.
 
-This list is maintained by
-`undo-auto-boundary-first-undoable-change-hook' and
+This list is maintained by `undo-undoable-change' and
 `undo-auto-boundary' and can be affected by changes to their
 default values.
 
 See also `undo-buffer-undoably-changed'.")
 
-(defun undo-auto-boundary-first-undoable-change-hook ()
-  "Default value of `undo-boundary-first-undoable-change-hook'."
-  ;;(undo-auto-message "undo-auto adding-to-list %s" (current-buffer))
-  (add-to-list 'undo-undoably-changed-buffers (current-buffer))
-  (undo-auto-boundary-ensure-timer))
-
 (defun undo-auto-post-command-hook ()
   (unless (eq buffer-undo-list t)
-    (undo-auto-boundary `(command ,this-command))))
-
-(defun undo-auto-pre-self-insert-command()
+    (undo-auto-boundary
+     (if undo--last-command-amalgamating
+         'amalgamate
+       'command))))
+
+(defun undo-auto-pre-amalgamating-command ()
+  "Amalgamate undo if necessary.
+This function is called before `self-insert-command', and removes
+the previous `undo-boundary' if a series of `self-insert-command'
+calls have been made."
   (condition-case err
-      (let ((last-sic-count
-             (undo-last-boundary-sic-p undo-last-boundary)))
+      (let ((last-amalgamating-count
+             (undo-last-boundary-amalgamating-p)))
+        (setq undo--last-command-amalgamating t)
         (when
-            last-sic-count
+            last-amalgamating-count
           (if
-              (< last-sic-count 20)
+              (and
+               (< last-amalgamating-count 20)
+               (eq this-command last-command))
               (progn (undo-auto-message "(changed) Removing last undo")
                      (setq buffer-undo-list
                            (cdr buffer-undo-list)))
             (progn (undo-auto-message "Reset sic to 0")
-                   (setq undo-last-boundary
-                         '(command self-insert-command 0))))))
+                   (setq undo-last-boundary 0)))))
     (error
      (undo-auto-message "pre-command-error %s"
                         (error-message-string err)))))
 
 (defun undo-undoable-change ()
-  (undo-auto-message "undo-auto adding-to-list %s" (current-buffer))
+  "Called after every undoable buffer change."
+  ;;(undo-auto-message "undo-auto adding-to-list %s" (current-buffer))
   (add-to-list 'undo-undoably-changed-buffers (current-buffer))
   (undo-auto-boundary-ensure-timer))
 
 (add-hook 'post-command-hook
           #'undo-auto-post-command-hook)
 
+;; End auto-boundary section
+
 (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/src/cmds.c b/src/cmds.c
index 4a1782c..6931546 100644
--- a/src/cmds.c
+++ b/src/cmds.c
@@ -265,9 +265,8 @@ because it respects values of `delete-active-region' and 
`overwrite-mode'.  */)
 
   CHECK_NUMBER (n);
 
-  // PWL
-  //if (abs (XINT (n)) < 2)
-  //  remove_excessive_undo_boundaries ();
+  if (abs (XINT (n)) < 2)
+    call0(Qundo_auto_pre_amalgamating_command);
 
   pos = PT + XINT (n);
   if (NILP (killflag))
@@ -312,10 +311,10 @@ At the end, it runs `post-self-insert-hook'.  */)
   if (XFASTINT (n) < 0)
     error ("Negative repetition argument %"pI"d", XFASTINT (n));
 
-  // PWL remove for now
-  //if (XFASTINT (n) < 2)
+  if (XFASTINT (n) < 2)
+    call0(Qundo_auto_pre_amalgamating_command);
+
   //remove_excessive_undo_boundaries ();
-  call0(Qundo_auto_pre_self_insert_command);
 
   /* Barf if the key that invoked this was not a character.  */
   if (!CHARACTERP (last_command_event))
@@ -530,8 +529,8 @@ internal_self_insert (int c, EMACS_INT n)
 void
 syms_of_cmds (void)
 {
-  DEFSYM (Qundo_auto_pre_self_insert_command,
-          "undo-auto-pre-self-insert-command" );
+  DEFSYM (Qundo_auto_pre_amalgamating_command,
+          "undo-auto-pre-amalgamating-command" );
 
   DEFSYM (Qkill_forward_chars, "kill-forward-chars");
 
diff --git a/src/keyboard.c b/src/keyboard.c
index 29307cb..852ceed 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1502,6 +1502,8 @@ command_loop_1 (void)
               }
 #endif
 
+            Fset (Qundo__last_command_amalgamating, Qnil);
+
             /* if (NILP (KVAR (current_kboard, Vprefix_arg))) /\* FIXME: Why?  
--Stef  *\/ */
             /*   { */
             /*     Fundo_auto_boundary(); */
@@ -11088,6 +11090,8 @@ syms_of_keyboard (void)
   DEFSYM (Qpre_command_hook, "pre-command-hook");
   DEFSYM (Qpost_command_hook, "post-command-hook");
 
+  DEFSYM (Qundo__last_command_amalgamating, "undo--last-command-amalgamating");
+
   DEFSYM (Qdeferred_action_function, "deferred-action-function");
   DEFSYM (Qdelayed_warnings_hook, "delayed-warnings-hook");
   DEFSYM (Qfunction_key, "function-key");
diff --git a/src/undo.c b/src/undo.c
index 58d1e7d..57ee037 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -40,7 +40,7 @@ static Lisp_Object pending_boundary;
 void
 run_undoable_change ()
 {
-  call0(Qundo_undoable_change);
+  call0 (Qundo_undoable_change);
 }
 
 /* Record point as it was at beginning of this command (if necessary)
@@ -74,7 +74,8 @@ record_point (ptrdiff_t pt)
   if (at_boundary
       && current_buffer == last_boundary_buffer
       && last_boundary_position != pt)
-    bset_undo_list (current_buffer,
+
+   bset_undo_list (current_buffer,
                    Fcons (make_number (last_boundary_position),
                           BVAR (current_buffer, undo_list)));
 }
@@ -248,9 +249,8 @@ record_property_change (ptrdiff_t beg, ptrdiff_t length,
     pending_boundary = Fcons (Qnil, Qnil);
 
   /* Switch temporarily to the buffer that was changed.  */
-  current_buffer = buf;
+  set_buffer_internal (buf);
 
-  // PWL running with the wrong current-buffer
   run_undoable_change ();
 
   if (MODIFF <= SAVE_MODIFF)
@@ -262,7 +262,8 @@ record_property_change (ptrdiff_t beg, ptrdiff_t length,
   bset_undo_list (current_buffer,
                  Fcons (entry, BVAR (current_buffer, undo_list)));
 
-  current_buffer = obuf;
+  /* Reset the buffer */
+  set_buffer_internal (obuf);
 }
 
 DEFUN ("undo-boundary", Fundo_boundary, Sundo_boundary, 0, 0, 0,
@@ -293,7 +294,7 @@ but another undo command will undo to the previous 
boundary.  */)
   last_boundary_position = PT;
   last_boundary_buffer = current_buffer;
 
-  Fset(Qundo_last_boundary,Qnil);
+  Fset (Qundo_last_boundary,Qnil);
   return Qnil;
 }
 
@@ -565,12 +566,4 @@ so it must make sure not to do a lot of consing.  */);
 This hook will be run with `current-buffer' as the buffer that has
 changed.  Recent means since the last boundary. */);
   Vundo_first_undoable_change_hook = Qnil;
-
-  DEFVAR_LISP ("undo-last-boundary",
-               Vundo_last_boundary,
-               doc: /* TODO
-*/);
-
-  Fmake_variable_buffer_local (Qundo_last_boundary);
-  Vundo_last_boundary = Qnil;
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]