aboutsummaryrefslogtreecommitdiffstats
path: root/src/xdisp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xdisp.c')
-rw-r--r--src/xdisp.c103
1 files changed, 59 insertions, 44 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index 142b1fb1398..f8f97b44b3b 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -859,7 +859,7 @@ static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
859 Lisp_Object)); 859 Lisp_Object));
860static void extend_face_to_end_of_line P_ ((struct it *)); 860static void extend_face_to_end_of_line P_ ((struct it *));
861static int append_space_for_newline P_ ((struct it *, int)); 861static int append_space_for_newline P_ ((struct it *, int));
862static int make_cursor_line_fully_visible P_ ((struct window *, int)); 862static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
863static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int)); 863static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
864static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *)); 864static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
865static int trailing_whitespace_p P_ ((int)); 865static int trailing_whitespace_p P_ ((int));
@@ -1281,8 +1281,8 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
1281 } 1281 }
1282 1282
1283 start_display (&it, w, top); 1283 start_display (&it, w, top);
1284 move_it_to (&it, charpos, 0, it.last_visible_y, -1, 1284 move_it_to (&it, charpos, -1, it.last_visible_y, -1,
1285 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); 1285 MOVE_TO_POS | MOVE_TO_Y);
1286 1286
1287 /* Note that we may overshoot because of invisible text. */ 1287 /* Note that we may overshoot because of invisible text. */
1288 if (IT_CHARPOS (it) >= charpos) 1288 if (IT_CHARPOS (it) >= charpos)
@@ -1306,12 +1306,13 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
1306 } 1306 }
1307 } 1307 }
1308 } 1308 }
1309 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y) 1309 else
1310 { 1310 {
1311 struct it it2; 1311 struct it it2;
1312 1312
1313 it2 = it; 1313 it2 = it;
1314 move_it_by_lines (&it, 1, 0); 1314 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1315 move_it_by_lines (&it, 1, 0);
1315 if (charpos < IT_CHARPOS (it)) 1316 if (charpos < IT_CHARPOS (it))
1316 { 1317 {
1317 visible_p = 1; 1318 visible_p = 1;
@@ -1322,8 +1323,9 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
1322 *y = it2.current_y + it2.max_ascent - it2.ascent; 1323 *y = it2.current_y + it2.max_ascent - it2.ascent;
1323 if (rtop) 1324 if (rtop)
1324 { 1325 {
1325 *rtop = 0; 1326 *rtop = max (0, -it2.current_y);
1326 *rbot = max (0, (it2.current_y + it2.max_ascent + it2.max_descent) - it.last_visible_y); 1327 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1328 - it.last_visible_y));
1327 } 1329 }
1328 } 1330 }
1329 } 1331 }
@@ -4693,27 +4695,31 @@ back_to_previous_visible_line_start (it)
4693 /* If newline has a display property that replaces the newline with something 4695 /* If newline has a display property that replaces the newline with something
4694 else (image or text), find start of overlay or interval and continue search 4696 else (image or text), find start of overlay or interval and continue search
4695 from that point. */ 4697 from that point. */
4696 { 4698 if (IT_CHARPOS (*it) > BEGV)
4697 struct it it2 = *it; 4699 {
4698 int pos = IT_CHARPOS (*it); 4700 struct it it2 = *it;
4699 int beg, end; 4701 int pos;
4700 Lisp_Object val, overlay; 4702 int beg, end;
4701 4703 Lisp_Object val, overlay;
4702 it2.sp = 0; 4704
4703 if (handle_display_prop (&it2) == HANDLED_RETURN 4705 pos = --IT_CHARPOS (it2);
4704 && !NILP (val = get_char_property_and_overlay 4706 --IT_BYTEPOS (it2);
4705 (make_number (pos), Qdisplay, Qnil, &overlay)) 4707 it2.sp = 0;
4706 && (OVERLAYP (overlay) 4708 if (handle_display_prop (&it2) == HANDLED_RETURN
4707 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay))) 4709 && !NILP (val = get_char_property_and_overlay
4708 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil))) 4710 (make_number (pos), Qdisplay, Qnil, &overlay))
4709 { 4711 && (OVERLAYP (overlay)
4710 if (beg < BEGV) 4712 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
4711 beg = BEGV; 4713 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
4712 IT_CHARPOS (*it) = beg; 4714 {
4713 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg); 4715 if (beg < BEGV)
4714 continue; 4716 beg = BEGV;
4715 } 4717 IT_CHARPOS (*it) = beg;
4716 } 4718 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
4719 continue;
4720 }
4721 }
4722
4717 break; 4723 break;
4718 } 4724 }
4719 4725
@@ -6326,7 +6332,8 @@ move_it_vertically_backward (it, dy)
6326 a line height of 13 pixels each, recentering with point 6332 a line height of 13 pixels each, recentering with point
6327 on the bottom line will try to move -39/2 = 19 pixels 6333 on the bottom line will try to move -39/2 = 19 pixels
6328 backward. Try to avoid moving into the first line. */ 6334 backward. Try to avoid moving into the first line. */
6329 && it->current_y - target_y > line_height * 2 / 3 6335 && (it->current_y - target_y
6336 > min (window_box_height (it->w), line_height * 2 / 3))
6330 && IT_CHARPOS (*it) > BEGV) 6337 && IT_CHARPOS (*it) > BEGV)
6331 { 6338 {
6332 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n", 6339 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
@@ -11084,7 +11091,7 @@ run_window_scroll_functions (window, startp)
11084 as if point had gone off the screen. */ 11091 as if point had gone off the screen. */
11085 11092
11086static int 11093static int
11087make_cursor_line_fully_visible (w, force_p) 11094cursor_row_fully_visible_p (w, force_p, current_matrix_p)
11088 struct window *w; 11095 struct window *w;
11089 int force_p; 11096 int force_p;
11090{ 11097{
@@ -11100,7 +11107,7 @@ make_cursor_line_fully_visible (w, force_p)
11100 if (w->cursor.vpos < 0) 11107 if (w->cursor.vpos < 0)
11101 return 1; 11108 return 1;
11102 11109
11103 matrix = w->desired_matrix; 11110 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
11104 row = MATRIX_ROW (matrix, w->cursor.vpos); 11111 row = MATRIX_ROW (matrix, w->cursor.vpos);
11105 11112
11106 /* If the cursor row is not partially visible, there's nothing to do. */ 11113 /* If the cursor row is not partially visible, there's nothing to do. */
@@ -11405,7 +11412,7 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
11405 11412
11406 /* If cursor ends up on a partially visible line, 11413 /* If cursor ends up on a partially visible line,
11407 treat that as being off the bottom of the screen. */ 11414 treat that as being off the bottom of the screen. */
11408 if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1)) 11415 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
11409 { 11416 {
11410 clear_glyph_matrix (w->desired_matrix); 11417 clear_glyph_matrix (w->desired_matrix);
11411 ++extra_scroll_margin_lines; 11418 ++extra_scroll_margin_lines;
@@ -11675,6 +11682,12 @@ try_cursor_movement (window, startp, scroll_step)
11675 && CHARPOS (startp) != BEGV) 11682 && CHARPOS (startp) != BEGV)
11676 scroll_p = 1; 11683 scroll_p = 1;
11677 } 11684 }
11685 else
11686 {
11687 /* Cursor did not move. So don't scroll even if cursor line
11688 is partially visible, as it was so before. */
11689 rc = CURSOR_MOVEMENT_SUCCESS;
11690 }
11678 11691
11679 if (PT < MATRIX_ROW_START_CHARPOS (row) 11692 if (PT < MATRIX_ROW_START_CHARPOS (row)
11680 || PT > MATRIX_ROW_END_CHARPOS (row)) 11693 || PT > MATRIX_ROW_END_CHARPOS (row))
@@ -11682,7 +11695,8 @@ try_cursor_movement (window, startp, scroll_step)
11682 /* if PT is not in the glyph row, give up. */ 11695 /* if PT is not in the glyph row, give up. */
11683 rc = CURSOR_MOVEMENT_MUST_SCROLL; 11696 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11684 } 11697 }
11685 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row) 11698 else if (rc != CURSOR_MOVEMENT_SUCCESS
11699 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
11686 && make_cursor_line_fully_visible_p) 11700 && make_cursor_line_fully_visible_p)
11687 { 11701 {
11688 if (PT == MATRIX_ROW_END_CHARPOS (row) 11702 if (PT == MATRIX_ROW_END_CHARPOS (row)
@@ -11701,7 +11715,7 @@ try_cursor_movement (window, startp, scroll_step)
11701 else 11715 else
11702 { 11716 {
11703 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); 11717 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11704 if (!make_cursor_line_fully_visible (w, 0)) 11718 if (!cursor_row_fully_visible_p (w, 0, 1))
11705 rc = CURSOR_MOVEMENT_MUST_SCROLL; 11719 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11706 else 11720 else
11707 rc = CURSOR_MOVEMENT_SUCCESS; 11721 rc = CURSOR_MOVEMENT_SUCCESS;
@@ -11788,7 +11802,7 @@ redisplay_window (window, just_this_one_p)
11788 int temp_scroll_step = 0; 11802 int temp_scroll_step = 0;
11789 int count = SPECPDL_INDEX (); 11803 int count = SPECPDL_INDEX ();
11790 int rc; 11804 int rc;
11791 int centering_position; 11805 int centering_position = -1;
11792 int last_line_misfit = 0; 11806 int last_line_misfit = 0;
11793 11807
11794 SET_TEXT_POS (lpoint, PT, PT_BYTE); 11808 SET_TEXT_POS (lpoint, PT, PT_BYTE);
@@ -12034,7 +12048,7 @@ redisplay_window (window, just_this_one_p)
12034 new_vpos = window_box_height (w) / 2; 12048 new_vpos = window_box_height (w) / 2;
12035 } 12049 }
12036 12050
12037 if (!make_cursor_line_fully_visible (w, 0)) 12051 if (!cursor_row_fully_visible_p (w, 0, 0))
12038 { 12052 {
12039 /* Point does appear, but on a line partly visible at end of window. 12053 /* Point does appear, but on a line partly visible at end of window.
12040 Move it back to a fully-visible line. */ 12054 Move it back to a fully-visible line. */
@@ -12171,7 +12185,7 @@ redisplay_window (window, just_this_one_p)
12171 /* Forget any recorded base line for line number display. */ 12185 /* Forget any recorded base line for line number display. */
12172 w->base_line_number = Qnil; 12186 w->base_line_number = Qnil;
12173 12187
12174 if (!make_cursor_line_fully_visible (w, 1)) 12188 if (!cursor_row_fully_visible_p (w, 1, 0))
12175 { 12189 {
12176 clear_glyph_matrix (w->desired_matrix); 12190 clear_glyph_matrix (w->desired_matrix);
12177 last_line_misfit = 1; 12191 last_line_misfit = 1;
@@ -12231,10 +12245,8 @@ redisplay_window (window, just_this_one_p)
12231 /* Finally, just choose place to start which centers point */ 12245 /* Finally, just choose place to start which centers point */
12232 12246
12233 recenter: 12247 recenter:
12234 centering_position = window_box_height (w) / 2; 12248 if (centering_position < 0)
12235 12249 centering_position = window_box_height (w) / 2;
12236 point_at_top:
12237 /* Jump here with centering_position already set to 0. */
12238 12250
12239#if GLYPH_DEBUG 12251#if GLYPH_DEBUG
12240 debug_method_add (w, "recenter"); 12252 debug_method_add (w, "recenter");
@@ -12331,7 +12343,7 @@ redisplay_window (window, just_this_one_p)
12331 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); 12343 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12332 } 12344 }
12333 12345
12334 if (!make_cursor_line_fully_visible (w, centering_position > 0)) 12346 if (!cursor_row_fully_visible_p (w, 0, 0))
12335 { 12347 {
12336 /* If vscroll is enabled, disable it and try again. */ 12348 /* If vscroll is enabled, disable it and try again. */
12337 if (w->vscroll) 12349 if (w->vscroll)
@@ -12346,9 +12358,10 @@ redisplay_window (window, just_this_one_p)
12346 visible, if it can be done. */ 12358 visible, if it can be done. */
12347 if (centering_position == 0) 12359 if (centering_position == 0)
12348 goto done; 12360 goto done;
12361
12349 clear_glyph_matrix (w->desired_matrix); 12362 clear_glyph_matrix (w->desired_matrix);
12350 centering_position = 0; 12363 centering_position = 0;
12351 goto point_at_top; 12364 goto recenter;
12352 } 12365 }
12353 12366
12354 done: 12367 done:
@@ -13136,8 +13149,10 @@ find_first_unchanged_at_end_row (w, delta, delta_bytes)
13136 starts at a minimum position >= last_unchanged_pos_old. */ 13149 starts at a minimum position >= last_unchanged_pos_old. */
13137 for (; row > first_text_row; --row) 13150 for (; row > first_text_row; --row)
13138 { 13151 {
13152 /* This used to abort, but it can happen.
13153 It is ok to just stop the search instead here. KFS. */
13139 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row)) 13154 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
13140 abort (); 13155 break;
13141 13156
13142 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old) 13157 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
13143 row_found = row; 13158 row_found = row;