aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2016-07-05 19:33:01 +0300
committerEli Zaretskii2016-07-05 19:33:01 +0300
commit36e69bd82a0294b1f51d99a5eaf8e2c7661f7a16 (patch)
tree44fa24196ce4ed77b0cdbb6a3bf10b986da6a7d5 /src
parentc770dbb098a413b84b9f6d5afdc306d6c89c52cd (diff)
downloademacs-36e69bd82a0294b1f51d99a5eaf8e2c7661f7a16.tar.gz
emacs-36e69bd82a0294b1f51d99a5eaf8e2c7661f7a16.zip
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)
Diffstat (limited to 'src')
-rw-r--r--src/xdisp.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index d05eca169c3..d5ffb25eb18 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,
1321 if (CHARPOS (top) > ZV) 1321 if (CHARPOS (top) > ZV)
1322 SET_TEXT_POS (top, BEGV, BEGV_BYTE); 1322 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1323 1323
1324 /* If the top of the window is after CHARPOS, the latter is surely
1325 not visible. */
1326 if (charpos >= 0 && CHARPOS (top) > charpos)
1327 return visible_p;
1328
1324 /* Compute exact mode line heights. */ 1329 /* Compute exact mode line heights. */
1325 if (WINDOW_WANTS_MODELINE_P (w)) 1330 if (WINDOW_WANTS_MODELINE_P (w))
1326 w->mode_line_height 1331 w->mode_line_height
@@ -15512,12 +15517,14 @@ try_scrolling (Lisp_Object window, bool just_this_one_p,
15512 15517
15513 The new window start will be computed, based on W's width, starting 15518 The new window start will be computed, based on W's width, starting
15514 from the start of the continued line. It is the start of the 15519 from the start of the continued line. It is the start of the
15515 screen line with the minimum distance from the old start W->start. */ 15520 screen line with the minimum distance from the old start W->start,
15521 which is still before point (otherwise point will definitely not
15522 be visible in the window). */
15516 15523
15517static bool 15524static bool
15518compute_window_start_on_continuation_line (struct window *w) 15525compute_window_start_on_continuation_line (struct window *w)
15519{ 15526{
15520 struct text_pos pos, start_pos; 15527 struct text_pos pos, start_pos, pos_before_pt;
15521 bool window_start_changed_p = false; 15528 bool window_start_changed_p = false;
15522 15529
15523 SET_TEXT_POS_FROM_MARKER (start_pos, w->start); 15530 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
@@ -15545,10 +15552,14 @@ compute_window_start_on_continuation_line (struct window *w)
15545 reseat_at_previous_visible_line_start (&it); 15552 reseat_at_previous_visible_line_start (&it);
15546 15553
15547 /* If the line start is "too far" away from the window start, 15554 /* If the line start is "too far" away from the window start,
15548 say it takes too much time to compute a new window start. */ 15555 say it takes too much time to compute a new window start.
15549 if (CHARPOS (start_pos) - IT_CHARPOS (it) 15556 Also, give up if the line start is after point, as in that
15550 /* PXW: Do we need upper bounds here? */ 15557 case point will not be visible with any window start we
15551 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w)) 15558 compute. */
15559 if (IT_CHARPOS (it) <= PT
15560 || (CHARPOS (start_pos) - IT_CHARPOS (it)
15561 /* PXW: Do we need upper bounds here? */
15562 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w)))
15552 { 15563 {
15553 int min_distance, distance; 15564 int min_distance, distance;
15554 15565
@@ -15558,12 +15569,14 @@ compute_window_start_on_continuation_line (struct window *w)
15558 decreased, the new window start will be < the old start. 15569 decreased, the new window start will be < the old start.
15559 So, we're looking for the display line start with the 15570 So, we're looking for the display line start with the
15560 minimum distance from the old window start. */ 15571 minimum distance from the old window start. */
15561 pos = it.current.pos; 15572 pos_before_pt = pos = it.current.pos;
15562 min_distance = INFINITY; 15573 min_distance = INFINITY;
15563 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))), 15574 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
15564 distance < min_distance) 15575 distance < min_distance)
15565 { 15576 {
15566 min_distance = distance; 15577 min_distance = distance;
15578 if (CHARPOS (pos) <= PT)
15579 pos_before_pt = pos;
15567 pos = it.current.pos; 15580 pos = it.current.pos;
15568 if (it.line_wrap == WORD_WRAP) 15581 if (it.line_wrap == WORD_WRAP)
15569 { 15582 {
@@ -15586,6 +15599,13 @@ compute_window_start_on_continuation_line (struct window *w)
15586 move_it_by_lines (&it, 1); 15599 move_it_by_lines (&it, 1);
15587 } 15600 }
15588 15601
15602 /* It makes very little sense to make the new window start
15603 after point, as point won't be visible. If that's what
15604 the loop above finds, fall back on the candidate before
15605 or at point that is closest to the old window start. */
15606 if (CHARPOS (pos) > PT)
15607 pos = pos_before_pt;
15608
15589 /* Set the window start there. */ 15609 /* Set the window start there. */
15590 SET_MARKER_FROM_TEXT_POS (w->start, pos); 15610 SET_MARKER_FROM_TEXT_POS (w->start, pos);
15591 window_start_changed_p = true; 15611 window_start_changed_p = true;