emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 36e69bd: Fix redisplay with window-start on continu


From: Eli Zaretskii
Subject: [Emacs-diffs] master 36e69bd: Fix redisplay with window-start on continuation lines
Date: Tue, 5 Jul 2016 16:34:31 +0000 (UTC)

branch: master
commit 36e69bd82a0294b1f51d99a5eaf8e2c7661f7a16
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    Fix redisplay with window-start on continuation lines
    
    * src/xdisp.c (pos_visible_p): Return false if the window starts
    after CHARPOS.
    (compute_window_start_on_continuation_line): Don't return
    window-start position that is after point in the buffer, as the
    callers don't expect this to happen, and will generally display an
    empty window with the cursor in its middle.  (Bug#23871)
---
 src/xdisp.c |   34 +++++++++++++++++++++++++++-------
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/src/xdisp.c b/src/xdisp.c
index d05eca1..d5ffb25 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1321,6 +1321,11 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int 
*x, int *y,
   if (CHARPOS (top) > ZV)
     SET_TEXT_POS (top, BEGV, BEGV_BYTE);
 
+  /* If the top of the window is after CHARPOS, the latter is surely
+     not visible.  */
+  if (charpos >= 0 && CHARPOS (top) > charpos)
+    return visible_p;
+
   /* Compute exact mode line heights.  */
   if (WINDOW_WANTS_MODELINE_P (w))
     w->mode_line_height
@@ -15512,12 +15517,14 @@ try_scrolling (Lisp_Object window, bool 
just_this_one_p,
 
    The new window start will be computed, based on W's width, starting
    from the start of the continued line.  It is the start of the
-   screen line with the minimum distance from the old start W->start.  */
+   screen line with the minimum distance from the old start W->start,
+   which is still before point (otherwise point will definitely not
+   be visible in the window).  */
 
 static bool
 compute_window_start_on_continuation_line (struct window *w)
 {
-  struct text_pos pos, start_pos;
+  struct text_pos pos, start_pos, pos_before_pt;
   bool window_start_changed_p = false;
 
   SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
@@ -15545,10 +15552,14 @@ compute_window_start_on_continuation_line (struct 
window *w)
       reseat_at_previous_visible_line_start (&it);
 
       /* If the line start is "too far" away from the window start,
-         say it takes too much time to compute a new window start.  */
-      if (CHARPOS (start_pos) - IT_CHARPOS (it)
-         /* PXW: Do we need upper bounds here?  */
-         < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
+         say it takes too much time to compute a new window start.
+         Also, give up if the line start is after point, as in that
+         case point will not be visible with any window start we
+         compute.  */
+      if (IT_CHARPOS (it) <= PT
+         || (CHARPOS (start_pos) - IT_CHARPOS (it)
+             /* PXW: Do we need upper bounds here?  */
+             < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w)))
        {
          int min_distance, distance;
 
@@ -15558,12 +15569,14 @@ compute_window_start_on_continuation_line (struct 
window *w)
             decreased, the new window start will be < the old start.
             So, we're looking for the display line start with the
             minimum distance from the old window start.  */
-         pos = it.current.pos;
+         pos_before_pt = pos = it.current.pos;
          min_distance = INFINITY;
          while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
                 distance < min_distance)
            {
              min_distance = distance;
+             if (CHARPOS (pos) <= PT)
+               pos_before_pt = pos;
              pos = it.current.pos;
              if (it.line_wrap == WORD_WRAP)
                {
@@ -15586,6 +15599,13 @@ compute_window_start_on_continuation_line (struct 
window *w)
                move_it_by_lines (&it, 1);
            }
 
+         /* It makes very little sense to make the new window start
+            after point, as point won't be visible.  If that's what
+            the loop above finds, fall back on the candidate before
+            or at point that is closest to the old window start.  */
+         if (CHARPOS (pos) > PT)
+           pos = pos_before_pt;
+
          /* Set the window start there.  */
          SET_MARKER_FROM_TEXT_POS (w->start, pos);
          window_start_changed_p = true;



reply via email to

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