diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 103 |
1 files changed, 59 insertions, 44 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index f7a3b6dc914..85044a3713d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -863,7 +863,7 @@ static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *, | |||
| 863 | Lisp_Object)); | 863 | Lisp_Object)); |
| 864 | static void extend_face_to_end_of_line P_ ((struct it *)); | 864 | static void extend_face_to_end_of_line P_ ((struct it *)); |
| 865 | static int append_space_for_newline P_ ((struct it *, int)); | 865 | static int append_space_for_newline P_ ((struct it *, int)); |
| 866 | static int make_cursor_line_fully_visible P_ ((struct window *, int)); | 866 | static int cursor_row_fully_visible_p P_ ((struct window *, int, int)); |
| 867 | static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int)); | 867 | static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int)); |
| 868 | static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *)); | 868 | static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *)); |
| 869 | static int trailing_whitespace_p P_ ((int)); | 869 | static int trailing_whitespace_p P_ ((int)); |
| @@ -1285,8 +1285,8 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p) | |||
| 1285 | } | 1285 | } |
| 1286 | 1286 | ||
| 1287 | start_display (&it, w, top); | 1287 | start_display (&it, w, top); |
| 1288 | move_it_to (&it, charpos, 0, it.last_visible_y, -1, | 1288 | move_it_to (&it, charpos, -1, it.last_visible_y, -1, |
| 1289 | MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); | 1289 | MOVE_TO_POS | MOVE_TO_Y); |
| 1290 | 1290 | ||
| 1291 | /* Note that we may overshoot because of invisible text. */ | 1291 | /* Note that we may overshoot because of invisible text. */ |
| 1292 | if (IT_CHARPOS (it) >= charpos) | 1292 | if (IT_CHARPOS (it) >= charpos) |
| @@ -1310,12 +1310,13 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p) | |||
| 1310 | } | 1310 | } |
| 1311 | } | 1311 | } |
| 1312 | } | 1312 | } |
| 1313 | else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y) | 1313 | else |
| 1314 | { | 1314 | { |
| 1315 | struct it it2; | 1315 | struct it it2; |
| 1316 | 1316 | ||
| 1317 | it2 = it; | 1317 | it2 = it; |
| 1318 | move_it_by_lines (&it, 1, 0); | 1318 | if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n') |
| 1319 | move_it_by_lines (&it, 1, 0); | ||
| 1319 | if (charpos < IT_CHARPOS (it)) | 1320 | if (charpos < IT_CHARPOS (it)) |
| 1320 | { | 1321 | { |
| 1321 | visible_p = 1; | 1322 | visible_p = 1; |
| @@ -1326,8 +1327,9 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p) | |||
| 1326 | *y = it2.current_y + it2.max_ascent - it2.ascent; | 1327 | *y = it2.current_y + it2.max_ascent - it2.ascent; |
| 1327 | if (rtop) | 1328 | if (rtop) |
| 1328 | { | 1329 | { |
| 1329 | *rtop = 0; | 1330 | *rtop = max (0, -it2.current_y); |
| 1330 | *rbot = max (0, (it2.current_y + it2.max_ascent + it2.max_descent) - it.last_visible_y); | 1331 | *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent) |
| 1332 | - it.last_visible_y)); | ||
| 1331 | } | 1333 | } |
| 1332 | } | 1334 | } |
| 1333 | } | 1335 | } |
| @@ -4697,27 +4699,31 @@ back_to_previous_visible_line_start (it) | |||
| 4697 | /* If newline has a display property that replaces the newline with something | 4699 | /* If newline has a display property that replaces the newline with something |
| 4698 | else (image or text), find start of overlay or interval and continue search | 4700 | else (image or text), find start of overlay or interval and continue search |
| 4699 | from that point. */ | 4701 | from that point. */ |
| 4700 | { | 4702 | if (IT_CHARPOS (*it) > BEGV) |
| 4701 | struct it it2 = *it; | 4703 | { |
| 4702 | int pos = IT_CHARPOS (*it); | 4704 | struct it it2 = *it; |
| 4703 | int beg, end; | 4705 | int pos; |
| 4704 | Lisp_Object val, overlay; | 4706 | int beg, end; |
| 4705 | 4707 | Lisp_Object val, overlay; | |
| 4706 | it2.sp = 0; | 4708 | |
| 4707 | if (handle_display_prop (&it2) == HANDLED_RETURN | 4709 | pos = --IT_CHARPOS (it2); |
| 4708 | && !NILP (val = get_char_property_and_overlay | 4710 | --IT_BYTEPOS (it2); |
| 4709 | (make_number (pos), Qdisplay, Qnil, &overlay)) | 4711 | it2.sp = 0; |
| 4710 | && (OVERLAYP (overlay) | 4712 | if (handle_display_prop (&it2) == HANDLED_RETURN |
| 4711 | ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay))) | 4713 | && !NILP (val = get_char_property_and_overlay |
| 4712 | : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil))) | 4714 | (make_number (pos), Qdisplay, Qnil, &overlay)) |
| 4713 | { | 4715 | && (OVERLAYP (overlay) |
| 4714 | if (beg < BEGV) | 4716 | ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay))) |
| 4715 | beg = BEGV; | 4717 | : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil))) |
| 4716 | IT_CHARPOS (*it) = beg; | 4718 | { |
| 4717 | IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg); | 4719 | if (beg < BEGV) |
| 4718 | continue; | 4720 | beg = BEGV; |
| 4719 | } | 4721 | IT_CHARPOS (*it) = beg; |
| 4720 | } | 4722 | IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg); |
| 4723 | continue; | ||
| 4724 | } | ||
| 4725 | } | ||
| 4726 | |||
| 4721 | break; | 4727 | break; |
| 4722 | } | 4728 | } |
| 4723 | 4729 | ||
| @@ -6330,7 +6336,8 @@ move_it_vertically_backward (it, dy) | |||
| 6330 | a line height of 13 pixels each, recentering with point | 6336 | a line height of 13 pixels each, recentering with point |
| 6331 | on the bottom line will try to move -39/2 = 19 pixels | 6337 | on the bottom line will try to move -39/2 = 19 pixels |
| 6332 | backward. Try to avoid moving into the first line. */ | 6338 | backward. Try to avoid moving into the first line. */ |
| 6333 | && it->current_y - target_y > line_height * 2 / 3 | 6339 | && (it->current_y - target_y |
| 6340 | > min (window_box_height (it->w), line_height * 2 / 3)) | ||
| 6334 | && IT_CHARPOS (*it) > BEGV) | 6341 | && IT_CHARPOS (*it) > BEGV) |
| 6335 | { | 6342 | { |
| 6336 | TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n", | 6343 | TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n", |
| @@ -11088,7 +11095,7 @@ run_window_scroll_functions (window, startp) | |||
| 11088 | as if point had gone off the screen. */ | 11095 | as if point had gone off the screen. */ |
| 11089 | 11096 | ||
| 11090 | static int | 11097 | static int |
| 11091 | make_cursor_line_fully_visible (w, force_p) | 11098 | cursor_row_fully_visible_p (w, force_p, current_matrix_p) |
| 11092 | struct window *w; | 11099 | struct window *w; |
| 11093 | int force_p; | 11100 | int force_p; |
| 11094 | { | 11101 | { |
| @@ -11104,7 +11111,7 @@ make_cursor_line_fully_visible (w, force_p) | |||
| 11104 | if (w->cursor.vpos < 0) | 11111 | if (w->cursor.vpos < 0) |
| 11105 | return 1; | 11112 | return 1; |
| 11106 | 11113 | ||
| 11107 | matrix = w->desired_matrix; | 11114 | matrix = current_matrix_p ? w->current_matrix : w->desired_matrix; |
| 11108 | row = MATRIX_ROW (matrix, w->cursor.vpos); | 11115 | row = MATRIX_ROW (matrix, w->cursor.vpos); |
| 11109 | 11116 | ||
| 11110 | /* If the cursor row is not partially visible, there's nothing to do. */ | 11117 | /* If the cursor row is not partially visible, there's nothing to do. */ |
| @@ -11409,7 +11416,7 @@ try_scrolling (window, just_this_one_p, scroll_conservatively, | |||
| 11409 | 11416 | ||
| 11410 | /* If cursor ends up on a partially visible line, | 11417 | /* If cursor ends up on a partially visible line, |
| 11411 | treat that as being off the bottom of the screen. */ | 11418 | treat that as being off the bottom of the screen. */ |
| 11412 | if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1)) | 11419 | if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)) |
| 11413 | { | 11420 | { |
| 11414 | clear_glyph_matrix (w->desired_matrix); | 11421 | clear_glyph_matrix (w->desired_matrix); |
| 11415 | ++extra_scroll_margin_lines; | 11422 | ++extra_scroll_margin_lines; |
| @@ -11679,6 +11686,12 @@ try_cursor_movement (window, startp, scroll_step) | |||
| 11679 | && CHARPOS (startp) != BEGV) | 11686 | && CHARPOS (startp) != BEGV) |
| 11680 | scroll_p = 1; | 11687 | scroll_p = 1; |
| 11681 | } | 11688 | } |
| 11689 | else | ||
| 11690 | { | ||
| 11691 | /* Cursor did not move. So don't scroll even if cursor line | ||
| 11692 | is partially visible, as it was so before. */ | ||
| 11693 | rc = CURSOR_MOVEMENT_SUCCESS; | ||
| 11694 | } | ||
| 11682 | 11695 | ||
| 11683 | if (PT < MATRIX_ROW_START_CHARPOS (row) | 11696 | if (PT < MATRIX_ROW_START_CHARPOS (row) |
| 11684 | || PT > MATRIX_ROW_END_CHARPOS (row)) | 11697 | || PT > MATRIX_ROW_END_CHARPOS (row)) |
| @@ -11686,7 +11699,8 @@ try_cursor_movement (window, startp, scroll_step) | |||
| 11686 | /* if PT is not in the glyph row, give up. */ | 11699 | /* if PT is not in the glyph row, give up. */ |
| 11687 | rc = CURSOR_MOVEMENT_MUST_SCROLL; | 11700 | rc = CURSOR_MOVEMENT_MUST_SCROLL; |
| 11688 | } | 11701 | } |
| 11689 | else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row) | 11702 | else if (rc != CURSOR_MOVEMENT_SUCCESS |
| 11703 | && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row) | ||
| 11690 | && make_cursor_line_fully_visible_p) | 11704 | && make_cursor_line_fully_visible_p) |
| 11691 | { | 11705 | { |
| 11692 | if (PT == MATRIX_ROW_END_CHARPOS (row) | 11706 | if (PT == MATRIX_ROW_END_CHARPOS (row) |
| @@ -11705,7 +11719,7 @@ try_cursor_movement (window, startp, scroll_step) | |||
| 11705 | else | 11719 | else |
| 11706 | { | 11720 | { |
| 11707 | set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); | 11721 | set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); |
| 11708 | if (!make_cursor_line_fully_visible (w, 0)) | 11722 | if (!cursor_row_fully_visible_p (w, 0, 1)) |
| 11709 | rc = CURSOR_MOVEMENT_MUST_SCROLL; | 11723 | rc = CURSOR_MOVEMENT_MUST_SCROLL; |
| 11710 | else | 11724 | else |
| 11711 | rc = CURSOR_MOVEMENT_SUCCESS; | 11725 | rc = CURSOR_MOVEMENT_SUCCESS; |
| @@ -11790,7 +11804,7 @@ redisplay_window (window, just_this_one_p) | |||
| 11790 | int temp_scroll_step = 0; | 11804 | int temp_scroll_step = 0; |
| 11791 | int count = SPECPDL_INDEX (); | 11805 | int count = SPECPDL_INDEX (); |
| 11792 | int rc; | 11806 | int rc; |
| 11793 | int centering_position; | 11807 | int centering_position = -1; |
| 11794 | int last_line_misfit = 0; | 11808 | int last_line_misfit = 0; |
| 11795 | 11809 | ||
| 11796 | SET_TEXT_POS (lpoint, PT, PT_BYTE); | 11810 | SET_TEXT_POS (lpoint, PT, PT_BYTE); |
| @@ -12036,7 +12050,7 @@ redisplay_window (window, just_this_one_p) | |||
| 12036 | new_vpos = window_box_height (w) / 2; | 12050 | new_vpos = window_box_height (w) / 2; |
| 12037 | } | 12051 | } |
| 12038 | 12052 | ||
| 12039 | if (!make_cursor_line_fully_visible (w, 0)) | 12053 | if (!cursor_row_fully_visible_p (w, 0, 0)) |
| 12040 | { | 12054 | { |
| 12041 | /* Point does appear, but on a line partly visible at end of window. | 12055 | /* Point does appear, but on a line partly visible at end of window. |
| 12042 | Move it back to a fully-visible line. */ | 12056 | Move it back to a fully-visible line. */ |
| @@ -12173,7 +12187,7 @@ redisplay_window (window, just_this_one_p) | |||
| 12173 | /* Forget any recorded base line for line number display. */ | 12187 | /* Forget any recorded base line for line number display. */ |
| 12174 | w->base_line_number = Qnil; | 12188 | w->base_line_number = Qnil; |
| 12175 | 12189 | ||
| 12176 | if (!make_cursor_line_fully_visible (w, 1)) | 12190 | if (!cursor_row_fully_visible_p (w, 1, 0)) |
| 12177 | { | 12191 | { |
| 12178 | clear_glyph_matrix (w->desired_matrix); | 12192 | clear_glyph_matrix (w->desired_matrix); |
| 12179 | last_line_misfit = 1; | 12193 | last_line_misfit = 1; |
| @@ -12233,10 +12247,8 @@ redisplay_window (window, just_this_one_p) | |||
| 12233 | /* Finally, just choose place to start which centers point */ | 12247 | /* Finally, just choose place to start which centers point */ |
| 12234 | 12248 | ||
| 12235 | recenter: | 12249 | recenter: |
| 12236 | centering_position = window_box_height (w) / 2; | 12250 | if (centering_position < 0) |
| 12237 | 12251 | centering_position = window_box_height (w) / 2; | |
| 12238 | point_at_top: | ||
| 12239 | /* Jump here with centering_position already set to 0. */ | ||
| 12240 | 12252 | ||
| 12241 | #if GLYPH_DEBUG | 12253 | #if GLYPH_DEBUG |
| 12242 | debug_method_add (w, "recenter"); | 12254 | debug_method_add (w, "recenter"); |
| @@ -12333,7 +12345,7 @@ redisplay_window (window, just_this_one_p) | |||
| 12333 | set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); | 12345 | set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); |
| 12334 | } | 12346 | } |
| 12335 | 12347 | ||
| 12336 | if (!make_cursor_line_fully_visible (w, centering_position > 0)) | 12348 | if (!cursor_row_fully_visible_p (w, 0, 0)) |
| 12337 | { | 12349 | { |
| 12338 | /* If vscroll is enabled, disable it and try again. */ | 12350 | /* If vscroll is enabled, disable it and try again. */ |
| 12339 | if (w->vscroll) | 12351 | if (w->vscroll) |
| @@ -12348,9 +12360,10 @@ redisplay_window (window, just_this_one_p) | |||
| 12348 | visible, if it can be done. */ | 12360 | visible, if it can be done. */ |
| 12349 | if (centering_position == 0) | 12361 | if (centering_position == 0) |
| 12350 | goto done; | 12362 | goto done; |
| 12363 | |||
| 12351 | clear_glyph_matrix (w->desired_matrix); | 12364 | clear_glyph_matrix (w->desired_matrix); |
| 12352 | centering_position = 0; | 12365 | centering_position = 0; |
| 12353 | goto point_at_top; | 12366 | goto recenter; |
| 12354 | } | 12367 | } |
| 12355 | 12368 | ||
| 12356 | done: | 12369 | done: |
| @@ -13135,8 +13148,10 @@ find_first_unchanged_at_end_row (w, delta, delta_bytes) | |||
| 13135 | starts at a minimum position >= last_unchanged_pos_old. */ | 13148 | starts at a minimum position >= last_unchanged_pos_old. */ |
| 13136 | for (; row > first_text_row; --row) | 13149 | for (; row > first_text_row; --row) |
| 13137 | { | 13150 | { |
| 13151 | /* This used to abort, but it can happen. | ||
| 13152 | It is ok to just stop the search instead here. KFS. */ | ||
| 13138 | if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row)) | 13153 | if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row)) |
| 13139 | abort (); | 13154 | break; |
| 13140 | 13155 | ||
| 13141 | if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old) | 13156 | if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old) |
| 13142 | row_found = row; | 13157 | row_found = row; |