=== modified file 'src/window.h' --- src/window.h 2013-02-04 15:39:55 +0000 +++ src/window.h 2013-02-05 09:58:36 +0000 @@ -333,15 +333,13 @@ the frame image that window_end_pos did not get onto the frame. */ unsigned window_end_valid : 1; + /* Nonzero if we have highlighted the region (or any part of it). */ + unsigned region_showing : 1; + /* Amount by which lines of this window are scrolled in y-direction (smooth scrolling). */ int vscroll; - /* If we have highlighted the region (or any part of it), the mark - position or -1 (the latter is used by the iterator for internal - purposes); otherwise zero. */ - ptrdiff_t region_showing; - /* Z_BYTE - buffer position of the last glyph in the current matrix of W. Should be nonnegative, and only valid if window_end_valid is nonzero. */ ptrdiff_t window_end_bytepos; === modified file 'src/xdisp.c' --- src/xdisp.c 2013-02-04 15:39:55 +0000 +++ src/xdisp.c 2013-02-05 11:59:01 +0000 @@ -2536,8 +2536,8 @@ #endif /* GLYPH_DEBUG and ENABLE_CHECKING */ -/* Return mark position if current buffer has the region of non-zero length, - or -1 otherwise. */ +/* Return mark position if current buffer has the region of non-zero + length, zero if mark and point are the same, or -1 otherwise. */ static ptrdiff_t markpos_of_region (void) @@ -2547,9 +2547,7 @@ && XMARKER (BVAR (current_buffer, mark))->buffer != NULL) { ptrdiff_t markpos = XMARKER (BVAR (current_buffer, mark))->charpos; - - if (markpos != PT) - return markpos; + return markpos == PT ? 0 : markpos; } return -1; } @@ -2689,7 +2687,7 @@ and IT->region_end_charpos to the start and end of a visible region in window IT->w. Set both to -1 to indicate no region. */ markpos = markpos_of_region (); - if (0 <= markpos + if (0 < markpos /* Maybe highlight only in selected window. */ && (/* Either show region everywhere. */ highlight_nonselected_windows @@ -10753,7 +10751,7 @@ return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star) || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active))) - != (w->region_showing != 0))); + != w->region_showing)); } /* Nonzero if W has %c in its mode line and mode line should be updated. */ @@ -12793,7 +12791,7 @@ int must_finish = 0; struct text_pos tlbufpos, tlendpos; int number_of_visible_frames; - ptrdiff_t count, count1; + ptrdiff_t pos, count, count1; struct frame *sf; int polling_stopped_here = 0; Lisp_Object tail, frame; @@ -12806,6 +12804,9 @@ /* Non-zero means redisplay has to redisplay the miniwindow. */ int update_miniwindow_p = 0; + /* Non-zero means the mark is on the same line as point. */ + bool mark_at_this_line = 0; + TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p)); /* No redisplay if running in batch mode or frame is not yet fully @@ -13016,23 +13017,17 @@ clear_garbaged_frames (); } - /* If showing the region, and mark has changed, we must redisplay - the whole window. The assignment to this_line_start_pos prevents - the optimization directly below this if-statement. */ - if (((!NILP (Vtransient_mark_mode) - && !NILP (BVAR (XBUFFER (w->buffer), mark_active))) - != (w->region_showing > 0)) - || (w->region_showing - && w->region_showing - != XINT (Fmarker_position (BVAR (XBUFFER (w->buffer), mark))))) - CHARPOS (this_line_start_pos) = 0; - /* Optimize the case that only the line containing the cursor in the selected window has changed. Variables starting with this_ are set in display_line and record information about the line containing the cursor. */ tlbufpos = this_line_start_pos; tlendpos = this_line_end_pos; + pos = markpos_of_region (); + if (pos != -1) + mark_at_this_line = (CHARPOS (tlbufpos) <= pos + && pos <= Z - CHARPOS (tlendpos)); + if (!consider_all_windows_p && CHARPOS (tlbufpos) > 0 && !w->update_mode_line @@ -13048,6 +13043,8 @@ /* Point must be on the line that we have info recorded about. */ && PT >= CHARPOS (tlbufpos) && PT <= Z - CHARPOS (tlendpos) + /* No region or region which doesn't span multiple lines. */ + && (pos == -1 || mark_at_this_line) /* All text outside that line, including its final newline, must be unchanged. */ && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos), @@ -13059,7 +13056,7 @@ || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n')) /* Former continuation line has disappeared by becoming empty. */ goto cancel; - else if (window_outdated (w) || MINI_WINDOW_P (w)) + else if (window_outdated (w) || MINI_WINDOW_P (w) || mark_at_this_line) { /* We have to handle the case of continuation around a wide-column character (see the comment in indent.c around @@ -13239,8 +13236,6 @@ ++clear_image_cache_count; #endif - w->region_showing = XINT (Fmarker_position (BVAR (XBUFFER (w->buffer), mark))); - /* Build desired matrices, and update the display. If consider_all_windows_p is non-zero, do it for all windows on all frames. Otherwise do it for selected_window, only. */ @@ -14837,7 +14832,7 @@ /* Can't use this case if highlighting a region. When a region exists, cursor movement has to do more than just set the cursor. */ - && markpos_of_region () < 0 + && markpos_of_region () <= 0 && !w->region_showing && NILP (Vshow_trailing_whitespace) /* This code is not used for mini-buffer for the sake of the case @@ -15505,7 +15500,7 @@ /* If we are highlighting the region, then we just changed the region, so redisplay to show it. */ - if (0 <= markpos_of_region ()) + if (0 < markpos_of_region ()) { clear_glyph_matrix (w->desired_matrix); if (!try_window (window, startp, 0)) @@ -16206,7 +16201,7 @@ return 0; /* Can't do this if region may have changed. */ - if (0 <= markpos_of_region () + if (0 < markpos_of_region () || w->region_showing || !NILP (Vshow_trailing_whitespace)) return 0; @@ -17038,7 +17033,7 @@ /* Can't use this if highlighting a region because a cursor movement will do more than just set the cursor. */ - if (0 <= markpos_of_region ()) + if (0 < markpos_of_region ()) GIVE_UP (9); /* Likewise if highlighting trailing whitespace. */ @@ -19133,7 +19128,7 @@ } /* Is IT->w showing the region? */ - it->w->region_showing = it->region_beg_charpos > 0 ? -1 : 0; + it->w->region_showing = it->region_beg_charpos > 0; /* Clear the result glyph row and enable it. */ prepare_desired_row (row);