diff options
Diffstat (limited to 'src/xdisp.c')
| -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 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)); |
| 860 | static void extend_face_to_end_of_line P_ ((struct it *)); | 860 | static void extend_face_to_end_of_line P_ ((struct it *)); |
| 861 | static int append_space_for_newline P_ ((struct it *, int)); | 861 | static int append_space_for_newline P_ ((struct it *, int)); |
| 862 | static int make_cursor_line_fully_visible P_ ((struct window *, int)); | 862 | static int cursor_row_fully_visible_p P_ ((struct window *, int, int)); |
| 863 | static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int)); | 863 | static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int)); |
| 864 | static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *)); | 864 | static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *)); |
| 865 | static int trailing_whitespace_p P_ ((int)); | 865 | static 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 | ||
| 11086 | static int | 11093 | static int |
| 11087 | make_cursor_line_fully_visible (w, force_p) | 11094 | cursor_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; |