emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] emacs/lisp follow.el


From: Chong Yidong
Subject: [Emacs-diffs] emacs/lisp follow.el
Date: Tue, 30 Dec 2008 13:26:23 +0000

CVSROOT:        /sources/emacs
Module name:    emacs
Changes by:     Chong Yidong <cyd>      08/12/30 13:26:23

Modified files:
        lisp           : follow.el 

Log message:
        (follow-calc-win-end): Use with-selected-window.
        (follow-windows-start-end, follow-pos-visible)
        (follow-windows-aligned-p): Code cleanup.
        (follow-select-if-visible): Try to avoid partially-visible lines.
        (follow-select-if-visible-from-first): Call follow-redisplay and
        move point to destination.
        (follow-redisplay): New arg, to keep selected window unchanged.
        (follow-post-command-hook): In final check for destination
        visibility, use window-start and window-end instead of the less
        accurate follow-pos-visible.  If the selected window is redrawn,
        tell follow-redisplay to preserve it.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/emacs/lisp/follow.el?cvsroot=emacs&r1=1.50&r2=1.51

Patches:
Index: follow.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/follow.el,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -b -r1.50 -r1.51
--- follow.el   30 Dec 2008 10:52:01 -0000      1.50
+++ follow.el   30 Dec 2008 13:26:23 -0000      1.51
@@ -880,11 +880,8 @@
     ;; This code works on both XEmacs and Emacs, but now
     ;; that XEmacs has got custom-written code, this could
     ;; be optimized for Emacs.
-    (let ((orig-win (and win (selected-window)))
-         height
-         buffer-end-p)
-      (if win (select-window win))
-      (prog1
+    (let (height buffer-end-p)
+      (with-selected-window (or win (selected-window))
          (save-excursion
            (goto-char (window-start))
            (setq height
@@ -899,9 +896,7 @@
                      ;; coinside with the start of a line.
                      (narrow-to-region (point) (point-max))
                      (not (= height (vertical-motion height))))))
-           (list (point) buffer-end-p))
-       (if orig-win
-           (select-window orig-win))))))
+         (list (point) buffer-end-p))))))
 
 
 ;; Can't use `save-window-excursion' since it triggers a redraw.
@@ -955,30 +950,25 @@
   "Builds a list of (WIN START END BUFFER-END-P) for every window in WINDOWS."
   (if (follow-cache-valid-p windows)
       follow-windows-start-end-cache
-    (let ((win-start-end '())
-         (orig-win (selected-window)))
-      (while windows
-       (select-window (car windows))
-       (setq win-start-end
-             (cons (cons (car windows)
-                         (cons (window-start)
-                               (follow-calc-win-end)))
+    (let ((orig-win (selected-window))
+         win-start-end)
+      (dolist (w windows)
+       (select-window w)
+       (push (cons w (cons (window-start) (follow-calc-win-end)))
                    win-start-end))
-       (setq windows (cdr windows)))
       (select-window orig-win)
-      (setq follow-windows-start-end-cache (nreverse win-start-end))
-      follow-windows-start-end-cache)))
+      (setq follow-windows-start-end-cache (nreverse win-start-end)))))
 
 
 (defsubst follow-pos-visible (pos win win-start-end)
   "Non-nil when POS is visible in WIN."
   (let ((wstart-wend-bend (cdr (assq win win-start-end))))
     (and (>= pos (car wstart-wend-bend))
-        (or (< pos (car (cdr wstart-wend-bend)))
+        (or (< pos (cadr wstart-wend-bend))
             (nth 2 wstart-wend-bend)))))
 
 
-;; By `aligned' we mean that for all adjecent windows, the end of the
+;; By `aligned' we mean that for all adjacent windows, the end of the
 ;; first is equal with the start of the successor.  The first window
 ;; should start at a full screen line.
 
@@ -986,11 +976,10 @@
   "Non-nil if the follower windows are aligned."
   (let ((res t))
     (save-excursion
-       (goto-char (window-start (car (car win-start-end))))
-       (if (bolp)
-          nil
-        (vertical-motion 0 (car (car win-start-end)))
-        (setq res (eq (point) (window-start (car (car win-start-end)))))))
+      (goto-char (window-start (caar win-start-end)))
+      (unless (bolp)
+       (vertical-motion 0 (caar win-start-end))
+       (setq res (eq (point) (window-start (caar win-start-end))))))
     (while (and res (cdr win-start-end))
       ;; At least two followers left
       (setq res (eq (car (cdr (cdr (car win-start-end))))
@@ -1053,6 +1042,14 @@
        (setq win (caar 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))
+        win-start-end
+        (follow-pos-visible dest (caar win-start-end) win-start-end)
+        (setq win (caar win-start-end))
+        (select-window win))
     win))
 
 
@@ -1090,19 +1087,20 @@
 ;; as the point is not visible in any window.
 
 (defun follow-select-if-visible-from-first (dest windows)
-  "Select and return a window with DEST, if WINDOWS are redrawn from top."
-  (let ((win nil)
-       end-pos-end-p)
+  "Try to select one of WINDOWS without repositioning the topmost window.
+If one of the windows in WINDOWS contains DEST, select it, call
+`follow-redisplay', move point to DEST, and return that window.
+Otherwise, return nil."
+  (let (win end-pos-end-p)
     (save-excursion
       (goto-char (window-start (car windows)))
       ;; Make sure the line start in the beginning of a real screen
       ;; line.
       (vertical-motion 0 (car windows))
-      (if (< dest (point))
-         ;; Above the start, not visible.
-         nil
+      (when (>= dest (point))
        ;; At or below the start. Check the windows.
        (save-window-excursion
+         (let ((windows windows))
          (while (and (not win) windows)
            (set-window-start (car windows) (point) 'noforce)
            (setq end-pos-end-p (follow-calc-win-end (car windows)))
@@ -1112,9 +1110,11 @@
            (if (or (car (cdr end-pos-end-p))
                    (< dest (point)))
                  (setq win (car windows))
-               (setq windows (cdr windows)))))))
-    (if win
-       (select-window win))
+               (setq windows (cdr windows))))))))
+    (when win
+      (select-window win)
+      (follow-redisplay windows (car windows))
+      (goto-char dest))
     win))
 
 
@@ -1126,14 +1126,16 @@
 ;; is nil.  Start every window directly after the end of the previous
 ;; window, to make sure long lines are displayed correctly.
 
-(defun follow-redisplay (&optional windows win)
+(defun follow-redisplay (&optional windows win preserve-win)
   "Reposition the WINDOWS around WIN.
 Should the point be too close to the roof we redisplay everything
 from the top.  WINDOWS should contain a list of windows to
 redisplay, it is assumed that WIN is a member of the list.
 Should WINDOWS be nil, the windows displaying the
 same buffer as WIN, in the current frame, are used.
-Should WIN be nil, the selected window is used."
+Should WIN be nil, the selected window is used.
+If PRESERVE-WIN is non-nil, keep WIN itself unchanged while
+repositioning the other windows."
   (or win (setq win (selected-window)))
   (or windows (setq windows (follow-all-followers win)))
   ;; Calculate the start of the first window.
@@ -1154,7 +1156,8 @@
                       (follow-calculate-first-window-start-from-below
                        windows try-first-start win old-win-start)))))
     (dolist (w windows)
-      (set-window-start w start)
+      (unless (and preserve-win (eq w win))
+       (set-window-start w start))
       (setq start (car (follow-calc-win-end w))))))
 
 
@@ -1310,15 +1313,15 @@
        (when (and follow-mode
                   (not (window-minibuffer-p win)))
          ;; The buffer shown in the selected window is in follow
-         ;; mode.  Find the current state of the display and cache
-         ;; the result for speed (i.e. `aligned' and `visible'.)
+         ;; mode.  Find the current state of the display.
          (let* ((windows (follow-all-followers win))
                 (dest (point))
                 (win-start-end (progn
                                  (follow-update-window-start (car windows))
                                  (follow-windows-start-end windows)))
                 (aligned (follow-windows-aligned-p win-start-end))
-                (visible (follow-pos-visible dest win win-start-end)))
+                (visible (follow-pos-visible dest win win-start-end))
+                selected-window-up-to-date)
            (unless (and aligned visible)
              (follow-invalidate-cache))
            (follow-avoid-tail-recenter)
@@ -1392,9 +1395,7 @@
                 ;; at the bottom of a window.
                 ((follow-select-if-visible-from-first dest windows)
                  (follow-debug-message "Below first")
-                 (setq visible t aligned t)
-                 (follow-redisplay windows (car windows))
-                 (goto-char dest))
+                 (setq visible t aligned t))
                 ;; None of the above. For simplicity, we stick to the
                 ;; selected window.
                 (t
@@ -1403,27 +1404,34 @@
              ;; If a new window has been selected, make sure that the
              ;; old is not scrolled when the point is outside the
              ;; window.
-             (or (eq win (selected-window))
+             (unless (eq win (selected-window))
                  (let ((p (window-point win)))
                    (set-window-start win (window-start win) nil)
                    (set-window-point win p))))
-           ;; Make sure the point is visible in the selected window.
-           ;; (This could lead to a scroll.)
            (unless (or visible
-                       (follow-pos-visible dest win win-start-end))
+                       ;; 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)
+             (setq selected-window-up-to-date t)
              (follow-avoid-tail-recenter)
              (setq win-start-end (follow-windows-start-end windows))
              (follow-invalidate-cache)
              (setq aligned nil))
-           ;; Redraw the windows whenever needed.
+           ;; Now redraw the windows around the selected window.
            (unless (and (not follow-internal-force-redisplay)
                         (or aligned
                             (follow-windows-aligned-p win-start-end))
                         (follow-point-visible-all-windows-p
                          win-start-end))
              (setq follow-internal-force-redisplay nil)
-             (follow-redisplay windows (selected-window))
+             (follow-redisplay windows (selected-window)
+                               selected-window-up-to-date)
              (setq win-start-end (follow-windows-start-end windows))
              (follow-invalidate-cache)
              ;; When the point ends up in another window. This
@@ -1833,8 +1841,6 @@
                   ((follow-select-if-visible-from-first
                     new-window-point windows)
                    (follow-debug-message "filter: Seen from first")
-                   (follow-redisplay windows (car windows))
-                   (goto-char new-window-point)
                    (setq win-start-end
                          (follow-windows-start-end windows)))
                   ;; None of the above. We stick to the current window.




reply via email to

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