changeset 16751:d393cbcfb69c

(window_scroll): Preserve vpos of point if we cannot preserve the actual position of it. Make it static. New arg WHOLE; callers changed.
author Richard M. Stallman <rms@gnu.org>
date Thu, 26 Dec 1996 21:01:10 +0000
parents 06001fb1a820
children 6409ef81a2a8
files src/window.c
diffstat 1 files changed, 59 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/src/window.c	Thu Dec 26 21:00:03 1996 +0000
+++ b/src/window.c	Thu Dec 26 21:01:10 1996 +0000
@@ -2637,12 +2637,15 @@
 }
 
 
-/* Scroll contents of window WINDOW up N lines.  */
-
-void
-window_scroll (window, n, noerror)
+/* Scroll contents of window WINDOW up N lines.
+   If WHOLE is nonzero, it means we wanted to scroll
+   by entire screenfuls.  */
+
+static void
+window_scroll (window, n, whole, noerror)
      Lisp_Object window;
      int n;
+     int whole;
      int noerror;
 {
   register struct window *w = XWINDOW (window);
@@ -2653,6 +2656,16 @@
   int lose;
   Lisp_Object bolp, nmoved;
   int startpos;
+  struct position posit;
+  int original_vpos;
+
+  startpos = marker_position (w->start);
+
+  posit = *compute_motion (startpos, 0, 0, 0,
+			   PT, ht, 0,
+			   window_internal_width (w), XINT (w->hscroll),
+			   0, w);
+  original_vpos = posit.vpos;
 
   XSETFASTINT (tem, PT);
   tem = Fpos_visible_in_window_p (tem, window);
@@ -2662,8 +2675,6 @@
       Fvertical_motion (make_number (- (ht / 2)), window);
       startpos = PT;
     }
-  else
-    startpos = marker_position (w->start);
 
   SET_PT (startpos);
   lose = n < 0 && PT == BEGV;
@@ -2702,29 +2713,54 @@
 	 the window-scroll-functions.  */
       w->force_start = Qt;
 
-      /* If we scrolled forward, put point enough lines down
-	 that it is outside the scroll margin.  */
-      if (n > 0 && this_scroll_margin > 0)
+      if (whole)
 	{
 	  SET_PT (pos);
-	  Fvertical_motion (make_number (this_scroll_margin), window);
-	  pos = PT;
+	  Fvertical_motion (make_number (original_vpos), window);
 	}
-
-      if (pos > opoint)
+      /* If we scrolled forward, put point enough lines down
+	 that it is outside the scroll margin.  */
+      else if (n > 0)
 	{
-	  SET_PT (pos);
+	  int top_margin;
+
+	  if (this_scroll_margin > 0)
+	    {
+	      SET_PT (pos);
+	      Fvertical_motion (make_number (this_scroll_margin), window);
+	      top_margin = PT;
+	    }
+	  else
+	    top_margin = pos;
+
+	  if (top_margin <= opoint)
+	    SET_PT (opoint);
+	  else
+	    {
+	      SET_PT (pos);
+	      Fvertical_motion (make_number (original_vpos), window);
+	    }
 	}
-      if (n < 0)
+      else if (n < 0)
 	{
+	  int bottom_margin;
+
 	  /* If we scrolled backward, put point near the end of the window
 	     but not within the scroll margin.  */
 	  SET_PT (pos);
 	  tem = Fvertical_motion (make_number (ht - this_scroll_margin), window);
-	  if (PT > opoint || XFASTINT (tem) < ht - this_scroll_margin)
+	  if (XFASTINT (tem) == ht - this_scroll_margin)
+	    bottom_margin = PT;
+	  else
+	    bottom_margin = PT + 1;
+
+	  if (bottom_margin > opoint)
 	    SET_PT (opoint);
 	  else
-	    Fvertical_motion (make_number (-1), window);
+	    {
+	      SET_PT (pos);
+	      Fvertical_motion (make_number (original_vpos), window);
+	    }
 	}
     }
   else
@@ -2759,13 +2795,13 @@
   defalt = direction * (defalt < 1 ? 1 : defalt);
 
   if (NILP (n))
-    window_scroll (selected_window, defalt, 0);
+    window_scroll (selected_window, defalt, 1, 0);
   else if (EQ (n, Qminus))
-    window_scroll (selected_window, - defalt, 0);
+    window_scroll (selected_window, - defalt, 1, 0);
   else
     {
       n = Fprefix_numeric_value (n);
-      window_scroll (selected_window, XINT (n) * direction, 0);
+      window_scroll (selected_window, XINT (n) * direction, 0, 0);
     }
 
   unbind_to (count, Qnil);
@@ -2869,15 +2905,15 @@
   SET_PT (marker_position (w->pointm));
 
   if (NILP (arg))
-    window_scroll (window, defalt, 1);
+    window_scroll (window, defalt, 1, 1);
   else if (EQ (arg, Qminus))
-    window_scroll (window, -defalt, 1);
+    window_scroll (window, -defalt, 1, 1);
   else
     {
       if (CONSP (arg))
 	arg = Fcar (arg);
       CHECK_NUMBER (arg, 0);
-      window_scroll (window, XINT (arg), 1);
+      window_scroll (window, XINT (arg), 0, 1);
     }
 
   Fset_marker (w->pointm, make_number (PT), Qnil);