diff options
Diffstat (limited to 'src/xdisp.c')
-rw-r--r-- | src/xdisp.c | 62 |
1 files changed, 50 insertions, 12 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 5c273540c41..eb97ef110a9 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -12926,6 +12926,7 @@ redisplay_window (window, just_this_one_p) int rc; int centering_position = -1; int last_line_misfit = 0; + int save_beg_unchanged, save_end_unchanged; SET_TEXT_POS (lpoint, PT, PT_BYTE); opoint = lpoint; @@ -12990,6 +12991,9 @@ redisplay_window (window, just_this_one_p) set_buffer_internal_1 (XBUFFER (w->buffer)); SET_TEXT_POS (opoint, PT, PT_BYTE); + save_beg_unchanged = BEG_UNCHANGED; + save_end_unchanged = END_UNCHANGED; + current_matrix_up_to_date_p = (!NILP (w->window_end_valid) && !current_buffer->clip_changed @@ -13294,11 +13298,20 @@ redisplay_window (window, just_this_one_p) && NILP (do_mouse_tracking) && CHARPOS (startp) > BEGV) { - /* Make sure beg_unchanged and end_unchanged are up to date. - Do it only if buffer has really changed. This may or may - not have been done by try_window_id (see which) already. */ +#if 0 + /* The following code tried to make BEG_UNCHANGED and + END_UNCHANGED up to date (similar to try_window_id). + Is it important to do so? + + The trouble is that it's a little too strict when it + comes to overlays: modify_overlay can call + BUF_COMPUTE_UNCHANGED, which alters BUF_BEG_UNCHANGED and + BUF_END_UNCHANGED directly without moving the gap. + + This can result in spurious recentering when overlays are + altered in the buffer. So unless it's proven necessary, + let's leave this commented out for now. -- cyd. */ if (MODIFF > SAVE_MODIFF - /* This seems to happen sometimes after saving a buffer. */ || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE) { if (GPT - BEG < BEG_UNCHANGED) @@ -13306,9 +13319,10 @@ redisplay_window (window, just_this_one_p) if (Z - GPT < END_UNCHANGED) END_UNCHANGED = Z - GPT; } +#endif - if (CHARPOS (startp) > BEG + BEG_UNCHANGED - && CHARPOS (startp) <= Z - END_UNCHANGED) + if (CHARPOS (startp) > BEG + save_beg_unchanged + && CHARPOS (startp) <= Z - save_end_unchanged) { /* There doesn't seems to be a simple way to find a new window start that is near the old window start, so @@ -16002,13 +16016,37 @@ cursor_row_p (w, row) if (PT == MATRIX_ROW_END_CHARPOS (row)) { - /* If the row ends with a newline from a string, we don't want - the cursor there, but we still want it at the start of the - string if the string starts in this row. - If the row is continued it doesn't end in a newline. */ + /* Suppose the row ends on a string. + Unless the row is continued, that means it ends on a newline + in the string. If it's anything other than a display string + (e.g. a before-string from an overlay), we don't want the + cursor there. (This heuristic seems to give the optimal + behavior for the various types of multi-line strings.) */ if (CHARPOS (row->end.string_pos) >= 0) - cursor_row_p = (row->continued_p - || PT >= MATRIX_ROW_START_CHARPOS (row)); + { + if (row->continued_p) + cursor_row_p = 1; + else + { + /* Check for `display' property. */ + struct glyph *beg = row->glyphs[TEXT_AREA]; + struct glyph *end = beg + row->used[TEXT_AREA] - 1; + struct glyph *glyph; + + cursor_row_p = 0; + for (glyph = end; glyph >= beg; --glyph) + if (STRINGP (glyph->object)) + { + Lisp_Object prop + = Fget_char_property (make_number (PT), + Qdisplay, Qnil); + cursor_row_p = + (!NILP (prop) + && display_prop_string_p (prop, glyph->object)); + break; + } + } + } else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)) { /* If the row ends in middle of a real character, |