changeset 59127:25e00b2ef82f

(next-error-buffer-p): New arg AVOID-CURRENT. Test that the buffer is live, and maybe reject current buffer too. Rewrite for clarity. (next-error-find-buffer): Rewrite for clarity. (undo-list-saved): New variable (buffer-local). (undo): Set and test it. (next-matching-history-element): Use same `interactive' form as previous-matching-history-element.
author Richard M. Stallman <rms@gnu.org>
date Mon, 27 Dec 2004 16:34:43 +0000
parents 7c8ecf412b73
children e070d86ca060
files lisp/simple.el
diffstat 1 files changed, 82 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/simple.el	Mon Dec 27 16:24:54 2004 +0000
+++ b/lisp/simple.el	Mon Dec 27 16:34:43 2004 +0000
@@ -124,70 +124,87 @@
 (make-variable-buffer-local 'next-error-function)
 
 (defsubst next-error-buffer-p (buffer
-			       &optional
+			       &optional avoid-current
 			       extra-test-inclusive
 			       extra-test-exclusive)
   "Test if BUFFER is a next-error capable buffer.
-EXTRA-TEST-INCLUSIVE is called to allow extra buffers.
-EXTRA-TEST-EXCLUSIVE is called to disallow buffers."
-  (with-current-buffer buffer
-    (or (and extra-test-inclusive (funcall extra-test-inclusive))
-	(and (if extra-test-exclusive (funcall extra-test-exclusive) t)
-	 next-error-function))))
-
-(defun next-error-find-buffer (&optional other-buffer
+
+If AVOID-CURRENT is non-nil, treat the current buffer
+as an absolute last resort only.
+
+The function EXTRA-TEST-INCLUSIVE, if non-nil, is called in each buffer
+that normally would not qualify.  If it returns t, the buffer
+in question is treated as usable.
+
+The function EXTRA-TEST-EXCLUSIVE, if non-nil is called in each buffer
+that would normally be considered usable.  if it returns nil,
+that buffer is rejected."
+  (and (buffer-name buffer)		;First make sure it's live.
+       (not (and avoid-current (eq buffer (current-buffer))))
+       (with-current-buffer buffer
+	 (if next-error-function   ; This is the normal test.
+	     ;; Optionally reject some buffers.
+	     (if extra-test-exclusive
+		 (funcall extra-test-exclusive)
+	       t)
+	   ;; Optionally accept some other buffers.
+	   (and extra-test-inclusive
+		(funcall extra-test-inclusive))))))
+
+(defun next-error-find-buffer (&optional avoid-current
 					 extra-test-inclusive
 					 extra-test-exclusive)
   "Return a next-error capable buffer.
-OTHER-BUFFER will disallow the current buffer.
-EXTRA-TEST-INCLUSIVE is called to allow extra buffers.
-EXTRA-TEST-EXCLUSIVE is called to disallow buffers."
+If AVOID-CURRENT is non-nil, treat the current buffer
+as an absolute last resort only.
+
+The function EXTRA-TEST-INCLUSIVE, if non-nil, is called in each buffers
+that normally would not qualify.  If it returns t, the buffer
+in question is treated as usable.
+
+The function EXTRA-TEST-EXCLUSIVE, if non-nil is called in each buffer
+that would normally be considered usable.  If it returns nil,
+that buffer is rejected."
   (or
    ;; 1. If one window on the selected frame displays such buffer, return it.
    (let ((window-buffers
           (delete-dups
            (delq nil (mapcar (lambda (w)
                                (if (next-error-buffer-p
-                                    (window-buffer w)
+				    (window-buffer w)
+                                    avoid-current
                                     extra-test-inclusive extra-test-exclusive)
                                    (window-buffer w)))
                              (window-list))))))
-     (if other-buffer
-         (setq window-buffers (delq (current-buffer) window-buffers)))
      (if (eq (length window-buffers) 1)
          (car window-buffers)))
-   ;; 2. If next-error-last-buffer is set to a live buffer, use that.
+   ;; 2. If next-error-last-buffer is an acceptable buffer, use that.
    (if (and next-error-last-buffer
-            (buffer-name next-error-last-buffer)
-            (next-error-buffer-p next-error-last-buffer
-                                 extra-test-inclusive extra-test-exclusive)
-            (or (not other-buffer)
-                (not (eq next-error-last-buffer (current-buffer)))))
+            (next-error-buffer-p next-error-last-buffer avoid-current
+                                 extra-test-inclusive extra-test-exclusive))
        next-error-last-buffer)
-   ;; 3. If the current buffer is a next-error capable buffer, return it.
-   (if (and (not other-buffer)
-            (next-error-buffer-p (current-buffer)
-                                 extra-test-inclusive extra-test-exclusive))
+   ;; 3. If the current buffer is acceptable, choose it.
+   (if (next-error-buffer-p (current-buffer) avoid-current
+			    extra-test-inclusive extra-test-exclusive)
        (current-buffer))
-   ;; 4. Look for a next-error capable buffer in a buffer list.
+   ;; 4. Look for any acceptable buffer.
    (let ((buffers (buffer-list)))
      (while (and buffers
-                 (or (not (next-error-buffer-p
-                           (car buffers)
-                           extra-test-inclusive extra-test-exclusive))
-                     (and other-buffer (eq (car buffers) (current-buffer)))))
+                 (not (next-error-buffer-p
+		       (car buffers) avoid-current
+		       extra-test-inclusive extra-test-exclusive)))
        (setq buffers (cdr buffers)))
-     (if buffers
-         (car buffers)
-       (or (and other-buffer
-                (next-error-buffer-p (current-buffer)
-                                     extra-test-inclusive extra-test-exclusive)
-                ;; The current buffer is a next-error capable buffer.
-                (progn
-                  (if other-buffer
-                      (message "This is the only next-error capable buffer"))
-                  (current-buffer)))
-           (error "No next-error capable buffer found"))))))
+     (car buffers))
+   ;; 5. Use the current buffer as a last resort if it qualifies,
+   ;; even despite AVOID-CURRENT.
+   (and avoid-current
+	(next-error-buffer-p (current-buffer) nil
+			     extra-test-inclusive extra-test-exclusive)
+	(progn
+	  (message "This is the only next-error capable buffer")
+	  (current-buffer)))
+   ;; 6. Give up.
+   (error "No next-error capable buffer found")))
 
 (defun next-error (&optional arg reset)
   "Visit next next-error message and corresponding source code.
@@ -1113,11 +1130,13 @@
 					nil
 					minibuffer-local-map
 					nil
-					'minibuffer-history-search-history)))
+					'minibuffer-history-search-history
+ 					(car minibuffer-history-search-history))))
      ;; Use the last regexp specified, by default, if input is empty.
      (list (if (string= regexp "")
-	       (setcar minibuffer-history-search-history
-		       (nth 1 minibuffer-history-search-history))
+	       (if minibuffer-history-search-history
+		   (car minibuffer-history-search-history)
+		 (error "No previous history search regexp"))
 	     regexp)
 	   (prefix-numeric-value current-prefix-arg))))
   (previous-matching-history-element regexp (- n)))
@@ -1215,6 +1234,10 @@
 (defvar undo-no-redo nil
   "If t, `undo' doesn't go through redo entries.")
 
+(defvar undo-list-saved nil
+  "The value of `buffer-undo-list' saved by the last undo command.")
+(make-variable-buffer-local 'undo-list-saved)
+
 (defun undo (&optional arg)
   "Undo some previous changes.
 Repeat this command to undo more changes.
@@ -1237,7 +1260,10 @@
     ;; So set `this-command' to something other than `undo'.
     (setq this-command 'undo-start)
 
-    (unless (eq last-command 'undo)
+    (unless (and (eq last-command 'undo)
+		 ;; If something (a timer or filter?) changed the buffer
+		 ;; since the previous command, don't continue the undo seq.
+		 (eq undo-list-saved buffer-undo-list))
       (setq undo-in-region
 	    (if transient-mark-mode mark-active (and arg (not (numberp arg)))))
       (if undo-in-region
@@ -1289,10 +1315,20 @@
 	      (setq tail (cdr tail)))
 	    (setq tail nil)))
 	(setq prev tail tail (cdr tail))))
-
+    ;; Record what the current undo list says,
+    ;; so the next command can tell if the buffer was modified in between.
+    (setq undo-list-saved buffer-undo-list)
     (and modified (not (buffer-modified-p))
 	 (delete-auto-save-file-if-necessary recent-save))))
 
+(defun buffer-disable-undo (&optional buffer)
+  "Make BUFFER stop keeping undo information.
+No argument or nil as argument means do this for the current buffer."
+  (interactive)
+  (with-current-buffer (get-buffer buffer)
+    (setq buffer-undo-list t
+	  undo-list-saved nil)))
+
 (defun undo-only (&optional arg)
   "Undo some previous changes.
 Repeat this command to undo more changes.