]> code.delx.au - gnu-emacs/blobdiff - lisp/follow.el
Make autoloading commands prompt for autoload file (Bug#7989)
[gnu-emacs] / lisp / follow.el
index 59b8a8a38fdf242a2cb1452f7fdaab75b87a5b36..9bf472e547c8b1bc18df2590529d31763437c725 100644 (file)
@@ -1,7 +1,6 @@
 ;;; follow.el --- synchronize windows showing the same buffer
 
-;; Copyright (C) 1995, 1996, 1997, 1999, 2001, 2002, 2003, 2004,
-;;   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;; Copyright (C) 1995-1997, 1999, 2001-2011 Free Software Foundation, Inc.
 
 ;; Author: Anders Lindgren <andersl@andersl.com>
 ;; Maintainer: FSF (Anders' email bounces, Sep 2005)
@@ -872,8 +871,7 @@ Returns (end-pos end-of-buffer-p)"
       ;; XEmacs can calculate the end of the window by using
       ;; the 'guarantee options. GOOD!
       (let ((end (window-end win t)))
-       (if (= end (funcall (symbol-function 'point-max)
-                           (window-buffer win)))
+       (if (= end (point-max (window-buffer win)))
            (list end t)
          (list (+ end 1) nil)))
     ;; Emacs: We have to calculate the end by ourselves.
@@ -1033,21 +1031,27 @@ Note that this handles the case when the cache has been set to nil."
 (defun follow-select-if-visible (dest win-start-end)
   "Select and return a window, if DEST is visible in it.
 Return the selected window."
-  (let (win)
+  (let (win win-end)
     (while (and (not win) win-start-end)
       ;; Don't select a window that was just moved. This makes it
       ;; possible to later select the last window after a `end-of-buffer'
       ;; command.
       (when (follow-pos-visible dest (caar win-start-end) win-start-end)
-       (setq win (caar win-start-end))
+       (setq win (caar win-start-end)
+             win-end (car (cddr (car win-start-end))))
        (select-window win))
       (setq win-start-end (cdr win-start-end)))
     ;; The last line of the window may be partially visible; if so,
     ;; and if point is visible in the next window, select the next
     ;; window instead.
-    (and (/= dest (point-max))
+    (and win
+        (/= dest (point-max))
         win-start-end
         (follow-pos-visible dest (caar win-start-end) win-start-end)
+        (save-excursion
+          (goto-char dest)
+          (vertical-motion 1 win)
+          (>= (point) win-end))
         (setq win (caar win-start-end))
         (select-window win))
     win))
@@ -1057,7 +1061,7 @@ Return the selected window."
 ;; it wasn't just moved here. (i.e. M-> shall not unconditionally place
 ;; the point in the selected window.)
 ;;
-;; (Compability cludge: in Emacs `window-end' is equal to `point-max';
+;; (Compatibility cludge: in Emacs `window-end' is equal to `point-max';
 ;; in XEmacs, it is equal to `point-max + 1'. Should I really bother
 ;; checking `window-end' now when I check `end-of-buffer' explicitly?)
 
@@ -1208,22 +1212,25 @@ should be a member of WINDOWS, starts at position START."
   (setq win (or win (selected-window)))
   (setq start (or start (window-start win)))
   (save-excursion
-    (let ((done nil)
-         win-start
-         res)
+    (let (done win-start res opoint)
       ;; Always calculate what happens when no line is displayed in the first
       ;; window. (The `previous' res is needed below!)
       (goto-char guess)
       (vertical-motion 0 (car windows))
       (setq res (point))
       (while (not done)
+       (setq opoint (point))
        (if (not (= (vertical-motion -1 (car windows)) -1))
            ;; Hit roof!
            (setq done t res (point-min))
          (setq win-start (follow-calc-win-start windows (point) win))
-         (cond ((= win-start start)    ; Perfect match, use this value
-                (setq done t)
-                (setq res (point)))
+         (cond ((>= (point) opoint)
+                ;; In some pathological cases, vertical-motion may
+                ;; return -1 even though point has not decreased.  In
+                ;; that case, avoid looping forever.
+                (setq done t res (point)))
+               ((= win-start start)    ; Perfect match, use this value
+                (setq done t res (point)))
                ((< win-start start)    ; Walked to far, use preious result
                 (setq done t))
                (t                      ; Store result for next iteration
@@ -1253,7 +1260,7 @@ should be a member of WINDOWS, starts at position START."
 ;; especially if it is placed in the debug filter section.  I must
 ;; investigate this further...
 
-(defun follow-avoid-tail-recenter (&rest rest)
+(defun follow-avoid-tail-recenter (&rest _rest)
   "Make sure windows displaying the end of a buffer aren't recentered.
 
 This is done by reading and rewriting the start position of
@@ -1370,13 +1377,13 @@ non-first windows in Follow mode."
                 ((and visible aligned)
                  (follow-debug-message "same"))
                 ;; Pick a position in any window.  If the display is
-                ;; ok, this will pick the `correct' window.  If the
-                ;; display is wierd (e.g., after a delete at the
-                ;; beginning of the window) do this anyway.
+                ;; ok, this will pick the `correct' window.
                 ((follow-select-if-visible dest win-start-end)
                  (follow-debug-message "visible")
-                 (setq visible t)
-                 (goto-char dest))
+                 (goto-char dest)
+                 ;; We have to perform redisplay, since scrolling is
+                 ;; needed in case the line is partially visible.
+                 (setq visible nil))
                 ;; Not visible anywhere else, lets pick this one.
                 ;; (Is this case used?)
                 (visible
@@ -1408,16 +1415,10 @@ non-first windows in Follow mode."
                (let ((p (window-point win)))
                  (set-window-start win (window-start win) nil)
                  (set-window-point win p))))
-           (unless (or visible
-                       ;; Use the UPDATE argument of window-end
-                       ;; instead of calling follow-pos-visible
-                       ;; (which may be inaccurate for partially
-                       ;; visible lines).
-                       (and (>= dest (window-start))
-                            (< dest (window-end nil t))))
-             ;; If point is not visible in the selected window,
-             ;; perform a redisplay; this causes scrolling.
-             (sit-for 0)
+           (unless visible
+             ;; If point may not be visible in the selected window,
+             ;; perform a redisplay; this ensures scrolling.
+             (redisplay)
              (setq selected-window-up-to-date t)
              (follow-avoid-tail-recenter)
              (setq win-start-end (follow-windows-start-end windows))
@@ -2119,5 +2120,4 @@ This prevents `mouse-drag-region' from messing things up."
 ;; | save it".             -- Douglas Adams, "Last Chance to See"           |
 ;; \------------------------------------------------------------------------/
 
-;; arch-tag: 7b16bb1a-808c-4991-a8cc-66d3822936d0
 ;;; follow.el ends here